From mboxrd@z Thu Jan 1 00:00:00 1970 From: Steven Whitehouse Date: Fri, 12 Aug 2011 10:25:31 +0100 Subject: [Cluster-devel] [Patch 11/44] fsck.gfs2: directory entry count was only 16 bits in check_entries In-Reply-To: <472680793.544681.1313096563272.JavaMail.root@zmail06.collab.prod.int.phx2.redhat.com> References: <472680793.544681.1313096563272.JavaMail.root@zmail06.collab.prod.int.phx2.redhat.com> Message-ID: <1313141131.2704.28.camel@menhir> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Hi, Ah, now I see :-) That makes sense now, Steve. On Thu, 2011-08-11 at 17:02 -0400, Bob Peterson wrote: > >From 0dc5622515a2e888efd89cb33e7c2fe600f895a5 Mon Sep 17 00:00:00 2001 > From: Bob Peterson > Date: Mon, 8 Aug 2011 14:38:19 -0500 > Subject: [PATCH 11/44] fsck.gfs2: directory entry count was only 16 bits in > check_entries > > When counting directory links, fsck.gfs2 was using a 16-bit integer. > Therefore, if a directory had more than 65535 links, it would wrap to > zero and the counts would be damaged by fsck.gfs2. Subsequent runs would > not find the corruption, but it was there nonetheless. You would > encounter it if you tried to delete enough entries to cause the count > to become negative. > > rhbz#675723 > --- > gfs2/fsck/fsck.h | 6 +++--- > gfs2/fsck/metawalk.c | 8 ++++---- > gfs2/fsck/metawalk.h | 2 +- > gfs2/fsck/pass1.c | 2 +- > gfs2/fsck/pass1b.c | 4 ++-- > gfs2/fsck/pass2.c | 2 +- > 6 files changed, 12 insertions(+), 12 deletions(-) > > diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h > index 6353dfc..0fed06b 100644 > --- a/gfs2/fsck/fsck.h > +++ b/gfs2/fsck/fsck.h > @@ -29,9 +29,9 @@ struct inode_info > { > struct osi_node node; > uint64_t inode; > - uint16_t di_nlink; /* the number of links the inode > - * thinks it has */ > - uint16_t counted_links; /* the number of links we've found */ > + uint32_t di_nlink; /* the number of links the inode > + * thinks it has */ > + uint32_t counted_links; /* the number of links we've found */ > }; > > struct dir_info > diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c > index ea1774a..f2cd938 100644 > --- a/gfs2/fsck/metawalk.c > +++ b/gfs2/fsck/metawalk.c > @@ -300,7 +300,7 @@ static void dirblk_truncate(struct gfs2_inode *ip, struct gfs2_dirent *fixb, > * -1 - error occurred > */ > static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, > - int type, uint16_t *count, struct metawalk_fxns *pass) > + int type, uint32_t *count, struct metawalk_fxns *pass) > { > struct gfs2_dirent *dent; > struct gfs2_dirent de, *prev; > @@ -596,7 +596,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) > struct gfs2_buffer_head *lbh; > int lindex; > struct gfs2_sbd *sdp = ip->i_sbd; > - uint16_t count; > + uint32_t count; > int ref_count = 0, exp_count = 0; > > /* Find the first valid leaf pointer in range and use it as our "old" > @@ -1373,7 +1373,7 @@ int check_linear_dir(struct gfs2_inode *ip, struct gfs2_buffer_head *bh, > struct metawalk_fxns *pass) > { > int error = 0; > - uint16_t count = 0; > + uint32_t count = 0; > > error = check_entries(ip, bh, DIR_LINEAR, &count, pass); > if (error < 0) { > @@ -1406,7 +1406,7 @@ int check_dir(struct gfs2_sbd *sdp, uint64_t block, struct metawalk_fxns *pass) > static int remove_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, > struct gfs2_dirent *prev_de, > struct gfs2_buffer_head *bh, > - char *filename, uint16_t *count, void *private) > + char *filename, uint32_t *count, void *private) > { > /* the metawalk_fxn's private field must be set to the dentry > * block we want to clear */ > diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h > index ea023b6..c15d7b7 100644 > --- a/gfs2/fsck/metawalk.h > +++ b/gfs2/fsck/metawalk.h > @@ -74,7 +74,7 @@ struct metawalk_fxns { > int (*check_dentry) (struct gfs2_inode *ip, struct gfs2_dirent *de, > struct gfs2_dirent *prev, > struct gfs2_buffer_head *bh, > - char *filename, uint16_t *count, void *private); > + char *filename, uint32_t *count, void *private); > int (*check_eattr_entry) (struct gfs2_inode *ip, > struct gfs2_buffer_head *leaf_bh, > struct gfs2_ea_header *ea_hdr, > diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c > index 1bd8464..b9aa165 100644 > --- a/gfs2/fsck/pass1.c > +++ b/gfs2/fsck/pass1.c > @@ -147,7 +147,7 @@ static int resuscitate_metalist(struct gfs2_inode *ip, uint64_t block, > static int resuscitate_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, > struct gfs2_dirent *prev_de, > struct gfs2_buffer_head *bh, char *filename, > - uint16_t *count, void *priv) > + uint32_t *count, void *priv) > { > struct gfs2_sbd *sdp = ip->i_sbd; > struct gfs2_dirent dentry, *de; > diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c > index bbf33d2..9497c78 100644 > --- a/gfs2/fsck/pass1b.c > +++ b/gfs2/fsck/pass1b.c > @@ -49,7 +49,7 @@ static int check_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr, > void *private); > static int find_dentry(struct gfs2_inode *ip, struct gfs2_dirent *de, > struct gfs2_dirent *prev, struct gfs2_buffer_head *bh, > - char *filename, uint16_t *count, void *priv); > + char *filename, uint32_t *count, void *priv); > > struct metawalk_fxns find_refs = { > .private = NULL, > @@ -168,7 +168,7 @@ static int check_dir_dup_ref(struct gfs2_inode *ip, struct gfs2_dirent *de, > static int find_dentry(struct gfs2_inode *ip, struct gfs2_dirent *de, > struct gfs2_dirent *prev, > struct gfs2_buffer_head *bh, char *filename, > - uint16_t *count, void *priv) > + uint32_t *count, void *priv) > { > struct osi_node *n, *next = NULL; > osi_list_t *tmp2; > diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c > index 614c963..1143a15 100644 > --- a/gfs2/fsck/pass2.c > +++ b/gfs2/fsck/pass2.c > @@ -175,7 +175,7 @@ struct metawalk_fxns pass2_fxns_delete = { > static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent, > struct gfs2_dirent *prev_de, > struct gfs2_buffer_head *bh, char *filename, > - uint16_t *count, void *priv) > + uint32_t *count, void *priv) > { > struct gfs2_sbd *sdp = ip->i_sbd; > uint8_t q;