bcachefs: bch2_extent_trim_atomic()
authorKent Overstreet <kent.overstreet@gmail.com>
Sun, 5 Aug 2018 21:46:41 +0000 (17:46 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:09 +0000 (17:08 -0400)
Prep work for extents insert hook removal

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/extents.c
fs/bcachefs/extents.h
fs/bcachefs/fs-io.c

index b2f50e16278447f0d7b1da5e4c7f8b1bcb9c2684..59d2eaea9edf9d14d930f9dac8f7849ac7253290 100644 (file)
@@ -1298,6 +1298,17 @@ extent_insert_advance_pos(struct extent_insert_state *s, struct bkey_s_c k)
        return __extent_insert_advance_pos(s, next_pos, k);
 }
 
+void bch2_extent_trim_atomic(struct bkey_i *k, struct btree_iter *iter)
+{
+       struct btree *b = iter->l[0].b;
+
+       BUG_ON(iter->uptodate > BTREE_ITER_NEED_PEEK);
+
+       bch2_cut_back(b->key.k.p, &k->k);
+
+       BUG_ON(bkey_cmp(bkey_start_pos(&k->k), b->data->min_key) < 0);
+}
+
 enum btree_insert_ret
 bch2_extent_can_insert(struct btree_insert *trans,
                       struct btree_insert_entry *insert,
@@ -1311,6 +1322,9 @@ bch2_extent_can_insert(struct btree_insert *trans,
        struct bkey_s_c k;
        int sectors;
 
+       BUG_ON(trans->flags & BTREE_INSERT_ATOMIC &&
+              !bch2_extent_is_atomic(&insert->k->k, insert->iter));
+
        /*
         * We avoid creating whiteouts whenever possible when deleting, but
         * those optimizations mean we may potentially insert two whiteouts
index fddf25c3fa4bc2703d818e95b2015eb71adb1e3a..0721d1829f98f9788bca1609a3ed722306a9ba7f 100644 (file)
@@ -62,6 +62,17 @@ int bch2_extent_pick_ptr(struct bch_fs *, struct bkey_s_c,
                         struct bch_devs_mask *,
                         struct extent_pick_ptr *);
 
+void bch2_extent_trim_atomic(struct bkey_i *, struct btree_iter *);
+
+static inline bool bch2_extent_is_atomic(struct bkey *k,
+                                        struct btree_iter *iter)
+{
+       struct btree *b = iter->l[0].b;
+
+       return bkey_cmp(k->p, b->key.k.p) <= 0 &&
+               bkey_cmp(bkey_start_pos(k), b->data->min_key) >= 0;
+}
+
 enum btree_insert_ret
 bch2_extent_can_insert(struct btree_insert *, struct btree_insert_entry *,
                       unsigned *);
index cc99eb1b36e0d643003ffe26554cd7158259fa57..da8c1917c7602abb9c8c57bb8097a540b3e7ff96 100644 (file)
@@ -6,6 +6,7 @@
 #include "buckets.h"
 #include "clock.h"
 #include "error.h"
+#include "extents.h"
 #include "fs.h"
 #include "fs-io.h"
 #include "fsck.h"
@@ -430,17 +431,22 @@ static int bchfs_write_index_update(struct bch_write_op *wop)
        hook.need_inode_update  = false;
 
        do {
-               /* XXX: inode->i_size locking */
-               k = bch2_keylist_front(keys);
-               if (min(k->k.p.offset << 9, op->new_i_size) >
-                   op->inode->ei_inode.bi_size)
-                       hook.need_inode_update = true;
+               BKEY_PADDED(k) tmp;
 
-               /* optimization for fewer transaction restarts: */
                ret = bch2_btree_iter_traverse(extent_iter);
                if (ret)
                        goto err;
 
+               bkey_copy(&tmp.k, bch2_keylist_front(keys));
+               k = &tmp.k;
+
+               bch2_extent_trim_atomic(k, extent_iter);
+
+               /* XXX: inode->i_size locking */
+               if (min(k->k.p.offset << 9, op->new_i_size) >
+                   op->inode->ei_inode.bi_size)
+                       hook.need_inode_update = true;
+
                if (hook.need_inode_update) {
                        struct bkey_s_c inode;
 
@@ -515,8 +521,10 @@ err:
                if (hook.need_inode_update)
                        op->inode->ei_inode = hook.inode_u;
 
-               BUG_ON(bkey_cmp(extent_iter->pos, k->k.p) < 0);
-               bch2_keylist_pop_front(keys);
+               if (bkey_cmp(extent_iter->pos, bch2_keylist_front(keys)->k.p) < 0)
+                       bch2_cut_front(extent_iter->pos, bch2_keylist_front(keys));
+               else
+                       bch2_keylist_pop_front(keys);
        } while (!bch2_keylist_empty(keys));
 
        bch2_trans_exit(&trans);
@@ -2458,6 +2466,12 @@ static long bch2_fcollapse(struct bch_inode_info *inode,
                bch2_cut_front(src->pos, &copy.k);
                copy.k.k.p.offset -= len >> 9;
 
+               ret = bch2_btree_iter_traverse(dst);
+               if (ret)
+                       goto btree_iter_err;
+
+               bch2_extent_trim_atomic(&copy.k, dst);
+
                BUG_ON(bkey_cmp(dst->pos, bkey_start_pos(&copy.k.k)));
 
                ret = bch2_disk_reservation_get(c, &disk_res, copy.k.k.size,