From owner-svn-src-head@freebsd.org Fri Jun 5 01:00:58 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 1E3F2339679; Fri, 5 Jun 2020 01:00:58 +0000 (UTC) (envelope-from mckusick@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 "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 49dPTj74Bpz4VH0; Fri, 5 Jun 2020 01:00:57 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id D450C8C81; Fri, 5 Jun 2020 01:00:57 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 05510vwQ040282; Fri, 5 Jun 2020 01:00:57 GMT (envelope-from mckusick@FreeBSD.org) Received: (from mckusick@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 05510uuF040273; Fri, 5 Jun 2020 01:00:56 GMT (envelope-from mckusick@FreeBSD.org) Message-Id: <202006050100.05510uuF040273@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mckusick set sender to mckusick@FreeBSD.org using -f From: Kirk McKusick Date: Fri, 5 Jun 2020 01:00:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r361814 - in head/sys/ufs: ffs ufs X-SVN-Group: head X-SVN-Commit-Author: mckusick X-SVN-Commit-Paths: in head/sys/ufs: ffs ufs X-SVN-Commit-Revision: 361814 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Jun 2020 01:00:58 -0000 Author: mckusick Date: Fri Jun 5 01:00:55 2020 New Revision: 361814 URL: https://svnweb.freebsd.org/changeset/base/361814 Log: Further evaluation of the POSIX spec for fdatasync() shows that it requires that new data on growing files be accessible. Thus, the the fsyncdata() system call must update the on-disk inode when the size of the file has changed. This commit adds another inode update flag, IN_SIZEMOD, that gets set any time that the file size changes. If either the IN_IBLKDATA or the IN_SIZEMOD flag is set when fdatasync() is called, the associated inode is synchronously written to disk. We could have overloaded the IN_IBLKDATA flag to also track size changes since the only (current) use case for these flags are for fsyncdata(), but it does seem useful for possible future uses to separately track the file size changes and the inode block pointer changes. Reviewed by: kib MFC with: -r361785 Differential revision: https://reviews.freebsd.org/D25072 Modified: head/sys/ufs/ffs/ffs_alloc.c head/sys/ufs/ffs/ffs_balloc.c head/sys/ufs/ffs/ffs_inode.c head/sys/ufs/ffs/ffs_snapshot.c head/sys/ufs/ffs/ffs_softdep.c head/sys/ufs/ffs/ffs_vnops.c head/sys/ufs/ufs/inode.h head/sys/ufs/ufs/ufs_lookup.c head/sys/ufs/ufs/ufs_vnops.c Modified: head/sys/ufs/ffs/ffs_alloc.c ============================================================================== --- head/sys/ufs/ffs/ffs_alloc.c Fri Jun 5 00:16:54 2020 (r361813) +++ head/sys/ufs/ffs/ffs_alloc.c Fri Jun 5 01:00:55 2020 (r361814) @@ -3306,7 +3306,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS) break; ip = VTOI(vp); DIP_SET(ip, i_size, cmd.size); - UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_MODIFIED); + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE | IN_MODIFIED); error = ffs_update(vp, 1); vput(vp); break; Modified: head/sys/ufs/ffs/ffs_balloc.c ============================================================================== --- head/sys/ufs/ffs/ffs_balloc.c Fri Jun 5 00:16:54 2020 (r361813) +++ head/sys/ufs/ffs/ffs_balloc.c Fri Jun 5 01:00:55 2020 (r361814) @@ -155,7 +155,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, i dp->di_size = ip->i_size; dp->di_db[nb] = dbtofsb(fs, bp->b_blkno); UFS_INODE_SET_FLAG(ip, - IN_CHANGE | IN_UPDATE | IN_IBLKDATA); + IN_SIZEMOD | IN_CHANGE | IN_UPDATE | IN_IBLKDATA); if (flags & IO_SYNC) bwrite(bp); else if (DOINGASYNC(vp)) @@ -648,7 +648,8 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, i dp->di_extsize = smalllblktosize(fs, nb + 1); dp->di_extb[nb] = dbtofsb(fs, bp->b_blkno); bp->b_xflags |= BX_ALTDATA; - UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_IBLKDATA); + UFS_INODE_SET_FLAG(ip, + IN_SIZEMOD | IN_CHANGE | IN_IBLKDATA); if (flags & IO_SYNC) bwrite(bp); else @@ -751,8 +752,8 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, i ip->i_size = smalllblktosize(fs, nb + 1); dp->di_size = ip->i_size; dp->di_db[nb] = dbtofsb(fs, bp->b_blkno); - UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE | - IN_IBLKDATA); + UFS_INODE_SET_FLAG(ip, + IN_SIZEMOD |IN_CHANGE | IN_UPDATE | IN_IBLKDATA); if (flags & IO_SYNC) bwrite(bp); else Modified: head/sys/ufs/ffs/ffs_inode.c ============================================================================== --- head/sys/ufs/ffs/ffs_inode.c Fri Jun 5 00:16:54 2020 (r361813) +++ head/sys/ufs/ffs/ffs_inode.c Fri Jun 5 01:00:55 2020 (r361814) @@ -279,7 +279,7 @@ ffs_truncate(vp, length, flags, cred) oldblks[i] = ip->i_din2->di_extb[i]; ip->i_din2->di_extb[i] = 0; } - UFS_INODE_SET_FLAG(ip, IN_CHANGE); + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE); if ((error = ffs_update(vp, waitforupdate))) return (error); for (i = 0; i < UFS_NXADDR; i++) { @@ -303,7 +303,7 @@ ffs_truncate(vp, length, flags, cred) bzero(SHORTLINK(ip), (u_int)ip->i_size); ip->i_size = 0; DIP_SET(ip, i_size, 0); - UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE); + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE | IN_UPDATE); if (needextclean) goto extclean; return (ffs_update(vp, waitforupdate)); @@ -343,7 +343,7 @@ ffs_truncate(vp, length, flags, cred) bdwrite(bp); else bawrite(bp); - UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE); + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE | IN_UPDATE); return (ffs_update(vp, waitforupdate)); } /* @@ -429,6 +429,7 @@ ffs_truncate(vp, length, flags, cred) if (blkno != 0 && offset == 0) { ip->i_size = length; DIP_SET(ip, i_size, length); + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE | IN_UPDATE); } else { lbn = lblkno(fs, length); flags |= BA_CLRBUF; @@ -463,6 +464,7 @@ ffs_truncate(vp, length, flags, cred) bdwrite(bp); else bawrite(bp); + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE | IN_UPDATE); } /* * Calculate index into inode's block list of @@ -512,6 +514,7 @@ ffs_truncate(vp, length, flags, cred) } ip->i_size = osize; DIP_SET(ip, i_size, osize); + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE | IN_UPDATE); error = vtruncbuf(vp, length, fs->fs_bsize); if (error && (allerror == 0)) @@ -578,6 +581,7 @@ ffs_truncate(vp, length, flags, cred) oldspace = blksize(fs, ip, lastblock); ip->i_size = length; DIP_SET(ip, i_size, length); + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE | IN_UPDATE); newspace = blksize(fs, ip, lastblock); if (newspace == 0) panic("ffs_truncate: newspace"); @@ -623,7 +627,7 @@ done: DIP_SET(ip, i_blocks, DIP(ip, i_blocks) - blocksreleased); else /* sanity */ DIP_SET(ip, i_blocks, 0); - UFS_INODE_SET_FLAG(ip, IN_CHANGE); + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE); #ifdef QUOTA (void) chkdq(ip, -blocksreleased, NOCRED, FORCE); #endif Modified: head/sys/ufs/ffs/ffs_snapshot.c ============================================================================== --- head/sys/ufs/ffs/ffs_snapshot.c Fri Jun 5 00:16:54 2020 (r361813) +++ head/sys/ufs/ffs/ffs_snapshot.c Fri Jun 5 01:00:55 2020 (r361814) @@ -319,7 +319,7 @@ restart: goto out; ip->i_size = lblktosize(fs, (off_t)numblks); DIP_SET(ip, i_size, ip->i_size); - UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE); + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE | IN_UPDATE); error = readblock(vp, bp, numblks - 1); bawrite(bp); if (error != 0) Modified: head/sys/ufs/ffs/ffs_softdep.c ============================================================================== --- head/sys/ufs/ffs/ffs_softdep.c Fri Jun 5 00:16:54 2020 (r361813) +++ head/sys/ufs/ffs/ffs_softdep.c Fri Jun 5 01:00:55 2020 (r361814) @@ -6709,6 +6709,7 @@ softdep_journal_freeblocks(ip, cred, length, flags) } ip->i_size = length; DIP_SET(ip, i_size, ip->i_size); + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE); datablocks = DIP(ip, i_blocks) - extblocks; if (length != 0) datablocks = blkcount(fs, datablocks, length); @@ -6719,6 +6720,7 @@ softdep_journal_freeblocks(ip, cred, length, flags) setup_freeext(freeblks, ip, i, needj); ip->i_din2->di_extsize = 0; datablocks += extblocks; + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE); } #ifdef QUOTA /* Reference the quotas in case the block count is wrong in the end. */ @@ -6829,7 +6831,7 @@ softdep_journal_freeblocks(ip, cred, length, flags) } ip->i_size = length; DIP_SET(ip, i_size, length); - UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE); + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE | IN_UPDATE); allocbuf(bp, frags); ffs_update(vp, 0); bawrite(bp); @@ -6976,6 +6978,7 @@ softdep_setup_freeblocks(ip, length, flags) setup_freeindir(freeblks, ip, i, -lbn -i, 0); ip->i_size = 0; DIP_SET(ip, i_size, 0); + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE); datablocks = DIP(ip, i_blocks) - extblocks; } if ((flags & IO_EXT) != 0) { @@ -6983,6 +6986,7 @@ softdep_setup_freeblocks(ip, length, flags) setup_freeext(freeblks, ip, i, 0); ip->i_din2->di_extsize = 0; datablocks += extblocks; + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE); } #ifdef QUOTA /* Reference the quotas in case the block count is wrong in the end. */ Modified: head/sys/ufs/ffs/ffs_vnops.c ============================================================================== --- head/sys/ufs/ffs/ffs_vnops.c Fri Jun 5 00:16:54 2020 (r361813) +++ head/sys/ufs/ffs/ffs_vnops.c Fri Jun 5 01:00:55 2020 (r361814) @@ -416,7 +416,7 @@ next: error = ffs_update(vp, 1); if (DOINGSUJ(vp)) softdep_journal_fsync(VTOI(vp)); - } else if ((ip->i_flags & IN_IBLKDATA) != 0) { + } else if ((ip->i_flags & (IN_SIZEMOD | IN_IBLKDATA)) != 0) { error = ffs_update(vp, 1); } return (error); @@ -825,6 +825,7 @@ ffs_write(ap) if (uio->uio_offset + xfersize > ip->i_size) { ip->i_size = uio->uio_offset + xfersize; DIP_SET(ip, i_size, ip->i_size); + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE); } size = blksize(fs, ip, lbn) - bp->b_resid; @@ -1108,8 +1109,10 @@ ffs_extwrite(struct vnode *vp, struct uio *uio, int io if ((bp->b_flags & B_CACHE) == 0 && fs->fs_bsize <= xfersize) vfs_bio_clrbuf(bp); - if (uio->uio_offset + xfersize > dp->di_extsize) + if (uio->uio_offset + xfersize > dp->di_extsize) { dp->di_extsize = uio->uio_offset + xfersize; + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE); + } size = sblksize(fs, dp->di_extsize, lbn) - bp->b_resid; if (size < xfersize) Modified: head/sys/ufs/ufs/inode.h ============================================================================== --- head/sys/ufs/ufs/inode.h Fri Jun 5 00:16:54 2020 (r361813) +++ head/sys/ufs/ufs/inode.h Fri Jun 5 01:00:55 2020 (r361814) @@ -127,19 +127,21 @@ struct inode { #define IN_LAZYMOD 0x0020 /* Modified, but don't write yet. */ #define IN_LAZYACCESS 0x0040 /* Process IN_ACCESS after the suspension finished */ -#define IN_EA_LOCKED 0x0080 -#define IN_EA_LOCKWAIT 0x0100 +#define IN_EA_LOCKED 0x0080 /* Extended attributes locked */ +#define IN_EA_LOCKWAIT 0x0100 /* Want extended attributes lock */ #define IN_TRUNCATED 0x0200 /* Journaled truncation pending. */ #define IN_UFS2 0x0400 /* UFS2 vs UFS1 */ #define IN_IBLKDATA 0x0800 /* datasync requires inode block update */ +#define IN_SIZEMOD 0x1000 /* Inode size has been modified */ -#define PRINT_INODE_FLAGS "\20\20b16\17b15\16b14\15b13" \ +#define PRINT_INODE_FLAGS "\20\20b16\17b15\16b14\15sizemod" \ "\14iblkdata\13is_ufs2\12truncated\11ea_lockwait\10ea_locked" \ "\7lazyaccess\6lazymod\5needsync\4modified\3update\2change\1access" #define UFS_INODE_FLAG_LAZY_MASK \ - (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE | IN_LAZYMOD | IN_LAZYACCESS) + (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE | IN_LAZYMOD | \ + IN_LAZYACCESS) /* * Some flags can persist a vnode transitioning to 0 hold count and being tkaen * off the list. Modified: head/sys/ufs/ufs/ufs_lookup.c ============================================================================== --- head/sys/ufs/ufs/ufs_lookup.c Fri Jun 5 00:16:54 2020 (r361813) +++ head/sys/ufs/ufs/ufs_lookup.c Fri Jun 5 01:00:55 2020 (r361814) @@ -556,7 +556,7 @@ found: ufs_dirbad(dp, i_offset, "i_size too small"); dp->i_size = i_offset + DIRSIZ(OFSFMT(vdp), ep); DIP_SET(dp, i_size, dp->i_size); - UFS_INODE_SET_FLAG(dp, IN_CHANGE | IN_UPDATE); + UFS_INODE_SET_FLAG(dp, IN_SIZEMOD | IN_CHANGE | IN_UPDATE); } brelse(bp); @@ -918,7 +918,7 @@ ufs_direnter(dvp, tvp, dirp, cnp, newdirbp, isrename) dp->i_size = dp->i_offset + DIRBLKSIZ; DIP_SET(dp, i_size, dp->i_size); dp->i_endoff = dp->i_size; - UFS_INODE_SET_FLAG(dp, IN_CHANGE | IN_UPDATE); + UFS_INODE_SET_FLAG(dp, IN_SIZEMOD | IN_CHANGE | IN_UPDATE); dirp->d_reclen = DIRBLKSIZ; blkoff = dp->i_offset & (VFSTOUFS(dvp->v_mount)->um_mountp->mnt_stat.f_iosize - 1); @@ -1004,6 +1004,7 @@ ufs_direnter(dvp, tvp, dirp, cnp, newdirbp, isrename) if (dp->i_offset + dp->i_count > dp->i_size) { dp->i_size = dp->i_offset + dp->i_count; DIP_SET(dp, i_size, dp->i_size); + UFS_INODE_SET_FLAG(dp, IN_SIZEMOD | IN_MODIFIED); } /* * Get the block containing the space for the new directory entry. Modified: head/sys/ufs/ufs/ufs_vnops.c ============================================================================== --- head/sys/ufs/ufs/ufs_vnops.c Fri Jun 5 00:16:54 2020 (r361813) +++ head/sys/ufs/ufs/ufs_vnops.c Fri Jun 5 01:00:55 2020 (r361814) @@ -1932,7 +1932,7 @@ ufs_mkdir(ap) goto bad; ip->i_size = DIRBLKSIZ; DIP_SET(ip, i_size, DIRBLKSIZ); - UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE); + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE | IN_UPDATE); bcopy((caddr_t)&dirtemplate, (caddr_t)bp->b_data, sizeof dirtemplate); if (DOINGSOFTDEP(tvp)) { /* @@ -2119,7 +2119,7 @@ ufs_symlink(ap) bcopy(ap->a_target, SHORTLINK(ip), len); ip->i_size = len; DIP_SET(ip, i_size, len); - UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_UPDATE); + UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE | IN_UPDATE); error = UFS_UPDATE(vp, 0); } else error = vn_rdwr(UIO_WRITE, vp, __DECONST(void *, ap->a_target),