btrfs-progs: convert: allow to set filesystem features
authorDavid Sterba <dsterba@suse.cz>
Mon, 23 Mar 2015 18:31:31 +0000 (19:31 +0100)
committerDavid Sterba <dsterba@suse.cz>
Thu, 4 Jun 2015 17:14:54 +0000 (19:14 +0200)
Curretnly there are no features set for the converted filesystem and
it's not possible to request it like in mkfs.

Add new option -O|--features, use -O list-all to show all that are
supported for convert.

Note: from now on, convert without any -O option will use the same
defaults as mkfs. The original behaviour was rather confusing.

Convert is now more verbose about the parameters of the btrfs filesytem.

Signed-off-by: David Sterba <dsterba@suse.cz>
btrfs-convert.c
utils.h

index 9a9d619..409c0df 100644 (file)
@@ -2282,7 +2282,8 @@ err:
 }
 
 static int do_convert(const char *devname, int datacsum, int packing, int noxattr,
-               u32 nodesize, int copylabel, const char *fslabel, int progress)
+               u32 nodesize, int copylabel, const char *fslabel, int progress,
+               u64 features)
 {
        int i, ret, blocks_per_node;
        int fd = -1;
@@ -2294,6 +2295,7 @@ static int do_convert(const char *devname, int datacsum, int packing, int noxatt
        struct btrfs_root *root;
        struct btrfs_root *ext2_root;
        struct task_ctx ctx;
+       char features_buf[64];
 
        ret = open_ext2fs(devname, &ext2_fs);
        if (ret) {
@@ -2334,9 +2336,17 @@ static int do_convert(const char *devname, int datacsum, int packing, int noxatt
                fprintf(stderr, "unable to open %s\n", devname);
                goto fail;
        }
+       btrfs_parse_features_to_string(features_buf, features);
+       if (features == BTRFS_MKFS_DEFAULT_FEATURES)
+               strcat(features_buf, " (default)");
+
+       printf("create btrfs filesystem:\n");
+       printf("\tblocksize: %u\n", blocksize);
+       printf("\tnodesize:  %u\n", nodesize);
+       printf("\tfeatures:  %s\n", features_buf);
        ret = make_btrfs(fd, devname, ext2_fs->super->s_volume_name,
                         NULL, blocks, total_bytes, nodesize,
-                        blocksize, blocksize, 0);
+                        blocksize, blocksize, features);
        if (ret) {
                fprintf(stderr, "unable to create initial ctree: %s\n",
                        strerror(-ret));
@@ -2832,6 +2842,7 @@ static void print_usage(void)
        printf("\t-l|--label LABEL       set filesystem label\n");
        printf("\t-L|--copy-label        use label from converted filesystem\n");
        printf("\t-p|--progress          show converting progress (default)\n");
+       printf("\t-O|--features LIST     comma separated list of filesystem features\n");
        printf("\t--no-progress          show only overview, not the detailed progress\n");
 }
 
@@ -2849,6 +2860,7 @@ int main(int argc, char *argv[])
        int progress = 1;
        char *file;
        char *fslabel = NULL;
+       u64 features = BTRFS_MKFS_DEFAULT_FEATURES;
 
        while(1) {
                enum { GETOPT_VAL_NO_PROGRESS = 256 };
@@ -2859,13 +2871,14 @@ int main(int argc, char *argv[])
                        { "no-inline", no_argument, NULL, 'n' },
                        { "no-xattr", no_argument, NULL, 'i' },
                        { "rollback", no_argument, NULL, 'r' },
+                       { "features", required_argument, NULL, 'O' },
                        { "progress", no_argument, NULL, 'p' },
                        { "label", required_argument, NULL, 'l' },
                        { "copy-label", no_argument, NULL, 'L' },
                        { "nodesize", required_argument, NULL, 'N' },
                        { NULL, 0, NULL, 0 }
                };
-               int c = getopt_long(argc, argv, "dinN:rl:Lp", long_options, NULL);
+               int c = getopt_long(argc, argv, "dinN:rl:LpO:", long_options, NULL);
 
                if (c < 0)
                        break;
@@ -2901,6 +2914,37 @@ int main(int argc, char *argv[])
                        case 'p':
                                progress = 1;
                                break;
+                       case 'O': {
+                               char *orig = strdup(optarg);
+                               char *tmp = orig;
+
+                               tmp = btrfs_parse_fs_features(tmp, &features);
+                               if (tmp) {
+                                       fprintf(stderr,
+                                               "Unrecognized filesystem feature '%s'\n",
+                                                       tmp);
+                                       free(orig);
+                                       exit(1);
+                               }
+                               free(orig);
+                               if (features & BTRFS_FEATURE_LIST_ALL) {
+                                       btrfs_list_all_fs_features(
+                                               ~BTRFS_CONVERT_ALLOWED_FEATURES);
+                                       exit(0);
+                               }
+                               if (features & ~BTRFS_CONVERT_ALLOWED_FEATURES) {
+                                       char buf[64];
+
+                                       btrfs_parse_features_to_string(buf,
+                                               features & ~BTRFS_CONVERT_ALLOWED_FEATURES);
+                                       fprintf(stderr,
+                                               "ERROR: features not allowed for convert: %s\n",
+                                               buf);
+                                       exit(1);
+                               }
+
+                               break;
+                               }
                        case GETOPT_VAL_NO_PROGRESS:
                                progress = 0;
                                break;
@@ -2942,7 +2986,7 @@ int main(int argc, char *argv[])
                ret = do_rollback(file);
        } else {
                ret = do_convert(file, datacsum, packing, noxattr, nodesize,
-                               copylabel, fslabel, progress);
+                               copylabel, fslabel, progress, features);
        }
        if (ret)
                return 1;
diff --git a/utils.h b/utils.h
index 871cbd8..12923de 100644 (file)
--- a/utils.h
+++ b/utils.h
                (BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF           \
                | BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA)
 
+/*
+ * Avoid multi-device features (RAID56) and mixed block groups
+ */
+#define BTRFS_CONVERT_ALLOWED_FEATURES                         \
+       (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF                   \
+       | BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL                 \
+       | BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO                   \
+       | BTRFS_FEATURE_INCOMPAT_COMPRESS_LZOv2                 \
+       | BTRFS_FEATURE_INCOMPAT_BIG_METADATA                   \
+       | BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF                  \
+       | BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA                \
+       | BTRFS_FEATURE_INCOMPAT_NO_HOLES)
+
 #define BTRFS_FEATURE_LIST_ALL         (1ULL << 63)
 
 #define BTRFS_SCAN_MOUNTED     (1ULL << 0)