gfs2-utils: master - gfs2_convert: gfs2_convert segfaults when converting filesystems of blocksize 512 bytes

Abhijith Das adas at fedoraproject.org
Tue Apr 20 15:38:53 UTC 2010


Gitweb:        http://git.fedorahosted.org/git/gfs2-utils.git?p=gfs2-utils.git;a=commitdiff;h=e41bb86156dad9a8335634494fa1d902f7eaa6f5
Commit:        e41bb86156dad9a8335634494fa1d902f7eaa6f5
Parent:        3f5709b2167d405435730ae9103f48116cc2c9a2
Author:        Abhijith Das <adas at redhat.com>
AuthorDate:    Wed Apr 7 11:51:47 2010 -0500
Committer:     Abhijith Das <adas at redhat.com>
CommitterDate: Tue Apr 20 10:35:30 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#579621
Signed-off-by: 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 e28b8e7..f128efb 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -1281,6 +1281,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"
@@ -1296,6 +1297,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;
 
@@ -1312,6 +1321,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