浏览代码

Btrfs: update the checks for mixed block groups with big metadata blocks

Dave Sterba had put in patches to look for mixed data/metadata groups
with metadata bigger than 4KB.  But these ended up in the wrong place
and it wasn't testing the feature flag correctly.

This updates the tests to make sure our sizes are matching

Signed-off-by: Chris Mason <chris.mason@oracle.com>
Chris Mason 13 年之前
父节点
当前提交
bc3f116fec
共有 1 个文件被更改,包括 17 次插入12 次删除
  1. 17 12
      fs/btrfs/disk-io.c

+ 17 - 12
fs/btrfs/disk-io.c

@@ -2120,6 +2120,23 @@ int open_ctree(struct super_block *sb,
 		features |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA;
 		features |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA;
 	}
 	}
 
 
+	nodesize = btrfs_super_nodesize(disk_super);
+	leafsize = btrfs_super_leafsize(disk_super);
+	sectorsize = btrfs_super_sectorsize(disk_super);
+	stripesize = btrfs_super_stripesize(disk_super);
+
+	/*
+	 * mixed block groups end up with duplicate but slightly offset
+	 * extent buffers for the same range.  It leads to corruptions
+	 */
+	if ((features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) &&
+	    (sectorsize != leafsize)) {
+		printk(KERN_WARNING "btrfs: unequal leaf/node/sector sizes "
+				"are not allowed for mixed block groups on %s\n",
+				sb->s_id);
+		goto fail_alloc;
+	}
+
 	btrfs_set_super_incompat_flags(disk_super, features);
 	btrfs_set_super_incompat_flags(disk_super, features);
 
 
 	features = btrfs_super_compat_ro_flags(disk_super) &
 	features = btrfs_super_compat_ro_flags(disk_super) &
@@ -2223,10 +2240,6 @@ int open_ctree(struct super_block *sb,
 	fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages,
 	fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages,
 				    4 * 1024 * 1024 / PAGE_CACHE_SIZE);
 				    4 * 1024 * 1024 / PAGE_CACHE_SIZE);
 
 
-	nodesize = btrfs_super_nodesize(disk_super);
-	leafsize = btrfs_super_leafsize(disk_super);
-	sectorsize = btrfs_super_sectorsize(disk_super);
-	stripesize = btrfs_super_stripesize(disk_super);
 	tree_root->nodesize = nodesize;
 	tree_root->nodesize = nodesize;
 	tree_root->leafsize = leafsize;
 	tree_root->leafsize = leafsize;
 	tree_root->sectorsize = sectorsize;
 	tree_root->sectorsize = sectorsize;
@@ -2247,14 +2260,6 @@ int open_ctree(struct super_block *sb,
 		goto fail_sb_buffer;
 		goto fail_sb_buffer;
 	}
 	}
 
 
-	if ((features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) &&
-			(leafsize != nodesize || sectorsize != nodesize)) {
-		printk(KERN_WARNING "btrfs: unequal leaf/node/sector sizes "
-				"are not allowed for mixed block groups on %s\n",
-				sb->s_id);
-		goto fail_sb_buffer;
-	}
-
 	mutex_lock(&fs_info->chunk_mutex);
 	mutex_lock(&fs_info->chunk_mutex);
 	ret = btrfs_read_sys_array(tree_root);
 	ret = btrfs_read_sys_array(tree_root);
 	mutex_unlock(&fs_info->chunk_mutex);
 	mutex_unlock(&fs_info->chunk_mutex);