diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2022-11-13 18:54:37 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-01-06 19:47:58 -0500 |
commit | 7aba7622bc45731a7e4c16466b7921981d3f5d8d (patch) | |
tree | d448cebafb6e05ac6cd4ab86708ddd50a3fde2fd | |
parent | d193e2fcaffd179f4ee05acfef189180a5a4fa10 (diff) |
bcachefs: bch2_extent_fallocate()
This factors out part of __bchfs_fallocate() in fs-io.c into an new,
lower level io.c helper, which creates a single extent reservation.
This is prep work for nocow support - the new helper will shortly gain
the ability to create unwritten extents.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/fs-io.c | 35 | ||||
-rw-r--r-- | fs/bcachefs/io.c | 30 | ||||
-rw-r--r-- | fs/bcachefs/io.h | 3 |
3 files changed, 40 insertions, 28 deletions
diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c index e59d5e29951f..96b06b0a06b0 100644 --- a/fs/bcachefs/fs-io.c +++ b/fs/bcachefs/fs-io.c @@ -3044,7 +3044,7 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode, struct btree_trans trans; struct btree_iter iter; struct bpos end_pos = POS(inode->v.i_ino, end_sector); - unsigned replicas = io_opts(c, &inode->ei_inode).data_replicas; + struct bch_io_opts opts = io_opts(c, &inode->ei_inode); int ret = 0; bch2_trans_init(&trans, c, BTREE_ITER_MAX, 512); @@ -3055,9 +3055,7 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode, while (!ret && bkey_cmp(iter.pos, end_pos) < 0) { s64 i_sectors_delta = 0; - struct disk_reservation disk_res = { 0 }; struct quota_res quota_res = { 0 }; - struct bkey_i_reservation reservation; struct bkey_s_c k; unsigned sectors; u32 snapshot; @@ -3077,7 +3075,7 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode, /* already reserved */ if (k.k->type == KEY_TYPE_reservation && - bkey_s_c_to_reservation(k).v->nr_replicas >= replicas) { + bkey_s_c_to_reservation(k).v->nr_replicas >= opts.data_replicas) { bch2_btree_iter_advance(&iter); continue; } @@ -3088,16 +3086,7 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode, continue; } - bkey_reservation_init(&reservation.k_i); - reservation.k.type = KEY_TYPE_reservation; - reservation.k.p = k.k->p; - reservation.k.size = k.k->size; - - bch2_cut_front(iter.pos, &reservation.k_i); - bch2_cut_back(end_pos, &reservation.k_i); - - sectors = reservation.k.size; - reservation.v.nr_replicas = bch2_bkey_nr_ptrs_allocated(k); + sectors = bpos_min(k.k->p, end_pos).offset - iter.pos.offset; if (!bkey_extent_is_allocation(k.k)) { ret = bch2_quota_reservation_add(c, inode, @@ -3107,25 +3096,15 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode, goto bkey_err; } - if (reservation.v.nr_replicas < replicas || - bch2_bkey_sectors_compressed(k)) { - ret = bch2_disk_reservation_get(c, &disk_res, sectors, - replicas, 0); - if (unlikely(ret)) - goto bkey_err; - - reservation.v.nr_replicas = disk_res.nr_replicas; - } - - ret = bch2_extent_update(&trans, inode_inum(inode), &iter, - &reservation.k_i, &disk_res, - 0, &i_sectors_delta, true); + ret = bch2_extent_fallocate(&trans, inode_inum(inode), &iter, + sectors, opts, &i_sectors_delta, + writepoint_hashed((unsigned long) current)); if (ret) goto bkey_err; + i_sectors_acct(c, inode, "a_res, i_sectors_delta); bkey_err: bch2_quota_reservation_put(c, inode, "a_res); - bch2_disk_reservation_put(c, &disk_res); if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) ret = 0; } diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c index 72a922a164e2..94906e6da555 100644 --- a/fs/bcachefs/io.c +++ b/fs/bcachefs/io.c @@ -361,6 +361,36 @@ err: return ret; } +/* Overwrites whatever was present with zeroes: */ +int bch2_extent_fallocate(struct btree_trans *trans, + subvol_inum inum, + struct btree_iter *iter, + unsigned sectors, + struct bch_io_opts opts, + s64 *i_sectors_delta, + struct write_point_specifier write_point) +{ + int ret; + struct bch_fs *c = trans->c; + struct disk_reservation disk_res = { 0 }; + struct bkey_i_reservation *reservation = + bch2_trans_kmalloc(trans, sizeof(*reservation)); + + ret = PTR_ERR_OR_ZERO(reservation); + if (ret) + return ret; + + bkey_reservation_init(&reservation->k_i); + reservation->k.p = iter->pos; + bch2_key_resize(&reservation->k, sectors); + reservation->v.nr_replicas = opts.data_replicas; + + ret = bch2_extent_update(trans, inum, iter, &reservation->k_i, &disk_res, + 0, i_sectors_delta, true); + bch2_disk_reservation_put(c, &disk_res); + return ret; +} + /* * Returns -BCH_ERR_transacton_restart if we had to drop locks: */ diff --git a/fs/bcachefs/io.h b/fs/bcachefs/io.h index 43e78a368e84..da59d1196a47 100644 --- a/fs/bcachefs/io.h +++ b/fs/bcachefs/io.h @@ -74,6 +74,9 @@ int bch2_sum_sector_overwrites(struct btree_trans *, struct btree_iter *, int bch2_extent_update(struct btree_trans *, subvol_inum, struct btree_iter *, struct bkey_i *, struct disk_reservation *, u64, s64 *, bool); +int bch2_extent_fallocate(struct btree_trans *, subvol_inum, struct btree_iter *, + unsigned, struct bch_io_opts, s64 *, + struct write_point_specifier); int bch2_fpunch_at(struct btree_trans *, struct btree_iter *, subvol_inum, u64, s64 *); |