cluster: RHEL56 - gfs2_convert: gfs2_convert segfaults when converting filesystems of blocksize 512 bytes

Abhijith Das adas at fedoraproject.org
Fri Apr 30 02:30:02 UTC 2010


Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=e16c5e55e999c8f928c398a7afc7f100063d0c7f
Commit:        e16c5e55e999c8f928c398a7afc7f100063d0c7f
Parent:        d97b163ff014f1096a32afc908643dfb8dd396ff
Author:        Abhijith Das <adas at redhat.com>
AuthorDate:    Thu Apr 29 21:26:05 2010 -0500
Committer:     Abhijith Das <adas at redhat.com>
CommitterDate: Thu Apr 29 21:26:05 2010 -0500

gfs2_convert: gfs2_convert segfaults when converting filesystems of blocksize 512 bytes

gfs2_convert segfaults when the jindex inode is unstuffed.
i.e. if the block size is small enough such that the jindex
entries (directly proportional to the number of journals)
don't fit in the disk inode block, the jindex inode is
unstuffed. This is a journaled data file and the structures
are different for such files in gfs1 and gfs2 with respect
to metaheaders. gfs2_convert needs to trick the file
reading code in libgfs2 to think it's dealing with a gfs2
directory (whose structure is similar to a gfs1 jdata inode)
to operate on the file at the right offsets.

Resolves: rhbz#568852
Signed-off-by: Abhi Das <adas at redhat.com>
---
 gfs2/convert/gfs2_convert.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 3a9905e..5a45c96 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -1284,6 +1284,7 @@ static int read_gfs1_jiindex(struct gfs2_sbd *sdp)
 	char buf[sizeof(struct gfs1_jindex)];
 	unsigned int j;
 	int error=0;
+	unsigned int tmp_mode = 0;
 
 	if(ip->i_di.di_size % sizeof(struct gfs1_jindex) != 0){
 		log_crit("The size reported in the journal index"
@@ -1299,6 +1300,14 @@ static int read_gfs1_jiindex(struct gfs2_sbd *sdp)
 		log_crit("Unable to zero journal index\n");
 		return -1;
 	}
+	/* ugly hack
+	 * Faking the gfs1_jindex inode as a directory to gfs2_readi
+	 * so it skips the metaheader struct in the data blocks
+	 * in the inode. gfs2_jindex inode doesn't have metaheaders
+	 * in the data blocks */
+	tmp_mode = ip->i_di.di_mode;
+	ip->i_di.di_mode &= ~S_IFMT;
+	ip->i_di.di_mode |= S_IFDIR;
 	for (j = 0; ; j++) {
 		struct gfs1_jindex *journ;
 
@@ -1315,6 +1324,7 @@ static int read_gfs1_jiindex(struct gfs2_sbd *sdp)
 		gfs1_jindex_in(journ, buf);
 		sdp->jsize = (journ->ji_nsegment * 16 * sdp->bsize) >> 20;
 	}
+	ip->i_di.di_mode = tmp_mode;
 	if(j * sizeof(struct gfs1_jindex) != ip->i_di.di_size){
 		log_crit("journal inode size invalid\n");
 		goto fail;


More information about the cluster-commits mailing list