btrfs-progs: utils: Check nodesize against features
authorQu Wenruo <quwenruo@cn.fujitsu.com>
Fri, 25 Sep 2015 16:15:44 +0000 (18:15 +0200)
committerDavid Sterba <dsterba@suse.com>
Fri, 2 Oct 2015 15:54:04 +0000 (17:54 +0200)
Check nodesize against features, not only sectorsize.
In fact, one of the btrfs-convert and mkfs differs in the nodesize
check.

This patch also provides the basis for later btrfs-convert fix.

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
btrfs-convert.c
mkfs.c
utils.c
utils.h

index e7f3c9e1002eb9ec458c4f0afbde33c15becd7fa..802930c920b23c12bb5767662efe38b508b5dc0c 100644 (file)
@@ -2319,7 +2319,7 @@ static int do_convert(const char *devname, int datacsum, int packing, int noxatt
                fprintf(stderr, "filetype feature is missing\n");
                goto fail;
        }
-       if (btrfs_check_nodesize(nodesize, blocksize))
+       if (btrfs_check_nodesize(nodesize, blocksize, features))
                goto fail;
        blocks_per_node = nodesize / blocksize;
        ret = -blocks_per_node;
diff --git a/mkfs.c b/mkfs.c
index 14e7eb40baf73a55c44b40a42f99df6fc54cbacf..b8879fcf49cc5b02d0cc3b0e8b1b777c0612e58d 100644 (file)
--- a/mkfs.c
+++ b/mkfs.c
@@ -1466,9 +1466,8 @@ int main(int ac, char **av)
                                print_usage(c != GETOPT_VAL_HELP);
                }
        }
+
        sectorsize = max(sectorsize, (u32)sysconf(_SC_PAGESIZE));
-       if (btrfs_check_nodesize(nodesize, sectorsize))
-               exit(1);
        saved_optind = optind;
        dev_cnt = ac - optind;
        if (dev_cnt == 0)
@@ -1542,17 +1541,12 @@ int main(int ac, char **av)
                        }
                }
 
-               if (!nodesize_forced) {
+               if (!nodesize_forced)
                        nodesize = best_nodesize;
-                       if (btrfs_check_nodesize(nodesize, sectorsize))
-                               exit(1);
-               }
-               if (nodesize != sectorsize) {
-                       fprintf(stderr, "Error: mixed metadata/data block groups "
-                               "require metadata blocksizes equal to the sectorsize\n");
-                       exit(1);
-               }
        }
+       if (btrfs_check_nodesize(nodesize, sectorsize,
+                                features))
+               exit(1);
 
        /* Check device/block_count after the nodesize is determined */
        if (block_count && block_count < btrfs_min_dev_size(nodesize)) {
diff --git a/utils.c b/utils.c
index bb4091ece5863ea230089152013bc1563d8fa2eb..0f8f91dd452533b1e83a4e69a87678eaff933c19 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -2928,7 +2928,7 @@ int btrfs_tree_search2_ioctl_supported(int fd)
        return v2_supported;
 }
 
-int btrfs_check_nodesize(u32 nodesize, u32 sectorsize)
+int btrfs_check_nodesize(u32 nodesize, u32 sectorsize, u64 features)
 {
        if (nodesize < sectorsize) {
                fprintf(stderr,
@@ -2945,6 +2945,12 @@ int btrfs_check_nodesize(u32 nodesize, u32 sectorsize)
                        "ERROR: Illegal nodesize %u (not aligned to %u)\n",
                        nodesize, sectorsize);
                return -1;
+       } else if (features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS &&
+                  nodesize != sectorsize) {
+               fprintf(stderr,
+                       "ERROR: Illegal nodesize %u (not equal to %u for mixed block group)\n",
+                       nodesize, sectorsize);
+               return -1;
        }
        return 0;
 }
diff --git a/utils.h b/utils.h
index 93e1de6b8061c2b8361466ec52978f035ac26037..192f3d1cb58ff905e739e8992300784538d3f793 100644 (file)
--- a/utils.h
+++ b/utils.h
@@ -242,7 +242,7 @@ static inline u64 div_factor(u64 num, int factor)
 }
 
 int btrfs_tree_search2_ioctl_supported(int fd);
-int btrfs_check_nodesize(u32 nodesize, u32 sectorsize);
+int btrfs_check_nodesize(u32 nodesize, u32 sectorsize, u64 features);
 
 const char *get_argv0_buf(void);