[PATCH 12/15] xfs: use vfs inode nlink field everywhere

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Dave Chinner <dchinner@xxxxxxxxxx>

Source kernel commit 54d7b5c1d03e9711cce2d72237d5b3f5c87431f4

The VFS tracks the inode nlink just like the xfs_icdinode. We can
remove the variable from the icdinode and use the VFS inode variable
everywhere, reducing the size of the xfs_icdinode by a further 4
bytes.

Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx>
Reviewed-by: Brian Foster <bfoster@xxxxxxxxxx>
Reviewed-by: Christoph Hellwig <hch@xxxxxx>
Signed-off-by: Dave Chinner <david@xxxxxxxxxxxxx>
---
 include/xfs_inode.h      |  1 +
 libxfs/libxfs_api_defs.h |  4 ++++
 libxfs/util.c            |  5 ++---
 libxfs/xfs_inode_buf.c   |  6 +++---
 libxfs/xfs_inode_buf.h   |  1 -
 mkfs/proto.c             |  4 ++--
 repair/phase6.c          | 18 +++++++++---------
 repair/phase7.c          | 43 ++++++++++++++-----------------------------
 8 files changed, 35 insertions(+), 47 deletions(-)

diff --git a/include/xfs_inode.h b/include/xfs_inode.h
index 1efff0f..e7aa9e9 100644
--- a/include/xfs_inode.h
+++ b/include/xfs_inode.h
@@ -34,6 +34,7 @@ struct xfs_dir_ops;
  * metadata.
  */
 struct inode {
+	uint32_t	i_nlink;
 	struct timespec	i_atime;
 	struct timespec	i_mtime;
 	struct timespec	i_ctime;
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index 685c7a7..1408be3 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -108,4 +108,8 @@
 
 #define xfs_verify_cksum		libxfs_verify_cksum
 
+/* inode link counts */
+#define set_nlink(inode, nlink)	({ (inode)->i_nlink = (nlink); })
+#define inc_nlink(inode)	(inode)->i_nlink++
+
 #endif /* __LIBXFS_API_DEFS_H__ */
diff --git a/libxfs/util.c b/libxfs/util.c
index bbaf790..9327a62 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -218,8 +218,7 @@ libxfs_ialloc(
 	ASSERT(ip != NULL);
 
 	ip->i_d.di_mode = (__uint16_t)mode;
-	ip->i_d.di_nlink = nlink;
-	ASSERT(ip->i_d.di_nlink == nlink);
+	set_nlink(VFS_I(ip), nlink);
 	ip->i_d.di_uid = cr->cr_uid;
 	ip->i_d.di_gid = cr->cr_gid;
 	xfs_set_projid(&ip->i_d, pip ? 0 : fsx->fsx_projid);
@@ -387,7 +386,7 @@ libxfs_iprint(
 		printf("    Other inode\n");
 		break;
 	}
-	printf("   di_nlink %x\n", dip->di_nlink);
+	printf("   di_nlink %x\n", VFS_I(ip)->i_nlink);
 	printf("   di_uid %d\n", dip->di_uid);
 	printf("   di_gid %d\n", dip->di_gid);
 	printf("   di_nextents %d\n", dip->di_nextents);
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index 66a827a..dba8a4b 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -219,12 +219,12 @@ xfs_inode_from_disk(
 	 * minimum inode version format we support in the rest of the code.
 	 */
 	if (to->di_version == 1) {
-		to->di_nlink = be16_to_cpu(from->di_onlink);
+		set_nlink(inode, be16_to_cpu(from->di_onlink));
 		to->di_projid_lo = 0;
 		to->di_projid_hi = 0;
 		to->di_version = 2;
 	} else {
-		to->di_nlink = be32_to_cpu(from->di_nlink);
+		set_nlink(inode, be32_to_cpu(from->di_nlink));
 		to->di_projid_lo = be16_to_cpu(from->di_projid_lo);
 		to->di_projid_hi = be16_to_cpu(from->di_projid_hi);
 	}
@@ -284,7 +284,6 @@ xfs_inode_to_disk(
 	to->di_format = from->di_format;
 	to->di_uid = cpu_to_be32(from->di_uid);
 	to->di_gid = cpu_to_be32(from->di_gid);
-	to->di_nlink = cpu_to_be32(from->di_nlink);
 	to->di_projid_lo = cpu_to_be16(from->di_projid_lo);
 	to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
 
@@ -295,6 +294,7 @@ xfs_inode_to_disk(
 	to->di_mtime.t_nsec = cpu_to_be32(inode->i_mtime.tv_nsec);
 	to->di_ctime.t_sec = cpu_to_be32(inode->i_ctime.tv_sec);
 	to->di_ctime.t_nsec = cpu_to_be32(inode->i_ctime.tv_nsec);
+	to->di_nlink = cpu_to_be32(inode->i_nlink);
 
 	to->di_size = cpu_to_be64(from->di_size);
 	to->di_nblocks = cpu_to_be64(from->di_nblocks);
diff --git a/libxfs/xfs_inode_buf.h b/libxfs/xfs_inode_buf.h
index 489b96e..ccc4052 100644
--- a/libxfs/xfs_inode_buf.h
+++ b/libxfs/xfs_inode_buf.h
@@ -34,7 +34,6 @@ struct xfs_icdinode {
 	__uint16_t	di_flushiter;	/* incremented on flush */
 	__uint32_t	di_uid;		/* owner's user id */
 	__uint32_t	di_gid;		/* owner's group id */
-	__uint32_t	di_nlink;	/* number of links to file */
 	__uint16_t	di_projid_lo;	/* lower part of owner's project id */
 	__uint16_t	di_projid_hi;	/* higher part of owner's project id */
 	xfs_fsize_t	di_size;	/* number of bytes in file */
diff --git a/mkfs/proto.c b/mkfs/proto.c
index 72a1576..9550859 100644
--- a/mkfs/proto.c
+++ b/mkfs/proto.c
@@ -546,7 +546,7 @@ parseproto(
 				&creds, fsxp, &ip);
 		if (error)
 			fail(_("Inode allocation failed"), error);
-		ip->i_d.di_nlink++;		/* account for . */
+		ip->i_vnode.i_nlink++;		/* account for . */
 		if (!pip) {
 			pip = ip;
 			mp->m_sb.sb_rootino = ip->i_ino;
@@ -557,7 +557,7 @@ parseproto(
 			xname.type = XFS_DIR3_FT_DIR;
 			newdirent(mp, tp, pip, &xname, ip->i_ino,
 				  &first, &flist);
-			pip->i_d.di_nlink++;
+			pip->i_vnode.i_nlink++;
 			libxfs_trans_log_inode(tp, pip, XFS_ILOG_CORE);
 		}
 		newdirectory(mp, tp, ip, pip);
diff --git a/repair/phase6.c b/repair/phase6.c
index 00142e2..7e14346 100644
--- a/repair/phase6.c
+++ b/repair/phase6.c
@@ -515,7 +515,7 @@ mk_rbmino(xfs_mount_t *mp)
 	ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
 	ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
 
-	ip->i_d.di_nlink = 1;		/* account for sb ptr */
+	set_nlink(VFS_I(ip), 1);	/* account for sb ptr */
 
 	times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD;
 	if (ip->i_d.di_version == 3) {
@@ -768,7 +768,7 @@ mk_rsumino(xfs_mount_t *mp)
 	ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
 	ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
 
-	ip->i_d.di_nlink = 1;		/* account for sb ptr */
+	set_nlink(VFS_I(ip), 1);	/* account for sb ptr */
 
 	times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD;
 	if (ip->i_d.di_version == 3) {
@@ -877,7 +877,7 @@ mk_root_dir(xfs_mount_t *mp)
 	ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
 	ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
 
-	ip->i_d.di_nlink = 1;		/* account for . */
+	set_nlink(VFS_I(ip), 1);	/* account for . */
 
 	times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD;
 	if (ip->i_d.di_version == 3) {
@@ -976,7 +976,7 @@ mk_orphanage(xfs_mount_t *mp)
 		do_error(_("%s inode allocation failed %d\n"),
 			ORPHANAGE, error);
 	}
-	ip->i_d.di_nlink++;		/* account for . */
+	inc_nlink(VFS_I(ip));		/* account for . */
 	ino = ip->i_ino;
 
 	irec = find_inode_rec(mp,
@@ -1027,7 +1027,7 @@ mk_orphanage(xfs_mount_t *mp)
 	 * bump up the link count in the root directory to account
 	 * for .. in the new directory
 	 */
-	pip->i_d.di_nlink++;
+	inc_nlink(VFS_I(pip));
 	add_inode_ref(find_inode_rec(mp,
 				XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino),
 				XFS_INO_TO_AGINO(mp, mp->m_sb.sb_rootino)), 0);
@@ -1133,7 +1133,7 @@ mv_orphanage(
 			if (irec)
 				add_inode_ref(irec, ino_offset);
 			else
-				orphanage_ip->i_d.di_nlink++;
+				inc_nlink(VFS_I(orphanage_ip));
 			libxfs_trans_log_inode(tp, orphanage_ip, XFS_ILOG_CORE);
 
 			err = -libxfs_dir_createname(tp, ino_p, &xfs_name_dotdot,
@@ -1143,7 +1143,7 @@ mv_orphanage(
 	_("creation of .. entry failed (%d), filesystem may be out of space\n"),
 					err);
 
-			ino_p->i_d.di_nlink++;
+			inc_nlink(VFS_I(ino_p));
 			libxfs_trans_log_inode(tp, ino_p, XFS_ILOG_CORE);
 
 			err = -libxfs_bmap_finish(&tp, &flist, ino_p);
@@ -1176,7 +1176,7 @@ mv_orphanage(
 			if (irec)
 				add_inode_ref(irec, ino_offset);
 			else
-				orphanage_ip->i_d.di_nlink++;
+				inc_nlink(VFS_I(orphanage_ip));
 			libxfs_trans_log_inode(tp, orphanage_ip, XFS_ILOG_CORE);
 
 			/*
@@ -1229,7 +1229,7 @@ mv_orphanage(
 				ORPHANAGE, err);
 		ASSERT(err == 0);
 
-		ino_p->i_d.di_nlink = 1;
+		set_nlink(VFS_I(ino_p), 1);
 		libxfs_trans_log_inode(tp, ino_p, XFS_ILOG_CORE);
 
 		err = -libxfs_bmap_finish(&tp, &flist, ino_p);
diff --git a/repair/phase7.c b/repair/phase7.c
index 72a8ade..3e234b9 100644
--- a/repair/phase7.c
+++ b/repair/phase7.c
@@ -28,31 +28,6 @@
 #include "progress.h"
 #include "threads.h"
 
-/* dinoc is a pointer to the IN-CORE dinode core */
-static void
-set_nlinks(
-	struct xfs_icdinode	*dinoc,
-	xfs_ino_t		ino,
-	__uint32_t		nrefs,
-	int			*dirty)
-{
-	if (dinoc->di_nlink == nrefs)
-		return;
-
-	if (!no_modify) {
-		*dirty = 1;
-		do_warn(_("resetting inode %" PRIu64 " nlinks from %u to %u\n"),
-			ino, dinoc->di_nlink, nrefs);
-
-		ASSERT(dinoc->di_version > 1);
-		dinoc->di_nlink = nrefs;
-	} else  {
-		do_warn(
-_("would have reset inode %" PRIu64 " nlinks from %u to %u\n"),
-			ino, dinoc->di_nlink, nrefs);
-	}
-}
-
 static void
 update_inode_nlinks(
 	xfs_mount_t 		*mp,
@@ -88,10 +63,20 @@ update_inode_nlinks(
 
 	dirty = 0;
 
-	/*
-	 * compare and set links for all inodes
-	 */
-	set_nlinks(&ip->i_d, ino, nlinks, &dirty);
+	/* compare and set links if they differ.  */
+	if (VFS_I(ip)->i_nlink != nlinks) {
+		if (!no_modify) {
+			do_warn(
+	_("resetting inode %" PRIu64 " nlinks from %u to %u\n"),
+				ino, VFS_I(ip)->i_nlink, nlinks);
+			set_nlink(VFS_I(ip), nlinks);
+			dirty = 1;
+		} else {
+			do_warn(
+	_("would have reset inode %" PRIu64 " nlinks from %u to %u\n"),
+				ino, VFS_I(ip)->i_nlink, nlinks);
+		}
+	}
 
 	if (!dirty)  {
 		libxfs_trans_cancel(tp);
-- 
2.7.0

_______________________________________________
xfs mailing list
xfs@xxxxxxxxxxx
http://oss.sgi.com/mailman/listinfo/xfs



[Index of Archives]     [Linux XFS Devel]     [Linux Filesystem Development]     [Filesystem Testing]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux