From nobody Tue Oct 13 04:29:53 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4j3hFZ4jXFz6vgwJ for ; Tue, 13 Oct 2026 04:29:54 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4j3hFZ18t0z4qT4 for ; Tue, 13 Oct 2026 04:29:54 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791865794; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=MzrHhuxfNI8a4kLHr8wRNqVER+8QF2Iu7FLpZ+87bW0=; b=yHHpaWzUazHgsWwVH/CW5/BOxezGm3eNcWfoGqOHdSGwaQ5OdDGEJqumGPbuSVqtlNYHMv N4Dyl0BZAFPhXSzoah0ttgSEfgsKBc7QZ8NACmU9xEpxl2iL6UxGCbDNsWtePrERlp8adk GkxXBS/ixR36JVL8oTgzs9Tjz72SSSMDk8Tep1bwV8Doa1Bq8hwQrjpmmdrsY2MOu/e0Mh n/NQ0OWeEz/UhYhYbW92oEh1xaJnkjYXSs302bBpX6Qv2+gA1bt9ifzv41s0yzW//XvB2x SdsQHBEcwUv7Ex0HqtA/Rxa0cgv3nBHW2EVdUzRJZPPZByKOn/39+oRmx+Jc2w== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1791865794; b=R/AJld+LJEoCsgH4nEUL8/Wak5N6dCqf7VVc4iIJZp7ikwL0PPMUMRoE3l1eNC3SvhF1TK RcMud9u4baSqvJ9TyfGktXyxk/6I9Lgz/yxE4yrNh5ixUms22L97df2LrzmwO4zYTouIZ7 LGnXbU7sCZA3CqdsJZ/IBSc40xkeaAhbt5EK45JYr+WoOluCyWPvE6umZAGYXrv1O905Uh LNVAt7l2YdMQHq5hL5tVLZw4qaPwme4bzqh/1oT99z1aUrS5z+pfuWfFFuiwY3IOkkvzEJ RrwX8pFzus2LAAEZ/MONdCoruOcpGJ3xg6nJITz2qrHSQBEqmBkjoY7mmCaw7Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791865794; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=MzrHhuxfNI8a4kLHr8wRNqVER+8QF2Iu7FLpZ+87bW0=; b=L/0Jv93+Y/yL6A8WVdjB9LRNXmSZ/fLTEW6ly5nWLuuKrqET6BQxGgbvXz38aZFIGZvfmY zScLvlYxpizIj5F47GAwU8luwJFGovTwECXY+ulaNiA1bDhXT1MWFMrzLoMtSmzJpb3fJa cEfWINazevzHZfdH3nRZ0pZkB/UUN/CoHVGtrOjELnaCMAzmJMHv6emNAUFRQ7A4I81s4W YlMMkwPFA9NavAlGq0nM+zJxkE9ZBJIxVHWdaldQrWiikIrU0cvH7ubQQ4E73/oxk78M5E MtyZlJCz58U8oZXQ+dHx5rNOqC5bGn0mTPFjA63NuAI+nJ8783qJrOcuMo9+rQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4j3hFY6JFZz107K for ; Tue, 13 Oct 2026 04:29:53 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 27aac by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 13 Oct 2026 04:29:53 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Maxim Sobolev Subject: git: 1498efc4243e - main - ufs: make fdatasync(2) write dirty indirect blocks List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: Commit messages for the main branch of the src repository List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: sobomax X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 1498efc4243e963503179547221335940e2aeded Auto-Submitted: auto-generated Date: Tue, 13 Oct 2026 04:29:53 +0000 Message-Id: <6acdb3c1.27aac.6b90ea3a@gitrepo.freebsd.org> The branch main has been updated by sobomax: URL: https://cgit.FreeBSD.org/src/commit/?id=1498efc4243e963503179547221335940e2aeded commit 1498efc4243e963503179547221335940e2aeded Author: Maxim Sobolev AuthorDate: 2026-10-13 02:41:27 +0000 Commit: Maxim Sobolev CommitDate: 2026-10-13 04:28:32 +0000 ufs: make fdatasync(2) write dirty indirect blocks A data-only ffs_syncvnode() skips dirty indirect blocks on file systems without soft updates, and with soft updates stops making passes once only indirect blocks are left dirty. Indirect blocks only get dirty when the block pointers in them change, and those pointers are what makes a newly allocated block reachable. So when fdatasync() follows a write that extended the file or filled a hole past the direct blocks, the data and the inode size reached the disk but the pointer to the new block did not, and a crash lost the "synced" data. With soft updates the indirect block was usually written once, with the new pointer rolled back, and never rewritten. POSIX requires fdatasync() to write the metadata needed to retrieve the data, which 52488b51489 already acknowledged for the inode, so treat dirty indirect blocks the same way for a data-only sync as for a full one. This restores the loop to what it was before 2f514f92cf0. Plain overwrites, the case data-only sync is meant to speed up, do not dirty indirect blocks and still write neither them nor the inode. Fixes: 2f514f92cf0 ("Implement VOP_FDATASYNC() for UFS.") Sponsored by: Sippy Software, Inc. Reviewed by: kib Tested by: pho Differential Revision: https://reviews.freebsd.org/D60134 MFC after: 1 month --- sys/ufs/ffs/ffs_vnops.c | 50 +++++++++++++++---------------------------------- 1 file changed, 15 insertions(+), 35 deletions(-) diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index be708d07a2ca..4044ecf20f92 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -267,7 +267,7 @@ ffs_syncvnode(struct vnode *vp, int waitfor, int flags) struct buf *bp, *nbp; ufs_lbn_t lbn; int error, passes, wflag; - bool still_dirty, unlocked, wait; + bool unlocked, wait; ip = VTOI(vp); bo = &vp->v_bufobj; @@ -314,14 +314,13 @@ loop: /* * Flush indirects in order, if requested. * - * Note that if only datasync is requested, we can - * skip indirect blocks when softupdates are not - * active. Otherwise we must flush them with data, - * since dependencies prevent data block writes. + * Indirect blocks are only dirtied by changes to the + * block pointers they hold, so even a data-only sync + * must write them: they are needed to retrieve newly + * allocated blocks. */ if (waitfor == MNT_WAIT && bp->b_lblkno <= -UFS_NDADDR && - (lbn_level(bp->b_lblkno) >= passes || - ((flags & DATA_ONLY) != 0 && !DOINGSOFTDEP(vp)))) + lbn_level(bp->b_lblkno) >= passes) continue; if (bp->b_lblkno > lbn) panic("ffs_syncvnode: syncing truncated data."); @@ -421,35 +420,16 @@ next_locked: * these will be done with one sync and one async pass. */ if (bo->bo_dirty.bv_cnt > 0) { - if ((flags & DATA_ONLY) == 0) { - still_dirty = true; - } else { - /* - * For data-only sync, dirty indirect buffers - * are ignored. - */ - still_dirty = false; - TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs) { - if (bp->b_lblkno > -UFS_NDADDR) { - still_dirty = true; - break; - } - } - } - - if (still_dirty) { - /* Write the inode after sync passes to flush deps. */ - if (wait && DOINGSOFTDEP(vp) && - (flags & NO_INO_UPDT) == 0) { - BO_UNLOCK(bo); - ffs_update(vp, 1); - BO_LOCK(bo); - } - /* switch between sync/async. */ - wait = !wait; - if (wait || ++passes < UFS_NIADDR + 2) - goto loop; + /* Write the inode after sync passes to flush deps. */ + if (wait && DOINGSOFTDEP(vp) && (flags & NO_INO_UPDT) == 0) { + BO_UNLOCK(bo); + ffs_update(vp, 1); + BO_LOCK(bo); } + /* switch between sync/async. */ + wait = !wait; + if (wait || ++passes < UFS_NIADDR + 2) + goto loop; } BO_UNLOCK(bo); error = 0;