]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - cmd_migrate.c
Update bcachefs sources to f638850417 bcachefs: bch2_trans_log_msg()
[bcachefs-tools-debian] / cmd_migrate.c
index 4b6ceaa7b4e909275287b2110a7f64c7c057facc..08ec7de28004df6eca81c97b7fd933c9b502a434 100644 (file)
@@ -30,7 +30,7 @@
 #include "libbcachefs/btree_update.h"
 #include "libbcachefs/buckets.h"
 #include "libbcachefs/dirent.h"
-#include "libbcachefs/fs.h"
+#include "libbcachefs/fs-common.h"
 #include "libbcachefs/inode.h"
 #include "libbcachefs/io.h"
 #include "libbcachefs/replicas.h"
@@ -38,6 +38,9 @@
 #include "libbcachefs/super.h"
 #include "libbcachefs/xattr.h"
 
+/* XXX cut and pasted from fsck.c */
+#define QSTR(n) { { { .len = strlen(n) } }, .name = n }
+
 static char *dev_t_to_path(dev_t dev)
 {
        char link[PATH_MAX], *p;
@@ -119,43 +122,28 @@ static void update_inode(struct bch_fs *c,
        struct bkey_inode_buf packed;
        int ret;
 
-       bch2_inode_pack(&packed, inode);
-       ret = bch2_btree_insert(c, BTREE_ID_INODES, &packed.inode.k_i,
+       bch2_inode_pack(c, &packed, inode);
+       packed.inode.k.p.snapshot = U32_MAX;
+       ret = bch2_btree_insert(c, BTREE_ID_inodes, &packed.inode.k_i,
                                NULL, NULL, 0);
        if (ret)
-               die("error creating file: %s", strerror(-ret));
-}
-
-static void create_dirent(struct bch_fs *c,
-                         struct bch_inode_unpacked *parent,
-                         const char *name, u64 inum, mode_t mode)
-{
-       struct bch_hash_info parent_hash_info = bch2_hash_info_init(c, parent);
-       struct qstr qname = { { { .len = strlen(name), } }, .name = name };
-
-       int ret = bch2_dirent_create(c, parent->bi_inum, &parent_hash_info,
-                                    mode_to_type(mode), &qname,
-                                    inum, NULL, BCH_HASH_SET_MUST_CREATE);
-       if (ret)
-               die("error creating file: %s", strerror(-ret));
-
-       if (S_ISDIR(mode))
-               parent->bi_nlink++;
+               die("error updating inode: %s", strerror(-ret));
 }
 
 static void create_link(struct bch_fs *c,
                        struct bch_inode_unpacked *parent,
                        const char *name, u64 inum, mode_t mode)
 {
+       struct qstr qstr = QSTR(name);
+       struct bch_inode_unpacked parent_u;
        struct bch_inode_unpacked inode;
-       int ret = bch2_inode_find_by_inum(c, inum, &inode);
-       if (ret)
-               die("error looking up hardlink: %s", strerror(-ret));
-
-       inode.bi_nlink++;
-       update_inode(c, &inode);
 
-       create_dirent(c, parent, name, inum, mode);
+       int ret = bch2_trans_do(c, NULL, NULL, 0,
+               bch2_link_trans(&trans,
+                               (subvol_inum) { 1, parent->bi_inum }, &parent_u,
+                               (subvol_inum) { 1, inum }, &inode, &qstr));
+       if (ret)
+               die("error creating hardlink: %s", strerror(-ret));
 }
 
 static struct bch_inode_unpacked create_file(struct bch_fs *c,
@@ -164,17 +152,19 @@ static struct bch_inode_unpacked create_file(struct bch_fs *c,
                                             uid_t uid, gid_t gid,
                                             mode_t mode, dev_t rdev)
 {
+       struct qstr qstr = QSTR(name);
        struct bch_inode_unpacked new_inode;
-       int ret;
 
-       bch2_inode_init(c, &new_inode, uid, gid, mode, rdev, parent);
+       bch2_inode_init_early(c, &new_inode);
 
-       ret = bch2_inode_create(c, &new_inode, BLOCKDEV_INODE_MAX, 0,
-                               &c->unused_inode_hint);
+       int ret = bch2_trans_do(c, NULL, NULL, 0,
+               bch2_create_trans(&trans,
+                                 (subvol_inum) { 1, parent->bi_inum }, parent,
+                                 &new_inode, &qstr,
+                                 uid, gid, mode, rdev, NULL, NULL,
+                                 (subvol_inum) {}, 0));
        if (ret)
-               die("error creating file: %s", strerror(-ret));
-
-       create_dirent(c, parent, name, new_inode.bi_inum, mode);
+               die("error creating %s: %s", name, strerror(-ret));
 
        return new_inode;
 }
@@ -239,46 +229,49 @@ static void copy_xattrs(struct bch_fs *c, struct bch_inode_unpacked *dst,
 
                const struct xattr_handler *h = xattr_resolve_name(&attr);
 
-               int ret = bch2_trans_do(c, NULL, BTREE_INSERT_ATOMIC,
-                               bch2_xattr_set(&trans, dst->bi_inum, &hash_info, attr,
+               int ret = bch2_trans_do(c, NULL, NULL, 0,
+                               bch2_xattr_set(&trans,
+                                              (subvol_inum) { 1, dst->bi_inum },
+                                              &hash_info, attr,
                                               val, val_size, h->flags, 0));
                if (ret < 0)
                        die("error creating xattr: %s", strerror(-ret));
        }
 }
 
-static char buf[1 << 20] __aligned(PAGE_SIZE);
+#define WRITE_DATA_BUF (1 << 20)
+
+static char buf[WRITE_DATA_BUF] __aligned(PAGE_SIZE);
 
 static void write_data(struct bch_fs *c,
                       struct bch_inode_unpacked *dst_inode,
                       u64 dst_offset, void *buf, size_t len)
 {
-       struct {
-               struct bch_write_op op;
-               struct bio_vec bv[sizeof(buf) / PAGE_SIZE];
-       } o;
+       struct bch_write_op op;
+       struct bio_vec bv[WRITE_DATA_BUF / PAGE_SIZE];
        struct closure cl;
 
        BUG_ON(dst_offset       & (block_bytes(c) - 1));
        BUG_ON(len              & (block_bytes(c) - 1));
+       BUG_ON(len > WRITE_DATA_BUF);
 
        closure_init_stack(&cl);
 
-       bio_init(&o.op.wbio.bio, o.bv, ARRAY_SIZE(o.bv));
-       o.op.wbio.bio.bi_iter.bi_size = len;
-       bch2_bio_map(&o.op.wbio.bio, buf);
+       bio_init(&op.wbio.bio, bv, ARRAY_SIZE(bv));
+       bch2_bio_map(&op.wbio.bio, buf, len);
 
-       bch2_write_op_init(&o.op, c, bch2_opts_to_inode_opts(c->opts));
-       o.op.write_point        = writepoint_hashed(0);
-       o.op.nr_replicas        = 1;
-       o.op.pos                = POS(dst_inode->bi_inum, dst_offset >> 9);
+       bch2_write_op_init(&op, c, bch2_opts_to_inode_opts(c->opts));
+       op.write_point  = writepoint_hashed(0);
+       op.nr_replicas  = 1;
+       op.subvol       = 1;
+       op.pos          = SPOS(dst_inode->bi_inum, dst_offset >> 9, U32_MAX);
 
-       int ret = bch2_disk_reservation_get(c, &o.op.res, len >> 9,
+       int ret = bch2_disk_reservation_get(c, &op.res, len >> 9,
                                            c->opts.data_replicas, 0);
        if (ret)
                die("error reserving space in new filesystem: %s", strerror(-ret));
 
-       closure_call(&o.op.cl, bch2_write, NULL, &cl);
+       closure_call(&op.cl, bch2_write, NULL, &cl);
        closure_sync(&cl);
 
        dst_inode->bi_sectors += len >> 9;
@@ -317,9 +310,8 @@ static void link_data(struct bch_fs *c, struct bch_inode_unpacked *dst,
 
        while (length) {
                struct bkey_i_extent *e;
-               BKEY_PADDED(k) k;
+               __BKEY_PADDED(k, BKEY_EXTENT_VAL_U64s_MAX) k;
                u64 b = sector_to_bucket(ca, physical);
-               struct bucket_mark m;
                struct disk_reservation res;
                unsigned sectors;
                int ret;
@@ -331,24 +323,21 @@ static void link_data(struct bch_fs *c, struct bch_inode_unpacked *dst,
                e = bkey_extent_init(&k.k);
                e->k.p.inode    = dst->bi_inum;
                e->k.p.offset   = logical + sectors;
+               e->k.p.snapshot = U32_MAX;
                e->k.size       = sectors;
                bch2_bkey_append_ptr(&e->k_i, (struct bch_extent_ptr) {
                                        .offset = physical,
                                        .dev = 0,
-                                       .gen = bucket(ca, b)->mark.gen,
+                                       .gen = *bucket_gen(ca, b),
                                  });
 
-               bucket_cmpxchg(bucket(ca, b), m, m.dirty = true);
-
                ret = bch2_disk_reservation_get(c, &res, sectors, 1,
                                                BCH_DISK_RESERVATION_NOFAIL);
                if (ret)
                        die("error reserving space in new filesystem: %s",
                            strerror(-ret));
 
-               bch2_mark_bkey_replicas(c, extent_i_to_s_c(e).s_c);
-
-               ret = bch2_btree_insert(c, BTREE_ID_EXTENTS, &e->k_i,
+               ret = bch2_btree_insert(c, BTREE_ID_extents, &e->k_i,
                                        &res, NULL, 0);
                if (ret)
                        die("btree insert error %s", strerror(-ret));
@@ -447,6 +436,7 @@ static void copy_dir(struct copy_fs_state *s,
 
                if (!strcmp(d->d_name, ".") ||
                    !strcmp(d->d_name, "..") ||
+                   !strcmp(d->d_name, "lost+found") ||
                    stat.st_ino == s->bcachefs_inum)
                        continue;
 
@@ -540,7 +530,7 @@ static ranges reserve_new_fs_space(const char *file_path, unsigned block_size,
 
        struct fiemap_iter iter;
        struct fiemap_extent e;
-       ranges extents = { NULL };
+       ranges extents = { 0 };
 
        fiemap_for_each(fd, iter, e) {
                if (e.fe_flags & (FIEMAP_EXTENT_UNKNOWN|
@@ -588,7 +578,8 @@ static void copy_fs(struct bch_fs *c, int src_fd, const char *src_path,
        syncfs(src_fd);
 
        struct bch_inode_unpacked root_inode;
-       int ret = bch2_inode_find_by_inum(c, BCACHEFS_ROOT_INO, &root_inode);
+       int ret = bch2_inode_find_by_inum(c, (subvol_inum) { 1, BCACHEFS_ROOT_INO },
+                                         &root_inode);
        if (ret)
                die("error looking up root directory: %s", strerror(-ret));
 
@@ -612,26 +603,26 @@ static void copy_fs(struct bch_fs *c, int src_fd, const char *src_path,
 
        update_inode(c, &root_inode);
 
-       darray_free(s.extents);
+       darray_exit(s.extents);
        genradix_free(&s.hardlinks);
-
-       bool wrote;
-       bch2_alloc_write(c, false, &wrote);
 }
 
-static void find_superblock_space(ranges extents, struct dev_opts *dev)
+static void find_superblock_space(ranges extents,
+                                 struct format_opts opts,
+                                 struct dev_opts *dev)
 {
        struct range *i;
 
-       darray_foreach(i, extents) {
+       darray_for_each(extents, i) {
                u64 start = round_up(max(256ULL << 10, i->start),
                                     dev->bucket_size << 9);
                u64 end = round_down(i->end,
                                     dev->bucket_size << 9);
 
-               if (start + (128 << 10) <= end) {
+               /* Need space for two superblocks: */
+               if (start + (opts.superblock_size << 9) * 2 <= end) {
                        dev->sb_offset  = start >> 9;
-                       dev->sb_end     = dev->sb_offset + 256;
+                       dev->sb_end     = dev->sb_offset + opts.superblock_size * 2;
                        return;
                }
        }
@@ -689,11 +680,11 @@ static int migrate_fs(const char          *fs_path,
 
        u64 bcachefs_inum;
        ranges extents = reserve_new_fs_space(file_path,
-                               fs_opts.block_size << 9,
+                               fs_opts.block_size >> 9,
                                get_size(dev.path, dev.fd) / 5,
                                &bcachefs_inum, stat.st_dev, force);
 
-       find_superblock_space(extents, &dev);
+       find_superblock_space(extents, format_opts, &dev);
 
        struct bch_sb *sb = bch2_format(fs_opt_strs,
                                        fs_opts,format_opts, &dev, 1);
@@ -711,6 +702,7 @@ static int migrate_fs(const char            *fs_path,
        opt_set(opts, sb,       sb_offset);
        opt_set(opts, nostart,  true);
        opt_set(opts, noexcl,   true);
+       opt_set(opts, buckets_nouse, true);
 
        c = bch2_fs_open(path, 1, opts);
        if (IS_ERR(c))
@@ -718,9 +710,9 @@ static int migrate_fs(const char            *fs_path,
 
        mark_unreserved_space(c, extents);
 
-       const char *err = bch2_fs_start(c);
-       if (err)
-               die("Error starting new filesystem: %s", err);
+       int ret = bch2_fs_start(c);
+       if (ret)
+               die("Error starting new filesystem: %s", strerror(-ret));
 
        copy_fs(c, fs_fd, fs_path, bcachefs_inum, &extents);
 
@@ -785,15 +777,17 @@ int cmd_migrate(int argc, char *argv[])
                }
 
        if (!fs_path)
-               die("Please specify a filesytem to migrate");
+               die("Please specify a filesystem to migrate");
 
        if (format_opts.encrypted && !no_passphrase)
                format_opts.passphrase = read_passphrase_twice("Enter passphrase: ");
 
-       return migrate_fs(fs_path,
-                         fs_opt_strs,
-                         fs_opts,
-                         format_opts, force);
+       int ret = migrate_fs(fs_path,
+                            fs_opt_strs,
+                            fs_opts,
+                            format_opts, force);
+       bch2_opt_strs_free(&fs_opt_strs);
+       return ret;
 }
 
 static void migrate_superblock_usage(void)