summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2022-11-13 18:54:37 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2023-01-06 19:47:58 -0500
commit7aba7622bc45731a7e4c16466b7921981d3f5d8d (patch)
treed448cebafb6e05ac6cd4ab86708ddd50a3fde2fd
parentd193e2fcaffd179f4ee05acfef189180a5a4fa10 (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.c35
-rw-r--r--fs/bcachefs/io.c30
-rw-r--r--fs/bcachefs/io.h3
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, &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;
}
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 *);