cluster-devel.redhat.com archive mirror
 help / color / mirror / Atom feed
From: Bob Peterson <rpeterso@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [GFS2 PATCH 2/4 v2] GFS2: Reduce inode size by using 32-bit i_generation
Date: Thu, 29 Oct 2015 14:43:36 -0400 (EDT)	[thread overview]
Message-ID: <1516426202.67891865.1446144216343.JavaMail.zimbra@redhat.com> (raw)
In-Reply-To: <738004841.67890144.1446143990693.JavaMail.zimbra@redhat.com>

Hi,

This patch fixes the problems Andy Price pointed out.
I also added more explanation to the patch text, as requested.

Regards,

Bob Peterson
Red Hat File Systems
---
GFS2: Reduce inode size by using 32-bit i_generation

This patch removes variable i_generation from gfs2_inode. In its
place, we use inode->i_generation which is pretty much the same thing,
in 32-bits. The loss of 32 bits should not be a problem.
The generation number is kept 64 bits for the on-disk structures,
since that cannot change, so only the on-disk structures are changed.

For inodes, the generation number is only used for debugging purposes:
if there is file system corruption, we may be able to track back the
revision numbers through the journals to determine the cause.

The patch also does the same thing for resource group generation
numbers, although there's another purpose besides debugging: For
resource groups, the generation number is also used to determine if
a resource group has changed on a different node based on whether
the generation number has changed in the lvb (forcing an invalidation
and re-reading the media). The change from 64 to 32 bits should not
be a problem there either, since a wrap-around in the generation
number still counts as a change of the rgrp, and therefore it will be
handled the same way. Note how function gfs2_rgrp_lvb_valid() checks
the lvb is valid with "rgl->rl_igen2 != str->rg_igen2". If this was
"<=" or ">=" we'd have a problem, but "!=" is safe.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
---
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index f348cfb..017a8b3 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -358,7 +358,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
 	ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec);
 
 	ip->i_goal = be64_to_cpu(str->di_goal_meta);
-	ip->i_generation = be64_to_cpu(str->di_generation);
+	ip->i_inode.i_generation = be32_to_cpu(str->di_gen2);
 
 	ip->i_diskflags = be32_to_cpu(str->di_flags);
 	ip->i_eattr = be64_to_cpu(str->di_eattr);
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 7113284..fcdacf1 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -88,7 +88,7 @@ struct gfs2_rgrpd {
 	u32 rd_reserved;                /* number of blocks reserved */
 	u32 rd_free_clone;
 	u32 rd_dinodes;
-	u64 rd_igeneration;
+	u32 rd_igeneration;
 	struct gfs2_bitmap *rd_bits;
 	struct gfs2_sbd *rd_sbd;
 	struct gfs2_rgrp_lvb *rd_rgl;
@@ -384,7 +384,6 @@ struct gfs2_inode {
 	struct inode i_inode;
 	u64 i_no_addr;
 	u64 i_no_formal_ino;
-	u64 i_generation;
 	u64 i_eattr;
 	unsigned long i_flags;		/* GIF_... */
 	struct gfs2_glock *i_gl; /* Move into i_gh? */
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 063fdfc..cc815ab 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -394,8 +394,9 @@ static int alloc_dinode(struct gfs2_inode *ip, u32 flags, unsigned *dblocks)
 	if (error)
 		goto out_ipreserv;
 
-	error = gfs2_alloc_blocks(ip, &ip->i_no_addr, dblocks, 1, &ip->i_generation);
-	ip->i_no_formal_ino = ip->i_generation;
+	error = gfs2_alloc_blocks(ip, &ip->i_no_addr, dblocks, 1,
+				  &ip->i_inode.i_generation);
+	ip->i_no_formal_ino = ip->i_inode.i_generation;
 	ip->i_inode.i_ino = ip->i_no_addr;
 	ip->i_goal = ip->i_no_addr;
 
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index d29dd0c..682f6a3 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -1062,7 +1062,7 @@ static void gfs2_rgrp_in(struct gfs2_rgrpd *rgd, const void *buf)
 	rgd->rd_flags |= rg_flags;
 	rgd->rd_free = be32_to_cpu(str->rg_free);
 	rgd->rd_dinodes = be32_to_cpu(str->rg_dinodes);
-	rgd->rd_igeneration = be64_to_cpu(str->rg_igeneration);
+	rgd->rd_igeneration = be32_to_cpu(str->rg_igen2);
 }
 
 static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf)
@@ -1073,7 +1073,7 @@ static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf)
 	str->rg_free = cpu_to_be32(rgd->rd_free);
 	str->rg_dinodes = cpu_to_be32(rgd->rd_dinodes);
 	str->__pad = cpu_to_be32(0);
-	str->rg_igeneration = cpu_to_be64(rgd->rd_igeneration);
+	str->rg_igen2 = cpu_to_be32(rgd->rd_igeneration);
 	memset(&str->rg_reserved, 0, sizeof(str->rg_reserved));
 }
 
@@ -1084,7 +1084,7 @@ static int gfs2_rgrp_lvb_valid(struct gfs2_rgrpd *rgd)
 
 	if (rgl->rl_flags != str->rg_flags || rgl->rl_free != str->rg_free ||
 	    rgl->rl_dinodes != str->rg_dinodes ||
-	    rgl->rl_igeneration != str->rg_igeneration)
+	    rgl->rl_igen2 != str->rg_igen2)
 		return 0;
 	return 1;
 }
@@ -1097,7 +1097,7 @@ static void gfs2_rgrp_ondisk2lvb(struct gfs2_rgrp_lvb *rgl, const void *buf)
 	rgl->rl_flags = str->rg_flags;
 	rgl->rl_free = str->rg_free;
 	rgl->rl_dinodes = str->rg_dinodes;
-	rgl->rl_igeneration = str->rg_igeneration;
+	rgl->rl_igen2 = str->rg_igen2;
 	rgl->__pad = 0UL;
 }
 
@@ -1229,7 +1229,7 @@ static int update_rgrp_lvb(struct gfs2_rgrpd *rgd)
 	rgd->rd_free = be32_to_cpu(rgd->rd_rgl->rl_free);
 	rgd->rd_free_clone = rgd->rd_free;
 	rgd->rd_dinodes = be32_to_cpu(rgd->rd_rgl->rl_dinodes);
-	rgd->rd_igeneration = be64_to_cpu(rgd->rd_rgl->rl_igeneration);
+	rgd->rd_igeneration = be32_to_cpu(rgd->rd_rgl->rl_igen2);
 	return 0;
 }
 
@@ -2334,7 +2334,7 @@ static void gfs2_set_alloc_start(struct gfs2_rbm *rbm,
  */
 
 int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,
-		      bool dinode, u64 *generation)
+		      bool dinode, u32 *generation)
 {
 	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct buffer_head *dibh;
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
index c0ab33f..71c1a8e 100644
--- a/fs/gfs2/rgrp.h
+++ b/fs/gfs2/rgrp.h
@@ -47,7 +47,7 @@ extern int gfs2_inplace_reserve(struct gfs2_inode *ip,
 extern void gfs2_inplace_release(struct gfs2_inode *ip);
 
 extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n,
-			     bool dinode, u64 *generation);
+			     bool dinode, u32 *generation);
 
 extern int gfs2_rs_alloc(struct gfs2_inode *ip);
 extern void gfs2_rs_deltree(struct gfs2_blkreserv *rs);
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 894fb01..45a5566 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -714,7 +714,7 @@ void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf)
 
 	str->di_goal_meta = cpu_to_be64(ip->i_goal);
 	str->di_goal_data = cpu_to_be64(ip->i_goal);
-	str->di_generation = cpu_to_be64(ip->i_generation);
+	str->di_gen2 = cpu_to_be32(ip->i_inode.i_generation);
 
 	str->di_flags = cpu_to_be32(ip->i_diskflags);
 	str->di_height = cpu_to_be16(ip->i_height);
diff --git a/include/uapi/linux/gfs2_ondisk.h b/include/uapi/linux/gfs2_ondisk.h
index 1a763ea..62e469d 100644
--- a/include/uapi/linux/gfs2_ondisk.h
+++ b/include/uapi/linux/gfs2_ondisk.h
@@ -175,7 +175,13 @@ struct gfs2_rgrp_lvb {
 	__be32 rl_flags;
 	__be32 rl_free;
 	__be32 rl_dinodes;
-	__be64 rl_igeneration;
+	union {
+		__be64 rl_igeneration;
+		struct {
+			__be32 __pad1;
+			__be32 rl_igen2;
+		};
+	};
 	__be32 rl_unlinked;
 	__be32 __pad;
 };
@@ -187,7 +193,13 @@ struct gfs2_rgrp {
 	__be32 rg_free;
 	__be32 rg_dinodes;
 	__be32 __pad;
-	__be64 rg_igeneration;
+	union {
+		__be64 rg_igeneration;
+		struct {
+			__be32 __pad1;
+			__be32 rg_igen2;
+		};
+	};
 
 	__u8 rg_reserved[80]; /* Several fields from gfs1 now reserved */
 };
@@ -268,8 +280,13 @@ struct gfs2_dinode {
 	 */
 	__be64 di_goal_meta;	/* rgrp to alloc from next */
 	__be64 di_goal_data;	/* data block goal */
-	__be64 di_generation;	/* generation number for NFS */
-
+	union {
+		__be64 di_generation;	/* generation number for NFS */
+		struct {
+			__be32 __pad5;
+			__be32 di_gen2;
+		};
+	};
 	__be32 di_flags;	/* GFS2_DIF_... */
 	__be32 di_payload_format;  /* GFS2_FORMAT_... */
 	__u16 __pad1;	/* Was ditype in gfs1 */



  reply	other threads:[~2015-10-29 18:43 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-28 14:20 [Cluster-devel] [PATCH 0/4] Fix erroneous ETXTBSY problems with GFS2 Bob Peterson
2015-10-28 14:20 ` [Cluster-devel] [PATCH 1/4] GFS2: Reduce size of incore inode Bob Peterson
2015-10-30 10:34   ` Steven Whitehouse
2015-10-28 14:20 ` [Cluster-devel] [PATCH 2/4] GFS2: Reduce inode size by using 32-bit i_generation Bob Peterson
2015-10-29 17:21   ` Andrew Price
2015-10-29 18:39     ` Bob Peterson
2015-10-29 18:43       ` Bob Peterson [this message]
2015-10-30 10:42   ` Steven Whitehouse
2015-10-28 14:20 ` [Cluster-devel] [PATCH 3/4] GFS2: Extract quota data from reservations structure (revert 5407e24) Bob Peterson
2015-10-28 14:20 ` [Cluster-devel] [PATCH 4/4] GFS2: Make rgrp reservations part of the gfs2_inode structure Bob Peterson
2015-10-29 17:21 ` [Cluster-devel] [PATCH 0/4] Fix erroneous ETXTBSY problems with GFS2 Andrew Price

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1516426202.67891865.1446144216343.JavaMail.zimbra@redhat.com \
    --to=rpeterso@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).