bcachefs: bch2_fiemap(): call trans_begin() on every loop iter
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 17 Jul 2024 15:50:54 +0000 (11:50 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Mon, 9 Sep 2024 13:41:48 +0000 (09:41 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/fs.c

index d90b308..2de776d 100644 (file)
@@ -1095,7 +1095,6 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
        struct bkey_buf cur, prev;
        unsigned offset_into_extent, sectors;
        bool have_extent = false;
-       u32 snapshot;
        int ret = 0;
 
        ret = fiemap_prep(&ei->v, info, start, &len, FIEMAP_FLAG_SYNC);
@@ -1111,21 +1110,30 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
        bch2_bkey_buf_init(&cur);
        bch2_bkey_buf_init(&prev);
        trans = bch2_trans_get(c);
-retry:
-       bch2_trans_begin(trans);
-
-       ret = bch2_subvolume_get_snapshot(trans, ei->ei_inum.subvol, &snapshot);
-       if (ret)
-               goto err;
 
        bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
-                            SPOS(ei->v.i_ino, start, snapshot), 0);
+                            POS(ei->v.i_ino, start), 0);
 
-       while (!(ret = btree_trans_too_many_iters(trans)) &&
-              (k = bch2_btree_iter_peek_upto(&iter, end)).k &&
-              !(ret = bkey_err(k))) {
+       while (true) {
                enum btree_id data_btree = BTREE_ID_extents;
 
+               bch2_trans_begin(trans);
+
+               u32 snapshot;
+               ret = bch2_subvolume_get_snapshot(trans, ei->ei_inum.subvol, &snapshot);
+               if (ret)
+                       goto err;
+
+               bch2_btree_iter_set_snapshot(&iter, snapshot);
+
+               k = bch2_btree_iter_peek_upto(&iter, end);
+               ret = bkey_err(k);
+               if (ret)
+                       goto err;
+
+               if (!k.k)
+                       break;
+
                if (!bkey_extent_is_data(k.k) &&
                    k.k->type != KEY_TYPE_reservation) {
                        bch2_btree_iter_advance(&iter);
@@ -1169,16 +1177,12 @@ retry:
 
                bch2_btree_iter_set_pos(&iter,
                        POS(iter.pos.inode, iter.pos.offset + sectors));
-
-               ret = bch2_trans_relock(trans);
-               if (ret)
+err:
+               if (ret &&
+                   !bch2_err_matches(ret, BCH_ERR_transaction_restart))
                        break;
        }
-       start = iter.pos.offset;
        bch2_trans_iter_exit(trans, &iter);
-err:
-       if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
-               goto retry;
 
        if (!ret && have_extent) {
                bch2_trans_unlock(trans);