diff options
Diffstat (limited to 'fs/bcachefs')
-rw-r--r-- | fs/bcachefs/bcachefs_ioctl.h | 12 | ||||
-rw-r--r-- | fs/bcachefs/chardev.c | 16 | ||||
-rw-r--r-- | fs/bcachefs/chardev.h | 3 | ||||
-rw-r--r-- | fs/bcachefs/ec.c | 23 | ||||
-rw-r--r-- | fs/bcachefs/ec.h | 5 | ||||
-rw-r--r-- | fs/bcachefs/fs-io-buffered.c | 4 | ||||
-rw-r--r-- | fs/bcachefs/fs-io-buffered.h | 4 | ||||
-rw-r--r-- | fs/bcachefs/fs-ioctl.c | 91 | ||||
-rw-r--r-- | fs/bcachefs/fs.c | 12 | ||||
-rw-r--r-- | fs/bcachefs/journal_io.c | 4 | ||||
-rw-r--r-- | fs/bcachefs/migrate.c | 55 | ||||
-rw-r--r-- | fs/bcachefs/migrate.h | 4 | ||||
-rw-r--r-- | fs/bcachefs/super.c | 6 |
13 files changed, 176 insertions, 63 deletions
diff --git a/fs/bcachefs/bcachefs_ioctl.h b/fs/bcachefs/bcachefs_ioctl.h index 5dc562f2a881..6043a8d93b1e 100644 --- a/fs/bcachefs/bcachefs_ioctl.h +++ b/fs/bcachefs/bcachefs_ioctl.h @@ -87,7 +87,9 @@ struct bch_ioctl_incremental { #define BCH_IOCTL_DISK_RESIZE_JOURNAL_v2 _IOW(0xbc, 28, struct bch_ioctl_disk_resize_journal_v2) #define BCH_IOCTL_SUBVOLUME_CREATE _IOW(0xbc, 16, struct bch_ioctl_subvolume) +#define BCH_IOCTL_SUBVOLUME_CREATE_v2 _IOW(0xbc, 29, struct bch_ioctl_subvolume_v2) #define BCH_IOCTL_SUBVOLUME_DESTROY _IOW(0xbc, 17, struct bch_ioctl_subvolume) +#define BCH_IOCTL_SUBVOLUME_DESTROY_v2 _IOW(0xbc, 30, struct bch_ioctl_subvolume_v2) #define BCH_IOCTL_DEV_USAGE_V2 _IOWR(0xbc, 18, struct bch_ioctl_dev_usage_v2) @@ -451,6 +453,16 @@ struct bch_ioctl_subvolume { __u64 src_ptr; }; +struct bch_ioctl_subvolume_v2 { + __u32 flags; + __u32 dirfd; + __u16 mode; + __u16 pad[3]; + __u64 dst_ptr; + __u64 src_ptr; + struct bch_ioctl_err_msg err; +}; + #define BCH_SUBVOL_SNAPSHOT_CREATE (1U << 0) #define BCH_SUBVOL_SNAPSHOT_RO (1U << 1) diff --git a/fs/bcachefs/chardev.c b/fs/bcachefs/chardev.c index f6f90d421f27..108c362a0ff4 100644 --- a/fs/bcachefs/chardev.c +++ b/fs/bcachefs/chardev.c @@ -187,7 +187,7 @@ static long bch2_ioctl_stop(struct bch_fs *c) } #endif -static int copy_ioctl_err_msg(struct bch_ioctl_err_msg *dst, struct printbuf *src, int ret) +int bch2_copy_ioctl_err_msg(struct bch_ioctl_err_msg *dst, struct printbuf *src, int ret) { if (ret) { prt_printf(src, "error=%s", bch2_err_str(ret)); @@ -243,7 +243,7 @@ static long bch2_ioctl_disk_add_v2(struct bch_fs *c, struct bch_ioctl_disk_v2 ar CLASS(printbuf, err)(); ret = bch2_dev_add(c, path, &err); kfree(path); - return copy_ioctl_err_msg(&arg.err, &err, ret); + return bch2_copy_ioctl_err_msg(&arg.err, &err, ret); } static long bch2_ioctl_disk_remove(struct bch_fs *c, struct bch_ioctl_disk arg) @@ -287,7 +287,7 @@ static long bch2_ioctl_disk_remove_v2(struct bch_fs *c, struct bch_ioctl_disk_v2 CLASS(printbuf, err)(); int ret = bch2_dev_remove(c, ca, arg.flags, &err); - return copy_ioctl_err_msg(&arg.err, &err, ret); + return bch2_copy_ioctl_err_msg(&arg.err, &err, ret); } static long bch2_ioctl_disk_online(struct bch_fs *c, struct bch_ioctl_disk arg) @@ -333,7 +333,7 @@ static long bch2_ioctl_disk_online_v2(struct bch_fs *c, struct bch_ioctl_disk_v2 CLASS(printbuf, err)(); ret = bch2_dev_online(c, path, &err); kfree(path); - return copy_ioctl_err_msg(&arg.err, &err, ret); + return bch2_copy_ioctl_err_msg(&arg.err, &err, ret); } static long bch2_ioctl_disk_offline(struct bch_fs *c, struct bch_ioctl_disk arg) @@ -377,7 +377,7 @@ static long bch2_ioctl_disk_offline_v2(struct bch_fs *c, struct bch_ioctl_disk_v CLASS(printbuf, err)(); int ret = bch2_dev_offline(c, ca, arg.flags, &err); - return copy_ioctl_err_msg(&arg.err, &err, ret); + return bch2_copy_ioctl_err_msg(&arg.err, &err, ret); } static long bch2_ioctl_disk_set_state(struct bch_fs *c, @@ -429,7 +429,7 @@ static long bch2_ioctl_disk_set_state_v2(struct bch_fs *c, ret = bch2_dev_set_state(c, ca, arg.new_state, arg.flags, &err); err: - return copy_ioctl_err_msg(&arg.err, &err, ret); + return bch2_copy_ioctl_err_msg(&arg.err, &err, ret); } struct bch_data_ctx { @@ -783,7 +783,7 @@ static long bch2_ioctl_disk_resize_v2(struct bch_fs *c, CLASS(printbuf, err)(); int ret = bch2_dev_resize(c, ca, arg.nbuckets, &err); - return copy_ioctl_err_msg(&arg.err, &err, ret); + return bch2_copy_ioctl_err_msg(&arg.err, &err, ret); } static long bch2_ioctl_disk_resize_journal(struct bch_fs *c, @@ -825,7 +825,7 @@ static long bch2_ioctl_disk_resize_journal_v2(struct bch_fs *c, CLASS(printbuf, err)(); int ret = bch2_set_nr_journal_buckets(c, ca, arg.nbuckets); - return copy_ioctl_err_msg(&arg.err, &err, ret); + return bch2_copy_ioctl_err_msg(&arg.err, &err, ret); } #define BCH_IOCTL(_name, _argtype) \ diff --git a/fs/bcachefs/chardev.h b/fs/bcachefs/chardev.h index 0f563ca53c36..cdd63e7618e9 100644 --- a/fs/bcachefs/chardev.h +++ b/fs/bcachefs/chardev.h @@ -4,6 +4,9 @@ #ifndef NO_BCACHEFS_FS +struct printbuf; +int bch2_copy_ioctl_err_msg(struct bch_ioctl_err_msg *, struct printbuf *, int); + long bch2_fs_ioctl(struct bch_fs *, unsigned, void __user *); void bch2_fs_chardev_exit(struct bch_fs *); diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c index c2840cb674b2..271e252152da 100644 --- a/fs/bcachefs/ec.c +++ b/fs/bcachefs/ec.c @@ -2040,7 +2040,7 @@ int bch2_invalidate_stripe_to_dev(struct btree_trans *trans, struct btree_iter *iter, struct bkey_s_c k, unsigned dev_idx, - unsigned flags) + unsigned flags, struct printbuf *err) { if (k.k->type != KEY_TYPE_stripe) return 0; @@ -2081,13 +2081,21 @@ int bch2_invalidate_stripe_to_dev(struct btree_trans *trans, nr_good += ca && ca->mi.state != BCH_MEMBER_STATE_failed; } - if (nr_good < s->v.nr_blocks && !(flags & BCH_FORCE_IF_DATA_DEGRADED)) + if (nr_good < s->v.nr_blocks && !(flags & BCH_FORCE_IF_DATA_DEGRADED)) { + prt_str(err, "cannot drop device without degrading\n "); + bch2_bkey_val_to_text(err, c, k); + prt_newline(err); return bch_err_throw(c, remove_would_lose_data); + } unsigned nr_data = s->v.nr_blocks - s->v.nr_redundant; - if (nr_good < nr_data && !(flags & BCH_FORCE_IF_DATA_LOST)) + if (nr_good < nr_data && !(flags & BCH_FORCE_IF_DATA_LOST)) { + prt_str(err, "cannot drop device without losing data\n "); + bch2_bkey_val_to_text(err, c, k); + prt_newline(err); return bch_err_throw(c, remove_would_lose_data); + } sectors = -sectors; @@ -2099,7 +2107,7 @@ int bch2_invalidate_stripe_to_dev(struct btree_trans *trans, } static int bch2_invalidate_stripe_to_dev_from_alloc(struct btree_trans *trans, struct bkey_s_c k_a, - unsigned flags) + unsigned flags, struct printbuf *err) { struct bch_alloc_v4 a_convert; const struct bch_alloc_v4 *a = bch2_alloc_to_v4(k_a, &a_convert); @@ -2119,17 +2127,18 @@ static int bch2_invalidate_stripe_to_dev_from_alloc(struct btree_trans *trans, s if (ret) return ret; - return bch2_invalidate_stripe_to_dev(trans, &iter, s.s_c, k_a.k->p.inode, flags); + return bch2_invalidate_stripe_to_dev(trans, &iter, s.s_c, k_a.k->p.inode, flags, err); } -int bch2_dev_remove_stripes(struct bch_fs *c, unsigned dev_idx, unsigned flags) +int bch2_dev_remove_stripes(struct bch_fs *c, unsigned dev_idx, + unsigned flags, struct printbuf *err) { CLASS(btree_trans, trans)(c); int ret = for_each_btree_key_max_commit(trans, iter, BTREE_ID_alloc, POS(dev_idx, 0), POS(dev_idx, U64_MAX), BTREE_ITER_intent, k, NULL, NULL, 0, ({ - bch2_invalidate_stripe_to_dev_from_alloc(trans, k, flags); + bch2_invalidate_stripe_to_dev_from_alloc(trans, k, flags, err); })); bch_err_fn(c, ret); return ret; diff --git a/fs/bcachefs/ec.h b/fs/bcachefs/ec.h index e807e7027d7a..cc778da99030 100644 --- a/fs/bcachefs/ec.h +++ b/fs/bcachefs/ec.h @@ -289,8 +289,9 @@ static inline void ec_stripe_new_put(struct bch_fs *c, struct ec_stripe_new *s, } int bch2_invalidate_stripe_to_dev(struct btree_trans *, struct btree_iter *, - struct bkey_s_c, unsigned, unsigned); -int bch2_dev_remove_stripes(struct bch_fs *, unsigned, unsigned); + struct bkey_s_c, unsigned, + unsigned, struct printbuf *); +int bch2_dev_remove_stripes(struct bch_fs *, unsigned, unsigned, struct printbuf *); void bch2_ec_stop_dev(struct bch_fs *, struct bch_dev *); void bch2_fs_ec_stop(struct bch_fs *); diff --git a/fs/bcachefs/fs-io-buffered.c b/fs/bcachefs/fs-io-buffered.c index 9532f1a73053..45175a478b92 100644 --- a/fs/bcachefs/fs-io-buffered.c +++ b/fs/bcachefs/fs-io-buffered.c @@ -697,7 +697,7 @@ int bch2_writepages(struct address_space *mapping, struct writeback_control *wbc /* buffered writes: */ -int bch2_write_begin(struct file *file, struct address_space *mapping, +int bch2_write_begin(const struct kiocb *iocb, struct address_space *mapping, loff_t pos, unsigned len, struct folio **foliop, void **fsdata) { @@ -780,7 +780,7 @@ err_unlock: return bch2_err_class(ret); } -int bch2_write_end(struct file *file, struct address_space *mapping, +int bch2_write_end(const struct kiocb *iocb, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, struct folio *folio, void *fsdata) { diff --git a/fs/bcachefs/fs-io-buffered.h b/fs/bcachefs/fs-io-buffered.h index 3207ebbb4ab4..14de91c27656 100644 --- a/fs/bcachefs/fs-io-buffered.h +++ b/fs/bcachefs/fs-io-buffered.h @@ -10,9 +10,9 @@ int bch2_read_folio(struct file *, struct folio *); int bch2_writepages(struct address_space *, struct writeback_control *); void bch2_readahead(struct readahead_control *); -int bch2_write_begin(struct file *, struct address_space *, loff_t pos, +int bch2_write_begin(const struct kiocb *, struct address_space *, loff_t pos, unsigned len, struct folio **, void **); -int bch2_write_end(struct file *, struct address_space *, loff_t, +int bch2_write_end(const struct kiocb *, struct address_space *, loff_t, unsigned len, unsigned copied, struct folio *, void *); ssize_t bch2_write_iter(struct kiocb *, struct iov_iter *); diff --git a/fs/bcachefs/fs-ioctl.c b/fs/bcachefs/fs-ioctl.c index 8b9d3c7d1f57..20b46126c066 100644 --- a/fs/bcachefs/fs-ioctl.c +++ b/fs/bcachefs/fs-ioctl.c @@ -199,8 +199,9 @@ static int bch2_ioc_goingdown(struct bch_fs *c, u32 __user *arg) return ret; } -static long bch2_ioctl_subvolume_create(struct bch_fs *c, struct file *filp, - struct bch_ioctl_subvolume arg) +static long __bch2_ioctl_subvolume_create(struct bch_fs *c, struct file *filp, + struct bch_ioctl_subvolume_v2 arg, + struct printbuf *err) { struct inode *dir; struct bch_inode_info *inode; @@ -214,13 +215,17 @@ static long bch2_ioctl_subvolume_create(struct bch_fs *c, struct file *filp, unsigned create_flags = BCH_CREATE_SUBVOL; if (arg.flags & ~(BCH_SUBVOL_SNAPSHOT_CREATE| - BCH_SUBVOL_SNAPSHOT_RO)) + BCH_SUBVOL_SNAPSHOT_RO)) { + prt_str(err, "invalid flasg"); return -EINVAL; + } if (!(arg.flags & BCH_SUBVOL_SNAPSHOT_CREATE) && (arg.src_ptr || - (arg.flags & BCH_SUBVOL_SNAPSHOT_RO))) + (arg.flags & BCH_SUBVOL_SNAPSHOT_RO))) { + prt_str(err, "invalid flasg"); return -EINVAL; + } if (arg.flags & BCH_SUBVOL_SNAPSHOT_CREATE) create_flags |= BCH_CREATE_SNAPSHOT; @@ -243,6 +248,7 @@ static long bch2_ioctl_subvolume_create(struct bch_fs *c, struct file *filp, if (src_path.dentry->d_sb->s_fs_info != c) { path_put(&src_path); + prt_str(err, "src_path not on dst filesystem"); error = -EXDEV; goto err1; } @@ -258,6 +264,7 @@ static long bch2_ioctl_subvolume_create(struct bch_fs *c, struct file *filp, goto err2; if (dst_dentry->d_sb->s_fs_info != c) { + prt_str(err, "dst_path not on dst filesystem"); error = -EXDEV; goto err3; } @@ -276,6 +283,7 @@ static long bch2_ioctl_subvolume_create(struct bch_fs *c, struct file *filp, s_user_ns = dir->i_sb->s_user_ns; if (!kuid_has_mapping(s_user_ns, current_fsuid()) || !kgid_has_mapping(s_user_ns, current_fsgid())) { + prt_str(err, "current uid/gid not mapped into fs namespace"); error = -EOVERFLOW; goto err3; } @@ -315,8 +323,35 @@ err1: return error; } -static long bch2_ioctl_subvolume_destroy(struct bch_fs *c, struct file *filp, - struct bch_ioctl_subvolume arg) +static long bch2_ioctl_subvolume_create(struct bch_fs *c, struct file *filp, + struct bch_ioctl_subvolume arg) +{ + struct bch_ioctl_subvolume_v2 arg_v2 = { + .flags = arg.flags, + .dirfd = arg.dirfd, + .mode = arg.mode, + .dst_ptr = arg.dst_ptr, + .src_ptr = arg.src_ptr, + }; + + CLASS(printbuf, err)(); + long ret = __bch2_ioctl_subvolume_create(c, filp, arg_v2, &err); + if (ret) + bch_err_msg(c, ret, "%s", err.buf); + return ret; +} + +static long bch2_ioctl_subvolume_create_v2(struct bch_fs *c, struct file *filp, + struct bch_ioctl_subvolume_v2 arg) +{ + CLASS(printbuf, err)(); + long ret = __bch2_ioctl_subvolume_create(c, filp, arg, &err); + return bch2_copy_ioctl_err_msg(&arg.err, &err, ret); +} + +static long __bch2_ioctl_subvolume_destroy(struct bch_fs *c, struct file *filp, + struct bch_ioctl_subvolume_v2 arg, + struct printbuf *err) { const char __user *name = (void __user *)(unsigned long)arg.dst_ptr; struct path path; @@ -350,6 +385,32 @@ err: return ret; } +static long bch2_ioctl_subvolume_destroy(struct bch_fs *c, struct file *filp, + struct bch_ioctl_subvolume arg) +{ + struct bch_ioctl_subvolume_v2 arg_v2 = { + .flags = arg.flags, + .dirfd = arg.dirfd, + .mode = arg.mode, + .dst_ptr = arg.dst_ptr, + .src_ptr = arg.src_ptr, + }; + + CLASS(printbuf, err)(); + long ret = __bch2_ioctl_subvolume_destroy(c, filp, arg_v2, &err); + if (ret) + bch_err_msg(c, ret, "%s", err.buf); + return ret; +} + +static long bch2_ioctl_subvolume_destroy_v2(struct bch_fs *c, struct file *filp, + struct bch_ioctl_subvolume_v2 arg) +{ + CLASS(printbuf, err)(); + long ret = __bch2_ioctl_subvolume_destroy(c, filp, arg, &err); + return bch2_copy_ioctl_err_msg(&arg.err, &err, ret); +} + long bch2_fs_file_ioctl(struct file *file, unsigned cmd, unsigned long arg) { struct bch_inode_info *inode = file_bch_inode(file); @@ -391,6 +452,15 @@ long bch2_fs_file_ioctl(struct file *file, unsigned cmd, unsigned long arg) break; } + case BCH_IOCTL_SUBVOLUME_CREATE_v2: { + struct bch_ioctl_subvolume_v2 i; + + ret = copy_from_user(&i, (void __user *) arg, sizeof(i)) + ? -EFAULT + : bch2_ioctl_subvolume_create_v2(c, file, i); + break; + } + case BCH_IOCTL_SUBVOLUME_DESTROY: { struct bch_ioctl_subvolume i; @@ -400,6 +470,15 @@ long bch2_fs_file_ioctl(struct file *file, unsigned cmd, unsigned long arg) break; } + case BCH_IOCTL_SUBVOLUME_DESTROY_v2: { + struct bch_ioctl_subvolume_v2 i; + + ret = copy_from_user(&i, (void __user *) arg, sizeof(i)) + ? -EFAULT + : bch2_ioctl_subvolume_destroy_v2(c, file, i); + break; + } + default: ret = bch2_fs_ioctl(c, cmd, (void __user *) arg); break; diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c index 39ebcab17e32..c7bb5b108e2f 100644 --- a/fs/bcachefs/fs.c +++ b/fs/bcachefs/fs.c @@ -1520,11 +1520,11 @@ static const struct vm_operations_struct bch_vm_ops = { .page_mkwrite = bch2_page_mkwrite, }; -static int bch2_mmap(struct file *file, struct vm_area_struct *vma) +static int bch2_mmap_prepare(struct vm_area_desc *desc) { - file_accessed(file); + file_accessed(desc->file); - vma->vm_ops = &bch_vm_ops; + desc->vm_ops = &bch_vm_ops; return 0; } @@ -1586,7 +1586,7 @@ static const __maybe_unused unsigned bch_flags_to_xflags[] = { }; static int bch2_fileattr_get(struct dentry *dentry, - struct fileattr *fa) + struct file_kattr *fa) { struct bch_inode_info *inode = to_bch_ei(d_inode(dentry)); struct bch_fs *c = inode->v.i_sb->s_fs_info; @@ -1649,7 +1649,7 @@ static int fssetxattr_inode_update_fn(struct btree_trans *trans, static int bch2_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry, - struct fileattr *fa) + struct file_kattr *fa) { struct bch_inode_info *inode = to_bch_ei(d_inode(dentry)); struct bch_fs *c = inode->v.i_sb->s_fs_info; @@ -1714,7 +1714,7 @@ static const struct file_operations bch_file_operations = { .llseek = bch2_llseek, .read_iter = bch2_read_iter, .write_iter = bch2_write_iter, - .mmap = bch2_mmap, + .mmap_prepare = bch2_mmap_prepare, .get_unmapped_area = thp_get_unmapped_area, .fsync = bch2_fsync, .splice_read = filemap_splice_read, diff --git a/fs/bcachefs/journal_io.c b/fs/bcachefs/journal_io.c index 0a9fbc76f363..44328d02cf67 100644 --- a/fs/bcachefs/journal_io.c +++ b/fs/bcachefs/journal_io.c @@ -216,7 +216,9 @@ nocompact: if (seq < c->journal_entries_base_seq || seq >= c->journal_entries_base_seq + U32_MAX) { - bch_err(c, "journal entry sequence numbers span too large a range: cannot reply, contact developers"); + bch_err(c, "journal entry sequence numbers span too large a range: cannot replay, contact developers\n" + "base %llu last_seq currently %llu, but have seq %llu", + c->journal_entries_base_seq, jlist->last_seq, seq); return bch_err_throw(c, ENOMEM_journal_entry_add); } diff --git a/fs/bcachefs/migrate.c b/fs/bcachefs/migrate.c index 892990b4a6a6..5b4c3f4b1c25 100644 --- a/fs/bcachefs/migrate.c +++ b/fs/bcachefs/migrate.c @@ -22,8 +22,8 @@ #include "replicas.h" #include "super-io.h" -static int drop_dev_ptrs(struct bch_fs *c, struct bkey_s k, - unsigned dev_idx, unsigned flags, bool metadata) +static int drop_dev_ptrs(struct bch_fs *c, struct bkey_s k, unsigned dev_idx, + unsigned flags, struct printbuf *err, bool metadata) { unsigned replicas = metadata ? c->opts.metadata_replicas : c->opts.data_replicas; unsigned lost = metadata ? BCH_FORCE_IF_METADATA_LOST : BCH_FORCE_IF_DATA_LOST; @@ -34,14 +34,19 @@ static int drop_dev_ptrs(struct bch_fs *c, struct bkey_s k, nr_good = bch2_bkey_durability(c, k.s_c); if ((!nr_good && !(flags & lost)) || - (nr_good < replicas && !(flags & degraded))) + (nr_good < replicas && !(flags & degraded))) { + prt_str(err, "cannot drop device without degrading/losing data\n "); + bch2_bkey_val_to_text(err, c, k.s_c); + prt_newline(err); return bch_err_throw(c, remove_would_lose_data); + } return 0; } static int drop_btree_ptrs(struct btree_trans *trans, struct btree_iter *iter, - struct btree *b, unsigned dev_idx, unsigned flags) + struct btree *b, unsigned dev_idx, + unsigned flags, struct printbuf *err) { struct bch_fs *c = trans->c; struct bkey_buf k; @@ -49,10 +54,9 @@ static int drop_btree_ptrs(struct btree_trans *trans, struct btree_iter *iter, bch2_bkey_buf_init(&k); bch2_bkey_buf_copy(&k, c, &b->key); - int ret = drop_dev_ptrs(c, bkey_i_to_s(k.k), dev_idx, flags, true) ?: + int ret = drop_dev_ptrs(c, bkey_i_to_s(k.k), dev_idx, flags, err, true) ?: bch2_btree_node_update_key(trans, iter, b, k.k, 0, false); - bch_err_fn(c, ret); bch2_bkey_buf_exit(&k, c); return ret; } @@ -61,7 +65,7 @@ static int bch2_dev_usrdata_drop_key(struct btree_trans *trans, struct btree_iter *iter, struct bkey_s_c k, unsigned dev_idx, - unsigned flags) + unsigned flags, struct printbuf *err) { struct bch_fs *c = trans->c; struct bkey_i *n; @@ -75,7 +79,7 @@ static int bch2_dev_usrdata_drop_key(struct btree_trans *trans, if (ret) return ret; - ret = drop_dev_ptrs(c, bkey_i_to_s(n), dev_idx, flags, false); + ret = drop_dev_ptrs(c, bkey_i_to_s(n), dev_idx, flags, err, false); if (ret) return ret; @@ -101,7 +105,7 @@ static int bch2_dev_btree_drop_key(struct btree_trans *trans, struct bkey_s_c_backpointer bp, unsigned dev_idx, struct bkey_buf *last_flushed, - unsigned flags) + unsigned flags, struct printbuf *err) { struct btree_iter iter; struct btree *b = bch2_backpointer_get_node(trans, bp, &iter, last_flushed); @@ -109,7 +113,7 @@ static int bch2_dev_btree_drop_key(struct btree_trans *trans, if (ret) return ret == -BCH_ERR_backpointer_to_overwritten_btree_node ? 0 : ret; - ret = drop_btree_ptrs(trans, &iter, b, dev_idx, flags); + ret = drop_btree_ptrs(trans, &iter, b, dev_idx, flags, err); bch2_trans_iter_exit(&iter); return ret; @@ -117,7 +121,8 @@ static int bch2_dev_btree_drop_key(struct btree_trans *trans, static int bch2_dev_usrdata_drop(struct bch_fs *c, struct progress_indicator_state *progress, - unsigned dev_idx, unsigned flags) + unsigned dev_idx, + unsigned flags, struct printbuf *err) { CLASS(btree_trans, trans)(c); @@ -133,7 +138,7 @@ static int bch2_dev_usrdata_drop(struct bch_fs *c, BTREE_ITER_prefetch|BTREE_ITER_all_snapshots, k, NULL, NULL, BCH_TRANS_COMMIT_no_enospc, ({ bch2_progress_update_iter(trans, progress, &iter, "dropping user data"); - bch2_dev_usrdata_drop_key(trans, &iter, k, dev_idx, flags); + bch2_dev_usrdata_drop_key(trans, &iter, k, dev_idx, flags, err); })); if (ret) return ret; @@ -144,7 +149,8 @@ static int bch2_dev_usrdata_drop(struct bch_fs *c, static int bch2_dev_metadata_drop(struct bch_fs *c, struct progress_indicator_state *progress, - unsigned dev_idx, unsigned flags) + unsigned dev_idx, + unsigned flags, struct printbuf *err) { struct btree_iter iter; struct closure cl; @@ -174,7 +180,7 @@ retry: if (!bch2_bkey_has_device_c(bkey_i_to_s_c(&b->key), dev_idx)) goto next; - ret = drop_btree_ptrs(trans, &iter, b, dev_idx, flags); + ret = drop_btree_ptrs(trans, &iter, b, dev_idx, flags, err); if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) { ret = 0; continue; @@ -206,7 +212,7 @@ err: static int data_drop_bp(struct btree_trans *trans, unsigned dev_idx, struct bkey_s_c_backpointer bp, struct bkey_buf *last_flushed, - unsigned flags) + unsigned flags, struct printbuf *err) { struct btree_iter iter; struct bkey_s_c k = bch2_backpointer_get_key(trans, bp, &iter, BTREE_ITER_intent, @@ -226,17 +232,18 @@ static int data_drop_bp(struct btree_trans *trans, unsigned dev_idx, */ if (bkey_is_btree_ptr(k.k)) - ret = bch2_dev_btree_drop_key(trans, bp, dev_idx, last_flushed, flags); + ret = bch2_dev_btree_drop_key(trans, bp, dev_idx, last_flushed, flags, err); else if (k.k->type == KEY_TYPE_stripe) - ret = bch2_invalidate_stripe_to_dev(trans, &iter, k, dev_idx, flags); + ret = bch2_invalidate_stripe_to_dev(trans, &iter, k, dev_idx, flags, err); else - ret = bch2_dev_usrdata_drop_key(trans, &iter, k, dev_idx, flags); + ret = bch2_dev_usrdata_drop_key(trans, &iter, k, dev_idx, flags, err); out: bch2_trans_iter_exit(&iter); return ret; } -int bch2_dev_data_drop_by_backpointers(struct bch_fs *c, unsigned dev_idx, unsigned flags) +int bch2_dev_data_drop_by_backpointers(struct bch_fs *c, unsigned dev_idx, unsigned flags, + struct printbuf *err) { CLASS(btree_trans, trans)(c); @@ -253,22 +260,22 @@ int bch2_dev_data_drop_by_backpointers(struct bch_fs *c, unsigned dev_idx, unsig continue; data_drop_bp(trans, dev_idx, bkey_s_c_to_backpointer(k), - &last_flushed, flags); + &last_flushed, flags, err); })); bch2_bkey_buf_exit(&last_flushed, trans->c); - bch_err_fn(c, ret); return ret; } -int bch2_dev_data_drop(struct bch_fs *c, unsigned dev_idx, unsigned flags) +int bch2_dev_data_drop(struct bch_fs *c, unsigned dev_idx, + unsigned flags, struct printbuf *err) { struct progress_indicator_state progress; bch2_progress_init(&progress, c, BIT_ULL(BTREE_ID_extents)| BIT_ULL(BTREE_ID_reflink)); - return bch2_dev_usrdata_drop(c, &progress, dev_idx, flags) ?: - bch2_dev_metadata_drop(c, &progress, dev_idx, flags); + return bch2_dev_usrdata_drop(c, &progress, dev_idx, flags, err) ?: + bch2_dev_metadata_drop(c, &progress, dev_idx, flags, err); } diff --git a/fs/bcachefs/migrate.h b/fs/bcachefs/migrate.h index 30018140711b..ff4567fb5a83 100644 --- a/fs/bcachefs/migrate.h +++ b/fs/bcachefs/migrate.h @@ -2,7 +2,7 @@ #ifndef _BCACHEFS_MIGRATE_H #define _BCACHEFS_MIGRATE_H -int bch2_dev_data_drop_by_backpointers(struct bch_fs *, unsigned, unsigned); -int bch2_dev_data_drop(struct bch_fs *, unsigned, unsigned); +int bch2_dev_data_drop_by_backpointers(struct bch_fs *, unsigned, unsigned, struct printbuf *); +int bch2_dev_data_drop(struct bch_fs *, unsigned, unsigned, struct printbuf *); #endif /* _BCACHEFS_MIGRATE_H */ diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index 793c16fa8b09..d640ae188722 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -1992,9 +1992,9 @@ int bch2_dev_remove(struct bch_fs *c, struct bch_dev *ca, int flags, __bch2_dev_read_only(c, ca); ret = fast_device_removal - ? bch2_dev_data_drop_by_backpointers(c, ca->dev_idx, flags) - : (bch2_dev_data_drop(c, ca->dev_idx, flags) ?: - bch2_dev_remove_stripes(c, ca->dev_idx, flags)); + ? bch2_dev_data_drop_by_backpointers(c, ca->dev_idx, flags, err) + : (bch2_dev_data_drop(c, ca->dev_idx, flags, err) ?: + bch2_dev_remove_stripes(c, ca->dev_idx, flags, err)); if (ret) goto err; |