git: 220cd6b04580 - stable/13 - ufs_direnter: directory truncation does not need special case for rename

Konstantin Belousov kib at FreeBSD.org
Wed Feb 24 07:59:03 UTC 2021


The branch stable/13 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=220cd6b0458006554944598e170436eb0db683da

commit 220cd6b0458006554944598e170436eb0db683da
Author:     Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2021-01-29 12:31:52 +0000
Commit:     Konstantin Belousov <kib at FreeBSD.org>
CommitDate: 2021-02-24 07:45:57 +0000

    ufs_direnter: directory truncation does not need special case for rename
    
    (cherry picked from commit 06f2918ab8a2621c6e6bc5729ed9ab982741aaf2)
---
 sys/ufs/ffs/ffs_vnops.c  | 25 ++++++++++++-------------
 sys/ufs/ufs/ufs_extern.h |  2 +-
 sys/ufs/ufs/ufs_lookup.c | 12 +++++-------
 sys/ufs/ufs/ufs_vnops.c  | 10 +++++-----
 4 files changed, 23 insertions(+), 26 deletions(-)

diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
index dd0f1ba6b81d..38511647c502 100644
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -1968,22 +1968,21 @@ ffs_vput_pair(struct vop_vput_pair_args *ap)
 	 * now that other locks are no longer held.
          */
 	if ((dp->i_flag & IN_ENDOFF) != 0) {
+		VNASSERT(I_ENDOFF(dp) != 0 && I_ENDOFF(dp) < dp->i_size, dvp,
+		    ("IN_ENDOFF set but I_ENDOFF() is not"));
 		dp->i_flag &= ~IN_ENDOFF;
-		if (I_ENDOFF(dp) != 0 && I_ENDOFF(dp) < dp->i_size) {
-			old_size = dp->i_size;
-			error = UFS_TRUNCATE(dvp, (off_t)I_ENDOFF(dp),
-			    IO_NORMAL | (DOINGASYNC(dvp) ? 0 : IO_SYNC),
-			    curthread->td_ucred);
-			if (error != 0 && error != ERELOOKUP) {
-				if (!ffs_fsfail_cleanup(VFSTOUFS(mp), error)) {
-					vn_printf(dvp,
-					    "IN_ENDOFF: failed to truncate, "
-					    "error %d\n", error);
-				}
+		old_size = dp->i_size;
+		error = UFS_TRUNCATE(dvp, (off_t)I_ENDOFF(dp), IO_NORMAL |
+		    (DOINGASYNC(dvp) ? 0 : IO_SYNC), curthread->td_ucred);
+		if (error != 0 && error != ERELOOKUP) {
+			if (!ffs_fsfail_cleanup(VFSTOUFS(mp), error)) {
+				vn_printf(dvp,
+				    "IN_ENDOFF: failed to truncate, "
+				    "error %d\n", error);
+			}
 #ifdef UFS_DIRHASH
-				ufsdirhash_free(dp);
+			ufsdirhash_free(dp);
 #endif
-			}
 		}
 		SET_I_ENDOFF(dp, 0);
 	}
diff --git a/sys/ufs/ufs/ufs_extern.h b/sys/ufs/ufs/ufs_extern.h
index 1697f2c0ba61..3ac631e6ab0b 100644
--- a/sys/ufs/ufs/ufs_extern.h
+++ b/sys/ufs/ufs/ufs_extern.h
@@ -68,7 +68,7 @@ int	 ufs_extwrite(struct vop_write_args *);
 void	 ufs_makedirentry(struct inode *, struct componentname *,
 	    struct direct *);
 int	 ufs_direnter(struct vnode *, struct vnode *, struct direct *,
-	    struct componentname *, struct buf *, int);
+	    struct componentname *, struct buf *);
 int	 ufs_dirremove(struct vnode *, struct inode *, int, int);
 int	 ufs_dirrewrite(struct inode *, struct inode *, ino_t, int, int);
 int	 ufs_lookup_ino(struct vnode *, struct vnode **, struct componentname *,
diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c
index 3036bce81caf..0509185c4663 100644
--- a/sys/ufs/ufs/ufs_lookup.c
+++ b/sys/ufs/ufs/ufs_lookup.c
@@ -876,13 +876,12 @@ ufs_makedirentry(ip, cnp, newdirp)
  * soft dependency code).
  */
 int
-ufs_direnter(dvp, tvp, dirp, cnp, newdirbp, isrename)
+ufs_direnter(dvp, tvp, dirp, cnp, newdirbp)
 	struct vnode *dvp;
 	struct vnode *tvp;
 	struct direct *dirp;
 	struct componentname *cnp;
 	struct buf *newdirbp;
-	int isrename;
 {
 	struct ucred *cr;
 	struct thread *td;
@@ -1111,14 +1110,13 @@ ufs_direnter(dvp, tvp, dirp, cnp, newdirbp, isrename)
 			error = bwrite(bp);
 		}
 	}
-	UFS_INODE_SET_FLAG(dp, IN_CHANGE | IN_UPDATE);
 
 	/*
-	 * If all went well, and the directory can be shortened, mark directory inode
-	 * with the truncation request right before unlock.
+	 * If all went well, and the directory can be shortened,
+	 * mark directory inode with the truncation request.
 	 */
-	if (isrename == 0 && error == 0)
-		UFS_INODE_SET_FLAG(dp, IN_ENDOFF);
+	UFS_INODE_SET_FLAG(dp, IN_CHANGE | IN_UPDATE | (error == 0 &&
+	    I_ENDOFF(dp) != 0 && I_ENDOFF(dp) < dp->i_size ? IN_ENDOFF : 0));
 
 	return (error);
 }
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index c101e699bad6..22199a390dd4 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -1111,7 +1111,7 @@ ufs_link(ap)
 	error = UFS_UPDATE(vp, !DOINGSOFTDEP(vp) && !DOINGASYNC(vp));
 	if (!error) {
 		ufs_makedirentry(ip, cnp, &newdir);
-		error = ufs_direnter(tdvp, vp, &newdir, cnp, NULL, 0);
+		error = ufs_direnter(tdvp, vp, &newdir, cnp, NULL);
 	}
 
 	if (error) {
@@ -1171,7 +1171,7 @@ ufs_whiteout(ap)
 		newdir.d_namlen = cnp->cn_namelen;
 		bcopy(cnp->cn_nameptr, newdir.d_name, (unsigned)cnp->cn_namelen + 1);
 		newdir.d_type = DT_WHT;
-		error = ufs_direnter(dvp, NULL, &newdir, cnp, NULL, 0);
+		error = ufs_direnter(dvp, NULL, &newdir, cnp, NULL);
 		break;
 
 	case DELETE:
@@ -1511,7 +1511,7 @@ relock:
 			}
 		}
 		ufs_makedirentry(fip, tcnp, &newdir);
-		error = ufs_direnter(tdvp, NULL, &newdir, tcnp, NULL, 1);
+		error = ufs_direnter(tdvp, NULL, &newdir, tcnp, NULL);
 		if (error)
 			goto bad;
 		/* Setup tdvp for directory compaction if needed. */
@@ -2132,7 +2132,7 @@ ufs_mkdir(ap)
 	else if (!DOINGSOFTDEP(dvp) && ((error = bwrite(bp))))
 		goto bad;
 	ufs_makedirentry(ip, cnp, &newdir);
-	error = ufs_direnter(dvp, tvp, &newdir, cnp, bp, 0);
+	error = ufs_direnter(dvp, tvp, &newdir, cnp, bp);
 
 bad:
 	if (error == 0) {
@@ -2865,7 +2865,7 @@ ufs_makeinode(mode, dvp, vpp, cnp, callfunc)
 	}
 #endif /* !UFS_ACL */
 	ufs_makedirentry(ip, cnp, &newdir);
-	error = ufs_direnter(dvp, tvp, &newdir, cnp, NULL, 0);
+	error = ufs_direnter(dvp, tvp, &newdir, cnp, NULL);
 	if (error)
 		goto bad;
 	vn_seqc_write_end(tvp);


More information about the dev-commits-src-all mailing list