#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"
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));
}
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)
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,
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));
{
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);
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,
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;
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));
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);
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 {
if (errno)
die("readdir error: %m");
+ closedir(dir);
}
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);
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);
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);