From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bob Peterson Date: Thu, 29 Oct 2015 14:43:36 -0400 (EDT) Subject: [Cluster-devel] [GFS2 PATCH 2/4 v2] GFS2: Reduce inode size by using 32-bit i_generation In-Reply-To: <738004841.67890144.1446143990693.JavaMail.zimbra@redhat.com> Message-ID: <1516426202.67891865.1446144216343.JavaMail.zimbra@redhat.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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 --- 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 */