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>
This commit is contained in:
Kent Overstreet 2022-11-13 18:54:37 -05:00
parent 9bcbc0307d
commit 70de7a47e2
3 changed files with 38 additions and 26 deletions

View file

@ -3074,9 +3074,7 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
while (!ret && bkey_lt(iter.pos, end_pos)) {
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;
@ -3107,16 +3105,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,
@ -3126,25 +3115,15 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
goto bkey_err;
}
if (reservation.v.nr_replicas < opts.data_replicas ||
bch2_bkey_sectors_compressed(k)) {
ret = bch2_disk_reservation_get(c, &disk_res, sectors,
opts.data_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, &quota_res, i_sectors_delta);
bkey_err:
bch2_quota_reservation_put(c, inode, &quota_res);
bch2_disk_reservation_put(c, &disk_res);
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
ret = 0;
}

View file

@ -360,6 +360,36 @@ int bch2_extent_update(struct btree_trans *trans,
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:
*/

View file

@ -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 *);