]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - c_src/cmd_migrate.c
Update upstream source from tag 'v1.6.3'
[bcachefs-tools-debian] / c_src / cmd_migrate.c
similarity index 96%
rename from cmd_migrate.c
rename to c_src/cmd_migrate.c
index cde1fce4397c725baafa3326d10d54799b65ed5f..1c7cc929be0d9d6b84a73e4efeece9e61fd74cb5 100644 (file)
@@ -251,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);
 
@@ -274,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,
@@ -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,15 +676,20 @@ 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.bdev = blkdev_get_by_path(dev.path, BLK_OPEN_READ|BLK_OPEN_WRITE, &dev, NULL);
+       dev.handle = bdev_open_by_path(dev.path, BLK_OPEN_READ|BLK_OPEN_WRITE, &dev, NULL);
+
+       int ret = PTR_ERR_OR_ZERO(dev.handle);
+       if (ret < 0)
+               die("Error opening device to format %s: %s", dev.path, strerror(-ret));
+       dev.bdev = dev.handle->bdev;
 
-       opt_set(fs_opts, block_size, get_blocksize(dev.bdev->bd_buffered_fd));
+       opt_set(fs_opts, block_size, get_blocksize(dev.bdev->bd_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);
 
-       dev.size        = get_size(dev.bdev->bd_buffered_fd);
+       dev.size        = get_size(dev.bdev->bd_fd);
        dev.bucket_size = bch2_pick_bucket_size(fs_opts, &dev);
        dev.nbuckets    = dev.size / dev.bucket_size;
 
@@ -686,13 +698,13 @@ static int migrate_fs(const char          *fs_path,
        u64 bcachefs_inum;
        ranges extents = reserve_new_fs_space(file_path,
                                fs_opts.block_size >> 9,
-                               get_size(dev.bdev->bd_buffered_fd) / 5,
+                               get_size(dev.bdev->bd_fd) / 5,
                                &bcachefs_inum, stat.st_dev, force);
 
        find_superblock_space(extents, format_opts, &dev);
 
        struct bch_sb *sb = bch2_format(fs_opt_strs,
-                                       fs_opts,format_opts, &dev, 1);
+                                       fs_opts, format_opts, &dev, 1);
        u64 sb_offset = le64_to_cpu(sb->layout.sb_offset[0]);
 
        if (format_opts.passphrase)
@@ -715,7 +727,7 @@ static int migrate_fs(const char            *fs_path,
 
        mark_unreserved_space(c, extents);
 
-       int ret = bch2_fs_start(c);
+       ret = bch2_fs_start(c);
        if (ret)
                die("Error starting new filesystem: %s", bch2_err_str(ret));
 
@@ -726,6 +738,7 @@ static int migrate_fs(const char            *fs_path,
        printf("Migrate complete, running fsck:\n");
        opt_set(opts, nostart,  false);
        opt_set(opts, nochanges, true);
+       opt_set(opts, read_only, true);
 
        c = bch2_fs_open(path, 1, opts);
        if (IS_ERR(c))