bcachefs: bch2_extent_fallocate()
authorKent Overstreet <kent.overstreet@linux.dev>
Sun, 13 Nov 2022 23:54:37 +0000 (18:54 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:51 +0000 (17:09 -0400)
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>
fs/bcachefs/fs-io.c
fs/bcachefs/io.c
fs/bcachefs/io.h

index 944fffd9f7b54c9b7a54e2c7416e163167a2c461..77037574cb0d5d57054d1751587d6738b5a87002 100644 (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;
        }
index af6b9a7456f54578c6f8d3a21ad5c4ed3333f24d..bde3a4c421893a2a4eca376bf4eaeab0cc053f7d 100644 (file)
@@ -360,6 +360,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:
  */
index 39f2aabf4f5969ac93b18e1875f63d0e24cc3020..aafe1bf993bbf9578f0cba673317d797c268e17d 100644 (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 *);