Blame SOURCES/bz1482542-gfs2_edit_savemeta_Fix_up_saving_of_dinodes_symlinks.patch

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