Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 May 2023 02:28:44 GMT
From:      Kirk McKusick <mckusick@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: e4a905d1e0d9 - main - Add the ability to adjust directory depths to background fsck_ffs(8).
Message-ID:  <202305260228.34Q2SiFi051613@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by mckusick:

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

commit e4a905d1e0d94ddb8e15de50d37e67f13e058047
Author:     Kirk McKusick <mckusick@FreeBSD.org>
AuthorDate: 2023-05-26 02:27:04 +0000
Commit:     Kirk McKusick <mckusick@FreeBSD.org>
CommitDate: 2023-05-26 02:27:04 +0000

    Add the ability to adjust directory depths to background fsck_ffs(8).
    
    Commit fe5e6e2 improved FFS directory placement when creating new
    directories. It is done by keeping track of the depth of directories
    in the filesystem and placing those lower in the tree closer together
    while spreading out those higher in the tree.
    
    Fsck_ffs(8) checks these depths and if incorrect adjusts them to
    their correct value. When running in background fsck_ffs(8) needs
    to be able to make an adjustment to the depth. This commit adds
    the sysctl to make such an adjustment and adds the code to fsck_ffs(8)
    to use the new sysctl.
    
    MFC after:    1 week
    Sponsored by: The FreeBSD Foundation
---
 sbin/fsck_ffs/dir.c     | 26 +++++++++++++++++++++-----
 sbin/fsck_ffs/fsck.h    |  1 +
 sbin/fsck_ffs/globs.c   |  2 ++
 sys/ufs/ffs/ffs_alloc.c | 28 ++++++++++++++++++++++++++++
 sys/ufs/ffs/fs.h        |  3 ++-
 5 files changed, 54 insertions(+), 6 deletions(-)

diff --git a/sbin/fsck_ffs/dir.c b/sbin/fsck_ffs/dir.c
index cc5305c390a4..e5f0e1e7e7f4 100644
--- a/sbin/fsck_ffs/dir.c
+++ b/sbin/fsck_ffs/dir.c
@@ -105,6 +105,7 @@ check_dirdepth(struct inoinfo *inp)
 	struct inode ip;
 	union dinode *dp;
 	int saveresolved;
+	size_t size;
 	static int updateasked, dirdepthupdate;
 
 	if ((parentinp = getinoinfo(inp->i_parent)) == NULL) {
@@ -141,9 +142,11 @@ check_dirdepth(struct inoinfo *inp)
 		}
 	}
 	/*
-	 * If we are not converting, nothing more to do.
+	 * If we are not converting or we are running in no-write mode
+	 * there is nothing more to do.
 	 */
-	if (inp->i_depth == 0 && dirdepthupdate == 0)
+	if ((inp->i_depth == 0 && dirdepthupdate == 0) ||
+	    (fswritefd < 0 && bkgrdflag == 0))
 		return;
 	/*
 	 * Individual directory at wrong depth. Report it and correct if
@@ -174,8 +177,20 @@ check_dirdepth(struct inoinfo *inp)
 			printf(" (ADJUSTED)\n");
 	}
 	inp->i_depth = parentinp->i_depth + 1;
-	DIP_SET(dp, di_dirdepth, inp->i_depth);
-	inodirty(&ip);
+	if (bkgrdflag == 0) {
+		DIP_SET(dp, di_dirdepth, inp->i_depth);
+		inodirty(&ip);
+	} else {
+		cmd.value = inp->i_number;
+		cmd.size = (int64_t)inp->i_depth - DIP(dp, di_dirdepth);
+		if (debug)
+			printf("adjdepth ino %ld amt %jd\n", (long)cmd.value,
+			    (intmax_t)cmd.size);
+		size = MIBSIZE;
+		if (sysctlnametomib("vfs.ffs.adjdepth", adjdepth, &size) < 0 ||
+		    sysctl(adjdepth, MIBSIZE, 0, 0, &cmd, sizeof cmd) == -1)
+			rwerror("ADJUST INODE DEPTH", cmd.value);
+	}
 	irelse(&ip);
 }
 
@@ -506,7 +521,8 @@ adjust(struct inodesc *idesc, int lcnt)
 					    (long long)cmd.size);
 				if (sysctl(adjrefcnt, MIBSIZE, 0, 0,
 				    &cmd, sizeof cmd) == -1)
-					rwerror("ADJUST INODE", cmd.value);
+					rwerror("ADJUST INODE LINK COUNT",
+					    cmd.value);
 			}
 		}
 	}
diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h
index 092d9575dc2a..ad82c5f80da1 100644
--- a/sbin/fsck_ffs/fsck.h
+++ b/sbin/fsck_ffs/fsck.h
@@ -333,6 +333,7 @@ extern int adjnbfree[MIBSIZE];	/* MIB cmd to adjust number of free blocks */
 extern int adjnifree[MIBSIZE];	/* MIB cmd to adjust number of free inodes */
 extern int adjnffree[MIBSIZE];	/* MIB cmd to adjust number of free frags */
 extern int adjnumclusters[MIBSIZE]; /* MIB cmd adjust number of free clusters */
+extern int adjdepth[MIBSIZE];	/* MIB cmd to adjust directory depth count */
 extern int freefiles[MIBSIZE];	/* MIB cmd to free a set of files */
 extern int freedirs[MIBSIZE];	/* MIB cmd to free a set of directories */
 extern int freeblks[MIBSIZE];	/* MIB cmd to free a set of data blocks */
diff --git a/sbin/fsck_ffs/globs.c b/sbin/fsck_ffs/globs.c
index bce499754301..7aef7364eeba 100644
--- a/sbin/fsck_ffs/globs.c
+++ b/sbin/fsck_ffs/globs.c
@@ -68,6 +68,7 @@ int	adjnbfree[MIBSIZE];	/* MIB command to adjust number of free blocks */
 int	adjnifree[MIBSIZE];	/* MIB command to adjust number of free inodes */
 int	adjnffree[MIBSIZE];	/* MIB command to adjust number of free frags */
 int	adjnumclusters[MIBSIZE];	/* MIB command to adjust number of free clusters */
+int	adjdepth[MIBSIZE];	/* MIB cmd to adjust directory depth count */
 int	freefiles[MIBSIZE];	/* MIB command to free a set of files */
 int	freedirs[MIBSIZE];	/* MIB command to free a set of directories */
 int	freeblks[MIBSIZE];	/* MIB command to free a set of data blocks */
@@ -140,6 +141,7 @@ fsckinit(void)
 	bzero(adjnifree, sizeof(int) * MIBSIZE);
 	bzero(adjnffree, sizeof(int) * MIBSIZE);
 	bzero(adjnumclusters, sizeof(int) * MIBSIZE);
+	bzero(adjdepth, sizeof(int) * MIBSIZE);
 	bzero(freefiles, sizeof(int) * MIBSIZE);
 	bzero(freedirs, sizeof(int) * MIBSIZE);
 	bzero(freeblks, sizeof(int) * MIBSIZE);
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index fbc99951bcc6..957be753ce15 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -3108,6 +3108,8 @@ ffs_fserr(struct fs *fs,
  *	the count to zero will cause the inode to be freed.
  * adjblkcnt(inode, amt) - adjust the number of blocks used by the
  *	inode by the specified amount.
+ * adjdepth(inode, amt) - adjust the depth of the specified directory
+ *	inode by the specified amount.
  * setsize(inode, size) - set the size of the inode to the
  *	specified size.
  * adjndir, adjbfree, adjifree, adjffree, adjnumclusters(amt) -
@@ -3142,6 +3144,10 @@ static SYSCTL_NODE(_vfs_ffs, FFS_ADJ_BLKCNT, adjblkcnt,
     CTLFLAG_WR | CTLFLAG_NEEDGIANT, sysctl_ffs_fsck,
     "Adjust Inode Used Blocks Count");
 
+static SYSCTL_NODE(_vfs_ffs, FFS_ADJ_DEPTH, adjdepth,
+    CTLFLAG_WR | CTLFLAG_NEEDGIANT, sysctl_ffs_fsck,
+    "Adjust Directory Inode Depth");
+
 static SYSCTL_NODE(_vfs_ffs, FFS_SET_SIZE, setsize,
     CTLFLAG_WR | CTLFLAG_NEEDGIANT, sysctl_ffs_fsck,
     "Set the inode size");
@@ -3299,6 +3305,28 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS)
 		vput(vp);
 		break;
 
+	case FFS_ADJ_DEPTH:
+#ifdef DIAGNOSTIC
+		if (fsckcmds) {
+			printf("%s: adjust directory inode %jd depth by %jd\n",
+			    mp->mnt_stat.f_mntonname, (intmax_t)cmd.value,
+			    (intmax_t)cmd.size);
+		}
+#endif /* DIAGNOSTIC */
+		if ((error = ffs_vget(mp, (ino_t)cmd.value, LK_EXCLUSIVE, &vp)))
+			break;
+		if (vp->v_type != VDIR) {
+			vput(vp);
+			error = ENOTDIR;
+			break;
+		}
+		ip = VTOI(vp);
+		DIP_SET(ip, i_dirdepth, DIP(ip, i_dirdepth) + cmd.size);
+		UFS_INODE_SET_FLAG(ip, IN_CHANGE | IN_MODIFIED);
+		error = ffs_update(vp, 1);
+		vput(vp);
+		break;
+
 	case FFS_SET_SIZE:
 #ifdef DIAGNOSTIC
 		if (fsckcmds) {
diff --git a/sys/ufs/ffs/fs.h b/sys/ufs/ffs/fs.h
index 7b7a1f9f2ef6..1f2a56c26641 100644
--- a/sys/ufs/ffs/fs.h
+++ b/sys/ufs/ffs/fs.h
@@ -263,7 +263,8 @@
 /* Was FFS_SET_INODE		15 */
 /* Was FFS_SET_BUFOUTPUT	16 */
 #define	FFS_SET_SIZE		17	/* set inode size */
-#define	FFS_MAXID		17	/* number of valid ffs ids */
+#define	FFS_ADJ_DEPTH		18	/* adjust directory inode depth */
+#define	FFS_MAXID		18	/* number of valid ffs ids */
 
 /*
  * Command structure passed in to the filesystem to adjust filesystem values.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202305260228.34Q2SiFi051613>