]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs.c
Update bcachefs sources to 1a510b00b6 bcachefs: Increase BTREE_TRANS_MEM_MAX
[bcachefs-tools-debian] / libbcachefs.c
index 1ae9b9ab1da9dc8904e0164dea4a66036d1ff76c..34246dc9106d5ffd83712f4b6571b4e91e042abe 100644 (file)
@@ -38,7 +38,7 @@ static u64 min_size(unsigned bucket_size)
 static void init_layout(struct bch_sb_layout *l,
                        unsigned block_size,
                        unsigned sb_size,
-                       u64 start, u64 end)
+                       u64 sb_start, u64 sb_end)
 {
        unsigned i;
 
@@ -51,14 +51,14 @@ static void init_layout(struct bch_sb_layout *l,
 
        /* Create two superblocks in the allowed range: */
        for (i = 0; i < l->nr_superblocks; i++) {
-               if (start != BCH_SB_SECTOR)
-                       start = round_up(start, block_size);
+               if (sb_start != BCH_SB_SECTOR)
+                       sb_start = round_up(sb_start, block_size);
 
-               l->sb_offset[i] = cpu_to_le64(start);
-               start += sb_size;
+               l->sb_offset[i] = cpu_to_le64(sb_start);
+               sb_start += sb_size;
        }
 
-       if (start >= end)
+       if (sb_start >= sb_end)
                die("insufficient space for superblocks");
 }
 
@@ -292,6 +292,21 @@ struct bch_sb *bch2_format(struct bch_opt_strs     fs_opt_strs,
                            opts.superblock_size,
                            i->sb_offset, i->sb_end);
 
+               /*
+                * Also create a backup superblock at the end of the disk:
+                *
+                * If we're not creating a superblock at the default offset, it
+                * means we're being run from the migrate tool and we could be
+                * overwriting existing data if we write to the end of the disk:
+                */
+               if (i->sb_offset == BCH_SB_SECTOR) {
+                       struct bch_sb_layout *l = &sb.sb->layout;
+                       u64 backup_sb = i->size - (1 << l->sb_max_size_bits);
+
+                       backup_sb = rounddown(backup_sb, i->bucket_size);
+                       l->sb_offset[l->nr_superblocks++] = cpu_to_le64(backup_sb);
+               }
+
                if (i->sb_offset == BCH_SB_SECTOR) {
                        /* Zero start of disk */
                        static const char zeroes[BCH_SB_SECTOR << 9];
@@ -669,6 +684,7 @@ void bch2_sb_print(struct bch_sb *sb, bool print_layout,
        struct bch_sb_field_members *mi;
        char user_uuid_str[40], internal_uuid_str[40];
        char features_str[500];
+       char compat_features_str[500];
        char fields_have_str[200];
        char label[BCH_SB_LABEL_SIZE + 1];
        char time_str[64];
@@ -722,6 +738,10 @@ void bch2_sb_print(struct bch_sb *sb, bool print_layout,
                           bch2_sb_features,
                           le64_to_cpu(sb->features[0]));
 
+       bch2_flags_to_text(&PBUF(compat_features_str),
+                          bch2_sb_compat,
+                          le64_to_cpu(sb->compat[0]));
+
        vstruct_for_each(sb, f)
                fields_have |= 1 << le32_to_cpu(f->type);
        bch2_flags_to_text(&PBUF(fields_have_str),
@@ -740,6 +760,7 @@ void bch2_sb_print(struct bch_sb *sb, bool print_layout,
               "Error action:                   %s\n"
               "Clean:                          %llu\n"
               "Features:                       %s\n"
+              "Compat features:                %s\n"
 
               "Metadata replicas:              %llu\n"
               "Data replicas:                  %llu\n"
@@ -778,6 +799,7 @@ void bch2_sb_print(struct bch_sb *sb, bool print_layout,
 
               BCH_SB_CLEAN(sb),
               features_str,
+              compat_features_str,
 
               BCH_SB_META_REPLICAS_WANT(sb),
               BCH_SB_DATA_REPLICAS_WANT(sb),
@@ -900,7 +922,7 @@ struct bchfs_handle bcache_fs_open(const char *path)
  * Given a path to a block device, open the filesystem it belongs to; also
  * return the device's idx:
  */
-struct bchfs_handle bchu_fs_open_by_dev(const char *path, unsigned *idx)
+struct bchfs_handle bchu_fs_open_by_dev(const char *path, int *idx)
 {
        char buf[1024], *uuid_str;
 
@@ -944,6 +966,17 @@ struct bchfs_handle bchu_fs_open_by_dev(const char *path, unsigned *idx)
        return bcache_fs_open(uuid_str);
 }
 
+int bchu_dev_path_to_idx(struct bchfs_handle fs, const char *dev_path)
+{
+       int idx;
+       struct bchfs_handle fs2 = bchu_fs_open_by_dev(dev_path, &idx);
+
+       if (memcmp(&fs.uuid, &fs2.uuid, sizeof(fs.uuid)))
+               idx = -1;
+       bcache_fs_close(fs2);
+       return idx;
+}
+
 int bchu_data(struct bchfs_handle fs, struct bch_ioctl_data cmd)
 {
        int progress_fd = xioctl(fs.ioctl_fd, BCH_IOCTL_DATA, &cmd);
@@ -988,6 +1021,16 @@ int bchu_data(struct bchfs_handle fs, struct bch_ioctl_data cmd)
 
 /* option parsing */
 
+void bch2_opt_strs_free(struct bch_opt_strs *opts)
+{
+       unsigned i;
+
+       for (i = 0; i < bch2_opts_nr; i++) {
+               free(opts->by_id[i]);
+               opts->by_id[i] = NULL;
+       }
+}
+
 struct bch_opt_strs bch2_cmdline_opts_get(int *argc, char *argv[],
                                          unsigned opt_types)
 {
@@ -1020,9 +1063,8 @@ struct bch_opt_strs bch2_cmdline_opts_get(int *argc, char *argv[],
                optid = bch2_opt_lookup(optstr);
                if (optid < 0 ||
                    !(bch2_opt_table[optid].mode & opt_types)) {
-                       free(optstr);
                        i++;
-                       continue;
+                       goto next;
                }
 
                if (!valstr &&
@@ -1034,13 +1076,15 @@ struct bch_opt_strs bch2_cmdline_opts_get(int *argc, char *argv[],
                if (!valstr)
                        valstr = "1";
 
-               opts.by_id[optid] = valstr;
+               opts.by_id[optid] = strdup(valstr);
 
                *argc -= nr_args;
                memmove(&argv[i],
                        &argv[i + nr_args],
                        sizeof(char *) * (*argc - i));
                argv[*argc] = NULL;
+next:
+               free(optstr);
        }
 
        return opts;
@@ -1071,22 +1115,17 @@ struct bch_opts bch2_parse_opts(struct bch_opt_strs strs)
        return opts;
 }
 
+#define newline(c)             \
+       do {                    \
+               printf("\n");   \
+               c = 0;          \
+       } while(0)
 void bch2_opts_usage(unsigned opt_types)
 {
        const struct bch_option *opt;
        unsigned i, c = 0, helpcol = 30;
 
-       void tabalign() {
-               while (c < helpcol) {
-                       putchar(' ');
-                       c++;
-               }
-       }
 
-       void newline() {
-               printf("\n");
-               c = 0;
-       }
 
        for (opt = bch2_opt_table;
             opt < bch2_opt_table + bch2_opts_nr;
@@ -1117,21 +1156,24 @@ void bch2_opts_usage(unsigned opt_types)
                        const char *l = opt->help;
 
                        if (c >= helpcol)
-                               newline();
+                               newline(c);
 
                        while (1) {
                                const char *n = strchrnul(l, '\n');
 
-                               tabalign();
+                               while (c < helpcol) {
+                                       putchar(' ');
+                                       c++;
+                               }
                                printf("%.*s", (int) (n - l), l);
-                               newline();
+                               newline(c);
 
                                if (!*n)
                                        break;
                                l = n + 1;
                        }
                } else {
-                       newline();
+                       newline(c);
                }
        }
 }