LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File gfs2_edit_tiny_files_had_user_data_saved_with_savemeta.patch of Package cluster (Project home:sschapiro:openstack:upstream)

commit 0f2b41806d9f911c344998b3e53f8d7fac447f35
Author: Bob Peterson <bob@ganesha.(none)>
Date:   Thu Sep 30 14:36:59 2010 -0500

    gfs2_edit: tiny (stuffed) files had user data saved with savemeta
    
    The gfs2_edit savemeta option was saving the entire block for dinodes.
    That's okay for average files where you need to save indirect block
    pointers.  It's okay for directories where you need to save the
    directory block pointers.  It's okay for system files where you want
    to save statfs data or inum data and such.  But it's not okay with
    stuffed user files because they contain user data.  This patch checks
    for this special dinode condition and saves only the dinode
    structure.
    
    rhbz#634623

diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index c052acf..0fff1f3 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -41,6 +41,24 @@ int journals_found = 0;
 
 extern void read_superblock(void);
 
+static int block_is_a_journal(void)
+{
+	int j;
+
+	for (j = 0; j < journals_found; j++)
+		if (block == journal_blocks[j])
+			return TRUE;
+	return FALSE;
+}
+
+static int block_is_systemfile(void)
+{
+	return block_is_jindex() || block_is_inum_file() ||
+		block_is_statfs_file() || block_is_quota_file() ||
+		block_is_rindex() || block_is_a_journal() ||
+		block_is_per_node() || block_is_in_per_node();
+}
+
 /*
  * get_gfs_struct_info - get block type and structure length
  *
@@ -54,6 +72,7 @@ static int get_gfs_struct_info(struct gfs2_buffer_head *lbh, int *block_type,
 			       int *gstruct_len)
 {
 	struct gfs2_meta_header mh;
+	struct gfs2_inode *inode;
 
 	*block_type = 0;
 	*gstruct_len = sbd.bsize;
@@ -75,7 +94,19 @@ static int get_gfs_struct_info(struct gfs2_buffer_head *lbh, int *block_type,
 		*gstruct_len = sbd.bsize;
 		break;
 	case GFS2_METATYPE_DI:   /* 4 (disk inode) */
-		*gstruct_len = sbd.bsize; /*sizeof(struct gfs_dinode);*/
+		if (gfs1)
+			inode = inode_get(&sbd, lbh);
+		else
+			inode = gfs_inode_get(&sbd, lbh);
+		if (inode->i_di.di_flags & GFS2_DIF_EXHASH &&
+		    (S_ISDIR(inode->i_di.di_mode) ||
+		     (gfs1 && inode->i_di.__pad1 == GFS_FILE_DIR)))
+			*gstruct_len = sbd.bsize;
+		else if (!inode->i_di.di_height && !block_is_systemfile() &&
+			 !S_ISDIR(inode->i_di.di_mode))
+			*gstruct_len = sizeof(struct gfs2_dinode);
+		else
+			*gstruct_len = sbd.bsize;
 		break;
 	case GFS2_METATYPE_IN:   /* 5 (indir inode blklst) */
 		*gstruct_len = sbd.bsize; /*sizeof(struct gfs_indirect);*/
@@ -155,24 +186,6 @@ static void warm_fuzzy_stuff(uint64_t wfsblock, int force, int save)
 	}
 }
 
-static int block_is_a_journal(void)
-{
-	int j;
-
-	for (j = 0; j < journals_found; j++)
-		if (block == journal_blocks[j])
-			return TRUE;
-	return FALSE;
-}
-
-static int block_is_systemfile(void)
-{
-	return block_is_jindex() || block_is_inum_file() ||
-		block_is_statfs_file() || block_is_quota_file() ||
-		block_is_rindex() || block_is_a_journal() ||
-		block_is_per_node() || block_is_in_per_node();
-}
-
 static int save_block(int fd, int out_fd, uint64_t blk)
 {
 	int blktype, blklen, outsz;