diff options
Diffstat (limited to 'fs/bcachefs/io_misc.c')
-rw-r--r-- | fs/bcachefs/io_misc.c | 64 |
1 files changed, 47 insertions, 17 deletions
diff --git a/fs/bcachefs/io_misc.c b/fs/bcachefs/io_misc.c index 1afea613df4a..327b3dd642de 100644 --- a/fs/bcachefs/io_misc.c +++ b/fs/bcachefs/io_misc.c @@ -15,6 +15,7 @@ #include "inode.h" #include "io_misc.h" #include "io_write.h" +#include "logged_ops.h" #include "subvolume.h" /* Overwrites whatever was present with zeroes: */ @@ -217,6 +218,17 @@ int bch2_fpunch(struct bch_fs *c, subvol_inum inum, u64 start, u64 end, return ret; } +/* truncate: */ + +void bch2_logged_op_truncate_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c k) +{ + struct bkey_s_c_logged_op_truncate op = bkey_s_c_to_logged_op_truncate(k); + + prt_printf(out, "subvol=%u", le32_to_cpu(op.v->subvol)); + prt_printf(out, " inum=%llu", le64_to_cpu(op.v->inum)); + prt_printf(out, " new_i_size=%llu", le64_to_cpu(op.v->new_i_size)); +} + static int truncate_set_isize(struct btree_trans *trans, subvol_inum inum, u64 new_i_size) @@ -233,36 +245,54 @@ static int truncate_set_isize(struct btree_trans *trans, return ret; } -int bch2_truncate(struct bch_fs *c, subvol_inum inum, u64 new_i_size, u64 *i_sectors_delta) +static int __bch2_resume_logged_op_truncate(struct btree_trans *trans, + struct bkey_i *op_k, + u64 *i_sectors_delta) { - struct btree_trans trans; + struct bch_fs *c = trans->c; struct btree_iter fpunch_iter; + struct bkey_i_logged_op_truncate *op = bkey_i_to_logged_op_truncate(op_k); + subvol_inum inum = { le32_to_cpu(op->v.subvol), le64_to_cpu(op->v.inum) }; + u64 new_i_size = le64_to_cpu(op->v.new_i_size); int ret; - bch2_trans_init(&trans, c, BTREE_ITER_MAX, 1024); - bch2_trans_iter_init(&trans, &fpunch_iter, BTREE_ID_extents, - POS(inum.inum, round_up(new_i_size, block_bytes(c)) >> 9), - BTREE_ITER_INTENT); - - ret = commit_do(&trans, NULL, NULL, BTREE_INSERT_NOFAIL, - truncate_set_isize(&trans, inum, new_i_size)); + ret = commit_do(trans, NULL, NULL, BTREE_INSERT_NOFAIL, + truncate_set_isize(trans, inum, new_i_size)); if (ret) goto err; - ret = bch2_fpunch_at(&trans, &fpunch_iter, inum, U64_MAX, i_sectors_delta); + bch2_trans_iter_init(trans, &fpunch_iter, BTREE_ID_extents, + POS(inum.inum, round_up(new_i_size, block_bytes(c)) >> 9), + BTREE_ITER_INTENT); + ret = bch2_fpunch_at(trans, &fpunch_iter, inum, U64_MAX, i_sectors_delta); + bch2_trans_iter_exit(trans, &fpunch_iter); + if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) ret = 0; - if (ret) - goto err; err: - bch2_trans_iter_exit(&trans, &fpunch_iter); - bch2_trans_exit(&trans); - - bch2_fs_fatal_err_on(ret, c, "%s: error truncating %u:%llu: %s", - __func__, inum.subvol, inum.inum, bch2_err_str(ret)); + bch2_logged_op_finish(trans, op_k); return ret; } +int bch2_resume_logged_op_truncate(struct btree_trans *trans, struct bkey_i *op_k) +{ + return __bch2_resume_logged_op_truncate(trans, op_k, NULL); +} + +int bch2_truncate(struct bch_fs *c, subvol_inum inum, u64 new_i_size, u64 *i_sectors_delta) +{ + struct bkey_i_logged_op_truncate op; + + bkey_logged_op_truncate_init(&op.k_i); + op.v.subvol = cpu_to_le32(inum.subvol); + op.v.inum = cpu_to_le64(inum.inum); + op.v.new_i_size = cpu_to_le64(new_i_size); + + return bch2_trans_run(c, + bch2_logged_op_start(&trans, &op.k_i) ?: + __bch2_resume_logged_op_truncate(&trans, &op.k_i, i_sectors_delta)); +} + static int adjust_i_size(struct btree_trans *trans, subvol_inum inum, u64 offset, s64 len) { struct btree_iter iter; |