[Cluster-devel] [PATCH 2/2] gfs2-utils: check and fix bad dinode pointers in gfs1 sb

Abhijith Das adas at redhat.com
Wed Mar 12 17:47:02 UTC 2014


Hi Bob,

Thanks for the review.

> ----- Original Message -----
> | This patch makes gfs2_convert check for bad values of sb_seg_size,
> | sb_quota_di and sb_license_di.
> | 
> | In fsck.gfs2, attempts are made to correct these erroneous values.
> | 
> | Resolves: rhbz#1053668
> | Signed-off-by: Abhi Das <adas at redhat.com>
> (snip)
> | diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
> | index 0f33aa6..24e5de2 100644
> | --- a/gfs2/fsck/initialize.c
> | +++ b/gfs2/fsck/initialize.c
> | @@ -727,6 +727,13 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
> |  	}
> |  
> |  	if (sdp->gfs1) {
> | +		/* In gfs1, the license_di is always 3 blocks after the jindex_di */
> | +		if (sbd1->sb_license_di.no_addr != sbd1->sb_jindex_di.no_addr + 3) {
> | +			sbd1->sb_license_di.no_addr = sbd1->sb_license_di.no_formal_ino
> | +				= sbd1->sb_jindex_di.no_addr + 3;
> | +			log_err(_("Reset statfs inode block address to: %llu\n"),
> | +				sbd1->sb_license_di.no_addr);
> | +		}
> 
> This resolves the problem in memory, but doesn't fix it on disk.
> We should probably fix it on disk and also use function query() to
> get their permission. Same for the quota file.

I took a quick look at the code and I only found lgfs2_sb_write() being called in
block_mounters()... which happens before init_system_inodes. But I could've sworn
the changes propagated to disk. I remember seeing it with gfs2_edit after the fsck.

I'll look into this and also add the permission check before changing the value.

> 
> | +static int reset_journal_seg_size(unsigned int jsize, unsigned int nsegs,
> | +					     unsigned int bsize)
> | +{
> | +	unsigned int seg_size = jsize / (nsegs * bsize);
> | +	if (!seg_size)
> | +		seg_size = 16; /* The default with 128MB journal and 4K bsize */
> | +	if (seg_size != sbd1->sb_seg_size) {
> | +		sbd1->sb_seg_size = seg_size;
> | +		if (!query(_("Computed correct journal segment size to %u."
> | +			     " Reset it? (y/n) "), seg_size)) {
> | +			log_crit(_("Error: Cannot proceed without a valid journal"
> | +				   " segment size value.\n"));
> | +			return -1;
> | +		}
> | +		log_err(_("Resetting journal segment size to %u\n"), sbd1->sb_seg_size);
> 
> Is the superblock being rewritten with the new value anywhere?
> If the value is only used for fsck purposes, then no problem. If
> there are places in gfs2_convert that may reference it (possibly
> through libgfs2) then we should fix it on disk as well.

Same thing here. I'll take a look.

> 
> | +static int correct_journal_seg_size(struct gfs2_sbd *sdp)
> | +{
> | +	int count;
> | +	struct gfs_jindex ji_0, ji_1;
> | +	char buf[sizeof(struct gfs_jindex)];
> | +	unsigned int jsize = GFS2_DEFAULT_JSIZE * 1024 * 1024;
> | +
> | +	count = gfs2_readi(sdp->md.jiinode, buf, 0, sizeof(struct gfs_jindex));
> | +	if (count != sizeof(struct gfs_jindex))
> | +		return -1;
> 
> We should probably log an error message here.
> 
> | +	return reset_journal_seg_size(jsize, ji_0.ji_nsegment, sbd1->sb_bsize);
> 
> ALso, make sure to test with a clean file system and "-n" to make sure it
> doesn't try to make changes. I think it's okay, but I always check it
> (I've been burned too many times in the past!).
> 

Yeah. I'll do that.

Cheers!
--Abhi
> Regards,
> 
> Bob Peterson
> Red Hat File Systems
> 




More information about the Cluster-devel mailing list