]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - cmd_migrate.c
cmd_show_super: --field-only
[bcachefs-tools-debian] / cmd_migrate.c
index 5a35c5a178aba004ab4a01c40953ea6113cbecee..07fc145290034ae9eed9706d86caada62c116202 100644 (file)
@@ -33,7 +33,7 @@
 #include "libbcachefs/errcode.h"
 #include "libbcachefs/fs-common.h"
 #include "libbcachefs/inode.h"
-#include "libbcachefs/io.h"
+#include "libbcachefs/io_write.h"
 #include "libbcachefs/replicas.h"
 #include "libbcachefs/str_hash.h"
 #include "libbcachefs/super.h"
@@ -126,7 +126,7 @@ static void update_inode(struct bch_fs *c,
        bch2_inode_pack(&packed, inode);
        packed.inode.k.p.snapshot = U32_MAX;
        ret = bch2_btree_insert(c, BTREE_ID_inodes, &packed.inode.k_i,
-                               NULL, NULL, 0);
+                               NULL, 0);
        if (ret)
                die("error updating inode: %s", bch2_err_str(ret));
 }
@@ -140,7 +140,7 @@ static void create_link(struct bch_fs *c,
        struct bch_inode_unpacked inode;
 
        int ret = bch2_trans_do(c, NULL, NULL, 0,
-               bch2_link_trans(&trans,
+               bch2_link_trans(trans,
                                (subvol_inum) { 1, parent->bi_inum }, &parent_u,
                                (subvol_inum) { 1, inum }, &inode, &qstr));
        if (ret)
@@ -159,7 +159,7 @@ static struct bch_inode_unpacked create_file(struct bch_fs *c,
        bch2_inode_init_early(c, &new_inode);
 
        int ret = bch2_trans_do(c, NULL, NULL, 0,
-               bch2_create_trans(&trans,
+               bch2_create_trans(trans,
                                  (subvol_inum) { 1, parent->bi_inum }, parent,
                                  &new_inode, &qstr,
                                  uid, gid, mode, rdev, NULL, NULL,
@@ -229,11 +229,12 @@ static void copy_xattrs(struct bch_fs *c, struct bch_inode_unpacked *dst,
                        die("error getting xattr val: %m");
 
                const struct xattr_handler *h = xattr_resolve_name(&attr);
+               struct bch_inode_unpacked inode_u;
 
                int ret = bch2_trans_do(c, NULL, NULL, 0,
-                               bch2_xattr_set(&trans,
+                               bch2_xattr_set(trans,
                                               (subvol_inum) { 1, dst->bi_inum },
-                                              &hash_info, attr,
+                                              &inode_u, &hash_info, attr,
                                               val, val_size, h->flags, 0));
                if (ret < 0)
                        die("error creating xattr: %s", bch2_err_str(ret));
@@ -250,14 +251,11 @@ static void write_data(struct bch_fs *c,
 {
        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(&op.wbio.bio, NULL, bv, ARRAY_SIZE(bv), 0);
        bch2_bio_map(&op.wbio.bio, buf, len);
 
@@ -273,9 +271,13 @@ static void write_data(struct bch_fs *c,
        if (ret)
                die("error reserving space in new filesystem: %s", bch2_err_str(ret));
 
-       closure_call(&op.cl, bch2_write, NULL, &cl);
+       closure_call(&op.cl, bch2_write, NULL, NULL);
 
+       BUG_ON(!(op.flags & BCH_WRITE_DONE));
        dst_inode->bi_sectors += len >> 9;
+
+       if (op.error)
+               die("write error: %s", bch2_err_str(op.error));
 }
 
 static void copy_data(struct bch_fs *c,
@@ -311,7 +313,7 @@ static void link_data(struct bch_fs *c, struct bch_inode_unpacked *dst,
 
        while (length) {
                struct bkey_i_extent *e;
-               __BKEY_PADDED(k, BKEY_EXTENT_VAL_U64s_MAX) k;
+               BKEY_PADDED_ONSTACK(k, BKEY_EXTENT_VAL_U64s_MAX) k;
                u64 b = sector_to_bucket(ca, physical);
                struct disk_reservation res;
                unsigned sectors;
@@ -338,8 +340,7 @@ static void link_data(struct bch_fs *c, struct bch_inode_unpacked *dst,
                        die("error reserving space in new filesystem: %s",
                            bch2_err_str(ret));
 
-               ret = bch2_btree_insert(c, BTREE_ID_extents, &e->k_i,
-                                       &res, NULL, 0);
+               ret = bch2_btree_insert(c, BTREE_ID_extents, &e->k_i, &res, 0);
                if (ret)
                        die("btree insert error %s", bch2_err_str(ret));
 
@@ -374,8 +375,13 @@ static void copy_file(struct bch_fs *c, struct bch_inode_unpacked *dst,
                        fsync(src_fd);
                        break;
                }
+       fiemap_iter_exit(&iter);
 
        fiemap_for_each(src_fd, iter, e) {
+               u64 src_max = roundup(src_size, block_bytes(c));
+
+               e.fe_length = min(e.fe_length, src_max - e.fe_logical);
+
                if ((e.fe_logical       & (block_bytes(c) - 1)) ||
                    (e.fe_length        & (block_bytes(c) - 1)))
                        die("Unaligned extent in %s - can't handle", src_path);
@@ -407,6 +413,7 @@ static void copy_file(struct bch_fs *c, struct bch_inode_unpacked *dst,
                range_add(extents, e.fe_physical, e.fe_length);
                link_data(c, dst, e.fe_logical, e.fe_physical, e.fe_length);
        }
+       fiemap_iter_exit(&iter);
 }
 
 struct copy_fs_state {
@@ -504,6 +511,7 @@ next:
 
        if (errno)
                die("readdir error: %m");
+       closedir(dir);
 }
 
 static ranges reserve_new_fs_space(const char *file_path, unsigned block_size,
@@ -546,6 +554,7 @@ static ranges reserve_new_fs_space(const char *file_path, unsigned block_size,
 
                range_add(&extents, e.fe_physical, e.fe_length);
        }
+       fiemap_iter_exit(&iter);
        close(fd);
 
        ranges_sort_merge(&extents);
@@ -612,8 +621,6 @@ static void find_superblock_space(ranges extents,
                                  struct format_opts opts,
                                  struct dev_opts *dev)
 {
-       struct range *i;
-
        darray_for_each(extents, i) {
                u64 start = round_up(max(256ULL << 10, i->start),
                                     dev->bucket_size << 9);
@@ -669,20 +676,24 @@ static int migrate_fs(const char          *fs_path,
        struct dev_opts dev = dev_opts_default();
 
        dev.path = dev_t_to_path(stat.st_dev);
-       dev.fd = xopen(dev.path, O_RDWR);
+       dev.bdev = blkdev_get_by_path(dev.path, BLK_OPEN_READ|BLK_OPEN_WRITE, &dev, NULL);
 
-       opt_set(fs_opts, block_size, get_blocksize(dev.path, dev.fd));
+       opt_set(fs_opts, block_size, get_blocksize(dev.bdev->bd_buffered_fd));
 
        char *file_path = mprintf("%s/bcachefs", fs_path);
        printf("Creating new filesystem on %s in space reserved at %s\n",
               dev.path, file_path);
 
-       bch2_pick_bucket_size(fs_opts, &dev);
+       dev.size        = get_size(dev.bdev->bd_buffered_fd);
+       dev.bucket_size = bch2_pick_bucket_size(fs_opts, &dev);
+       dev.nbuckets    = dev.size / dev.bucket_size;
+
+       bch2_check_bucket_size(fs_opts, &dev);
 
        u64 bcachefs_inum;
        ranges extents = reserve_new_fs_space(file_path,
                                fs_opts.block_size >> 9,
-                               get_size(dev.path, dev.fd) / 5,
+                               get_size(dev.bdev->bd_buffered_fd) / 5,
                                &bcachefs_inum, stat.st_dev, force);
 
        find_superblock_space(extents, format_opts, &dev);