Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 9383e745e23602bc45f9c92184feea59 > files > 105

gfs2-utils-0.1.62-28.el5.src.rpm

commit e16c5e55e999c8f928c398a7afc7f100063d0c7f
Author: Abhijith Das <adas@redhat.com>
Date:   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@redhat.com>

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;