From owner-svn-src-stable-11@freebsd.org Thu Jun 11 11:45:32 2020 Return-Path: Delivered-To: svn-src-stable-11@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 B951D32B8F8; Thu, 11 Jun 2020 11:45:32 +0000 (UTC) (envelope-from kib@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 49jMVh4xN3z4SMN; Thu, 11 Jun 2020 11:45:32 +0000 (UTC) (envelope-from kib@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 A4AE8179A2; Thu, 11 Jun 2020 11:45:32 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 05BBjWnd011394; Thu, 11 Jun 2020 11:45:32 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 05BBjUH0011385; Thu, 11 Jun 2020 11:45:30 GMT (envelope-from kib@FreeBSD.org) Message-Id: <202006111145.05BBjUH0011385@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Thu, 11 Jun 2020 11:45:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r362050 - in stable/11/sys/ufs: ffs ufs X-SVN-Group: stable-11 X-SVN-Commit-Author: kib X-SVN-Commit-Paths: in stable/11/sys/ufs: ffs ufs X-SVN-Commit-Revision: 362050 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-11@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for only the 11-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 11 Jun 2020 11:45:32 -0000 Author: kib Date: Thu Jun 11 11:45:30 2020 New Revision: 362050 URL: https://svnweb.freebsd.org/changeset/base/362050 Log: MFC r361785, r361801 (by mckusick), r361803 (by se), r361814 (by mckusick), r361875 (by mckusick): Fixes for UFS fdatasync(2). Modified: stable/11/sys/ufs/ffs/ffs_alloc.c stable/11/sys/ufs/ffs/ffs_balloc.c stable/11/sys/ufs/ffs/ffs_inode.c stable/11/sys/ufs/ffs/ffs_snapshot.c stable/11/sys/ufs/ffs/ffs_softdep.c stable/11/sys/ufs/ffs/ffs_vnops.c stable/11/sys/ufs/ufs/inode.h stable/11/sys/ufs/ufs/ufs_lookup.c stable/11/sys/ufs/ufs/ufs_vnops.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/ufs/ffs/ffs_alloc.c ============================================================================== --- stable/11/sys/ufs/ffs/ffs_alloc.c Thu Jun 11 11:36:49 2020 (r362049) +++ stable/11/sys/ufs/ffs/ffs_alloc.c Thu Jun 11 11:45:30 2020 (r362050) @@ -2897,7 +2897,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS) break; ip = VTOI(vp); DIP_SET(ip, i_size, cmd.size); - ip->i_flag |= IN_CHANGE | IN_MODIFIED; + ip->i_flag |= IN_SIZEMOD | IN_CHANGE | IN_MODIFIED; error = ffs_update(vp, 1); vput(vp); break; Modified: stable/11/sys/ufs/ffs/ffs_balloc.c ============================================================================== --- stable/11/sys/ufs/ffs/ffs_balloc.c Thu Jun 11 11:36:49 2020 (r362049) +++ stable/11/sys/ufs/ffs/ffs_balloc.c Thu Jun 11 11:45:30 2020 (r362050) @@ -152,7 +152,8 @@ ffs_balloc_ufs1(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); - ip->i_flag |= IN_CHANGE | IN_UPDATE; + ip->i_flag |= IN_SIZEMOD | IN_CHANGE | IN_UPDATE | + IN_IBLKDATA; if (flags & IO_SYNC) bwrite(bp); else @@ -222,7 +223,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, i nsize, 0, bp); } dp->di_db[lbn] = dbtofsb(fs, bp->b_blkno); - ip->i_flag |= IN_CHANGE | IN_UPDATE; + ip->i_flag |= IN_CHANGE | IN_UPDATE | IN_IBLKDATA; *bpp = bp; return (0); } @@ -279,7 +280,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, i } allocib = &dp->di_ib[indirs[0].in_off]; *allocib = nb; - ip->i_flag |= IN_CHANGE | IN_UPDATE; + ip->i_flag |= IN_CHANGE | IN_UPDATE | IN_IBLKDATA; } /* * Fetch through the indirect blocks, allocating as necessary. @@ -632,7 +633,7 @@ 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; - ip->i_flag |= IN_CHANGE; + ip->i_flag |= IN_SIZEMOD | IN_CHANGE | IN_IBLKDATA; if (flags & IO_SYNC) bwrite(bp); else @@ -708,7 +709,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, i nsize, 0, bp); } dp->di_extb[lbn] = dbtofsb(fs, bp->b_blkno); - ip->i_flag |= IN_CHANGE; + ip->i_flag |= IN_CHANGE | IN_IBLKDATA; *bpp = bp; return (0); } @@ -737,7 +738,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); - ip->i_flag |= IN_CHANGE | IN_UPDATE; + ip->i_flag |= IN_SIZEMOD | IN_CHANGE | IN_UPDATE | + IN_IBLKDATA; if (flags & IO_SYNC) bwrite(bp); else @@ -809,7 +811,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, i nsize, 0, bp); } dp->di_db[lbn] = dbtofsb(fs, bp->b_blkno); - ip->i_flag |= IN_CHANGE | IN_UPDATE; + ip->i_flag |= IN_CHANGE | IN_UPDATE | IN_IBLKDATA; *bpp = bp; return (0); } @@ -867,7 +869,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, i } allocib = &dp->di_ib[indirs[0].in_off]; *allocib = nb; - ip->i_flag |= IN_CHANGE | IN_UPDATE; + ip->i_flag |= IN_CHANGE | IN_UPDATE | IN_IBLKDATA; } /* * Fetch through the indirect blocks, allocating as necessary. Modified: stable/11/sys/ufs/ffs/ffs_inode.c ============================================================================== --- stable/11/sys/ufs/ffs/ffs_inode.c Thu Jun 11 11:36:49 2020 (r362049) +++ stable/11/sys/ufs/ffs/ffs_inode.c Thu Jun 11 11:45:30 2020 (r362050) @@ -92,6 +92,26 @@ ffs_update(vp, waitfor) if ((ip->i_flag & IN_MODIFIED) == 0 && waitfor == 0) return (0); ip->i_flag &= ~(IN_LAZYACCESS | IN_LAZYMOD | IN_MODIFIED); + /* + * The IN_SIZEMOD and IN_IBLKDATA flags indicate changes to the + * file size and block pointer fields in the inode. When these + * fields have been changed, the fsync() and fsyncdata() system + * calls must write the inode to ensure their semantics that the + * file is on stable store. + * + * The IN_SIZEMOD and IN_IBLKDATA flags cannot be cleared until + * a synchronous write of the inode is done. If they are cleared + * on an asynchronous write, then the inode may not yet have been + * written to the disk when an fsync() or fsyncdata() call is done. + * Absent these flags, these calls would not know that they needed + * to write the inode. Thus, these flags only can be cleared on + * synchronous writes of the inode. Since the inode will be locked + * for the duration of the I/O that writes it to disk, no fsync() + * or fsyncdata() will be able to run before the on-disk inode + * is complete. + */ + if (waitfor) + ip->i_flag &= ~(IN_SIZEMOD | IN_IBLKDATA); fs = ITOFS(ip); if (fs->fs_ronly && ITOUMP(ip)->um_fsckpid == 0) return (0); @@ -263,7 +283,7 @@ ffs_truncate(vp, length, flags, cred) oldblks[i] = ip->i_din2->di_extb[i]; ip->i_din2->di_extb[i] = 0; } - ip->i_flag |= IN_CHANGE; + ip->i_flag |= IN_SIZEMOD | IN_CHANGE; if ((error = ffs_update(vp, !DOINGASYNC(vp)))) return (error); for (i = 0; i < NXADDR; i++) { @@ -287,7 +307,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); - ip->i_flag |= IN_CHANGE | IN_UPDATE; + ip->i_flag |= IN_SIZEMOD | IN_CHANGE | IN_UPDATE; if (needextclean) goto extclean; return (ffs_update(vp, !DOINGASYNC(vp))); @@ -327,7 +347,7 @@ ffs_truncate(vp, length, flags, cred) bdwrite(bp); else bawrite(bp); - ip->i_flag |= IN_CHANGE | IN_UPDATE; + ip->i_flag |= IN_SIZEMOD | IN_CHANGE | IN_UPDATE; return (ffs_update(vp, !DOINGASYNC(vp))); } /* @@ -413,6 +433,7 @@ ffs_truncate(vp, length, flags, cred) if (blkno != 0 && offset == 0) { ip->i_size = length; DIP_SET(ip, i_size, length); + ip->i_flag |= IN_SIZEMOD | IN_CHANGE | IN_UPDATE; } else { lbn = lblkno(fs, length); flags |= BA_CLRBUF; @@ -447,6 +468,7 @@ ffs_truncate(vp, length, flags, cred) bdwrite(bp); else bawrite(bp); + ip->i_flag |= IN_SIZEMOD | IN_CHANGE | IN_UPDATE; } /* * Calculate index into inode's block list of @@ -496,6 +518,7 @@ ffs_truncate(vp, length, flags, cred) } ip->i_size = osize; DIP_SET(ip, i_size, osize); + ip->i_flag |= IN_SIZEMOD | IN_CHANGE | IN_UPDATE; error = vtruncbuf(vp, length, fs->fs_bsize); if (error && (allerror == 0)) @@ -560,6 +583,7 @@ ffs_truncate(vp, length, flags, cred) oldspace = blksize(fs, ip, lastblock); ip->i_size = length; DIP_SET(ip, i_size, length); + ip->i_flag |= IN_SIZEMOD | IN_CHANGE | IN_UPDATE; newspace = blksize(fs, ip, lastblock); if (newspace == 0) panic("ffs_truncate: newspace"); @@ -599,7 +623,7 @@ done: DIP_SET(ip, i_blocks, DIP(ip, i_blocks) - blocksreleased); else /* sanity */ DIP_SET(ip, i_blocks, 0); - ip->i_flag |= IN_CHANGE; + ip->i_flag |= IN_SIZEMOD | IN_CHANGE; #ifdef QUOTA (void) chkdq(ip, -blocksreleased, NOCRED, 0); #endif Modified: stable/11/sys/ufs/ffs/ffs_snapshot.c ============================================================================== --- stable/11/sys/ufs/ffs/ffs_snapshot.c Thu Jun 11 11:36:49 2020 (r362049) +++ stable/11/sys/ufs/ffs/ffs_snapshot.c Thu Jun 11 11:45:30 2020 (r362050) @@ -315,7 +315,7 @@ restart: goto out; ip->i_size = lblktosize(fs, (off_t)numblks); DIP_SET(ip, i_size, ip->i_size); - ip->i_flag |= IN_CHANGE | IN_UPDATE; + ip->i_flag |= IN_SIZEMOD | IN_CHANGE | IN_UPDATE; error = readblock(vp, bp, numblks - 1); bawrite(bp); if (error != 0) Modified: stable/11/sys/ufs/ffs/ffs_softdep.c ============================================================================== --- stable/11/sys/ufs/ffs/ffs_softdep.c Thu Jun 11 11:36:49 2020 (r362049) +++ stable/11/sys/ufs/ffs/ffs_softdep.c Thu Jun 11 11:45:30 2020 (r362050) @@ -6617,6 +6617,7 @@ softdep_journal_freeblocks(ip, cred, length, flags) } ip->i_size = length; DIP_SET(ip, i_size, ip->i_size); + ip->i_flag |= IN_SIZEMOD | IN_CHANGE; datablocks = DIP(ip, i_blocks) - extblocks; if (length != 0) datablocks = blkcount(fs, datablocks, length); @@ -6627,6 +6628,7 @@ softdep_journal_freeblocks(ip, cred, length, flags) setup_freeext(freeblks, ip, i, needj); ip->i_din2->di_extsize = 0; datablocks += extblocks; + ip->i_flag |= IN_SIZEMOD | IN_CHANGE; } #ifdef QUOTA /* Reference the quotas in case the block count is wrong in the end. */ @@ -6735,7 +6737,7 @@ softdep_journal_freeblocks(ip, cred, length, flags) } ip->i_size = length; DIP_SET(ip, i_size, length); - ip->i_flag |= IN_CHANGE | IN_UPDATE; + ip->i_flag |= IN_SIZEMOD | IN_CHANGE | IN_UPDATE; allocbuf(bp, frags); ffs_update(vp, 0); bawrite(bp); @@ -6881,6 +6883,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); + ip->i_flag |= IN_SIZEMOD | IN_CHANGE; datablocks = DIP(ip, i_blocks) - extblocks; } if ((flags & IO_EXT) != 0) { @@ -6888,6 +6891,7 @@ softdep_setup_freeblocks(ip, length, flags) setup_freeext(freeblks, ip, i, 0); ip->i_din2->di_extsize = 0; datablocks += extblocks; + ip->i_flag |= IN_SIZEMOD | IN_CHANGE; } #ifdef QUOTA /* Reference the quotas in case the block count is wrong in the end. */ Modified: stable/11/sys/ufs/ffs/ffs_vnops.c ============================================================================== --- stable/11/sys/ufs/ffs/ffs_vnops.c Thu Jun 11 11:36:49 2020 (r362049) +++ stable/11/sys/ufs/ffs/ffs_vnops.c Thu Jun 11 11:45:30 2020 (r362050) @@ -385,6 +385,8 @@ next: error = ffs_update(vp, 1); if (DOINGSUJ(vp)) softdep_journal_fsync(VTOI(vp)); + } else if ((ip->i_flags & (IN_SIZEMOD | IN_IBLKDATA)) != 0) { + error = ffs_update(vp, 1); } return (error); } @@ -758,6 +760,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); + ip->i_flag |= IN_SIZEMOD | IN_CHANGE; } size = blksize(fs, ip, lbn) - bp->b_resid; @@ -1037,8 +1040,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; + ip->i_flag |= IN_SIZEMOD | IN_CHANGE; + } size = sblksize(fs, dp->di_extsize, lbn) - bp->b_resid; if (size < xfersize) Modified: stable/11/sys/ufs/ufs/inode.h ============================================================================== --- stable/11/sys/ufs/ufs/inode.h Thu Jun 11 11:36:49 2020 (r362049) +++ stable/11/sys/ufs/ufs/inode.h Thu Jun 11 11:45:30 2020 (r362050) @@ -125,12 +125,13 @@ 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 i_dirhash i_un.dirhash #define i_snapblklist i_un.snapblklist Modified: stable/11/sys/ufs/ufs/ufs_lookup.c ============================================================================== --- stable/11/sys/ufs/ufs/ufs_lookup.c Thu Jun 11 11:36:49 2020 (r362049) +++ stable/11/sys/ufs/ufs/ufs_lookup.c Thu Jun 11 11:45:30 2020 (r362050) @@ -554,7 +554,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); - dp->i_flag |= IN_CHANGE | IN_UPDATE; + dp->i_flag |= IN_SIZEMOD | IN_CHANGE | IN_UPDATE; } brelse(bp); @@ -916,7 +916,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; - dp->i_flag |= IN_CHANGE | IN_UPDATE; + dp->i_flag |= 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); @@ -1002,6 +1002,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); + dp->i_flag |= IN_SIZEMOD | IN_MODIFIED; } /* * Get the block containing the space for the new directory entry. Modified: stable/11/sys/ufs/ufs/ufs_vnops.c ============================================================================== --- stable/11/sys/ufs/ufs/ufs_vnops.c Thu Jun 11 11:36:49 2020 (r362049) +++ stable/11/sys/ufs/ufs/ufs_vnops.c Thu Jun 11 11:45:30 2020 (r362050) @@ -1925,7 +1925,7 @@ ufs_mkdir(ap) goto bad; ip->i_size = DIRBLKSIZ; DIP_SET(ip, i_size, DIRBLKSIZ); - ip->i_flag |= IN_CHANGE | IN_UPDATE; + ip->i_flag |= IN_SIZEMOD | IN_CHANGE | IN_UPDATE; bcopy((caddr_t)&dirtemplate, (caddr_t)bp->b_data, sizeof dirtemplate); if (DOINGSOFTDEP(tvp)) { /* @@ -2112,7 +2112,7 @@ ufs_symlink(ap) bcopy(ap->a_target, SHORTLINK(ip), len); ip->i_size = len; DIP_SET(ip, i_size, len); - ip->i_flag |= IN_CHANGE | IN_UPDATE; + ip->i_flag |= IN_SIZEMOD | IN_CHANGE | IN_UPDATE; error = UFS_UPDATE(vp, 0); } else error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0,