Blame SOURCES/bz1482542-gfs2_edit_savemeta_Fix_up_saving_of_dinodes_symlinks.patch

ffc768
commit 52fce21ef94182fbe99b4e4344bdab42c6c95868
ffc768
Author: Andrew Price <anprice@redhat.com>
ffc768
Date:   Thu Aug 17 17:45:31 2017 +0100
ffc768
ffc768
    gfs2_edit savemeta: Fix up saving of dinodes/symlinks
ffc768
    
ffc768
    Factor out the code that decides whether to save the dinode contents,
ffc768
    improve its error reporting (and don't exit) and make sure contents of
ffc768
    symlink dinodes are saved.
ffc768
    
ffc768
    Resolves: rhbz#1482542
ffc768
    
ffc768
    Signed-off-by: Andrew Price <anprice@redhat.com>
ffc768
ffc768
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
ffc768
index dee405bc..04f67fc7 100644
ffc768
--- a/gfs2/edit/savemeta.c
ffc768
+++ b/gfs2/edit/savemeta.c
ffc768
@@ -190,6 +190,38 @@ static const char *anthropomorphize(unsigned long long inhuman_value)
ffc768
 	return out_val;
ffc768
 }
ffc768
 
ffc768
+static int di_save_len(struct gfs2_buffer_head *bh, uint64_t owner)
ffc768
+{
ffc768
+	struct gfs2_inode *inode;
ffc768
+	struct gfs2_dinode *dn;
ffc768
+	int len;
ffc768
+
ffc768
+	if (sbd.gfs1)
ffc768
+		inode = lgfs2_gfs_inode_get(&sbd, bh);
ffc768
+	else
ffc768
+		inode = lgfs2_inode_get(&sbd, bh);
ffc768
+
ffc768
+	if (inode == NULL) {
ffc768
+		fprintf(stderr, "Error reading inode at %"PRIu64": %s\n",
ffc768
+		        bh->b_blocknr, strerror(errno));
ffc768
+		return 0; /* Skip the block */
ffc768
+	}
ffc768
+	dn = &inode->i_di;
ffc768
+	len = sizeof(struct gfs2_dinode);
ffc768
+
ffc768
+	/* Do not save (user) data from the inode block unless they are
ffc768
+	   indirect pointers, dirents, symlinks or fs internal data */
ffc768
+	if (dn->di_height != 0 ||
ffc768
+	    S_ISDIR(dn->di_mode) ||
ffc768
+	    S_ISLNK(dn->di_mode) ||
ffc768
+	    (sbd.gfs1 && dn->__pad1 == GFS_FILE_DIR) ||
ffc768
+	    block_is_systemfile(owner))
ffc768
+		len = sbd.bsize;
ffc768
+
ffc768
+	inode_put(&inode;;
ffc768
+	return len;
ffc768
+}
ffc768
+
ffc768
 /*
ffc768
  * get_gfs_struct_info - get block type and structure length
ffc768
  *
ffc768
@@ -205,7 +237,6 @@ static int get_gfs_struct_info(struct gfs2_buffer_head *lbh, uint64_t owner,
ffc768
                                int *block_type, int *gstruct_len)
ffc768
 {
ffc768
 	struct gfs2_meta_header mh;
ffc768
-	struct gfs2_inode *inode;
ffc768
 
ffc768
 	if (block_type != NULL)
ffc768
 		*block_type = 0;
ffc768
@@ -229,24 +260,7 @@ static int get_gfs_struct_info(struct gfs2_buffer_head *lbh, uint64_t owner,
ffc768
 		*gstruct_len = sbd.bsize;
ffc768
 		break;
ffc768
 	case GFS2_METATYPE_DI:   /* 4 (disk inode) */
ffc768
-		if (sbd.gfs1) {
ffc768
-			inode = lgfs2_gfs_inode_get(&sbd, lbh);
ffc768
-		} else {
ffc768
-			inode = lgfs2_inode_get(&sbd, lbh);
ffc768
-		}
ffc768
-		if (inode == NULL) {
ffc768
-			perror("Error reading inode");
ffc768
-			exit(-1);
ffc768
-		}
ffc768
-		if (S_ISDIR(inode->i_di.di_mode) ||
ffc768
-		     (sbd.gfs1 && inode->i_di.__pad1 == GFS_FILE_DIR))
ffc768
-			*gstruct_len = sbd.bsize;
ffc768
-		else if (!inode->i_di.di_height && !block_is_systemfile(owner) &&
ffc768
-			 !S_ISDIR(inode->i_di.di_mode))
ffc768
-			*gstruct_len = sizeof(struct gfs2_dinode);
ffc768
-		else
ffc768
-			*gstruct_len = sbd.bsize;
ffc768
-		inode_put(&inode;;
ffc768
+		*gstruct_len = di_save_len(lbh, owner);
ffc768
 		break;
ffc768
 	case GFS2_METATYPE_IN:   /* 5 (indir inode blklst) */
ffc768
 		*gstruct_len = sbd.bsize; /*sizeof(struct gfs_indirect);*/