]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bcachefs: Fix unhandled transaction restart in fallocate
authorKent Overstreet <kent.overstreet@linux.dev>
Sat, 26 Oct 2024 00:18:48 +0000 (20:18 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Tue, 29 Oct 2024 10:34:10 +0000 (06:34 -0400)
This used to not matter, but now we're being more strict.

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

index 15d3f073b8243d268323a3a29590babec4ddca5a..2456c41b215ee019bc359dab7d7b998a309219c9 100644 (file)
@@ -587,7 +587,7 @@ static noinline int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
                        POS(inode->v.i_ino, start_sector),
                        BTREE_ITER_slots|BTREE_ITER_intent);
 
-       while (!ret && bkey_lt(iter.pos, end_pos)) {
+       while (!ret) {
                s64 i_sectors_delta = 0;
                struct quota_res quota_res = { 0 };
                struct bkey_s_c k;
@@ -598,6 +598,9 @@ static noinline int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
 
                bch2_trans_begin(trans);
 
+               if (bkey_ge(iter.pos, end_pos))
+                       break;
+
                ret = bch2_subvolume_get_snapshot(trans,
                                        inode->ei_inum.subvol, &snapshot);
                if (ret)
@@ -634,12 +637,15 @@ static noinline int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
                        if (bch2_clamp_data_hole(&inode->v,
                                                 &hole_start,
                                                 &hole_end,
-                                                opts.data_replicas, true))
+                                                opts.data_replicas, true)) {
                                ret = drop_locks_do(trans,
                                        (bch2_clamp_data_hole(&inode->v,
                                                              &hole_start,
                                                              &hole_end,
                                                              opts.data_replicas, false), 0));
+                               if (ret)
+                                       goto bkey_err;
+                       }
                        bch2_btree_iter_set_pos(&iter, POS(iter.pos.inode, hole_start));
 
                        if (ret)
@@ -667,10 +673,13 @@ static noinline int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
                bch2_i_sectors_acct(c, inode, &quota_res, i_sectors_delta);
 
                if (bch2_mark_pagecache_reserved(inode, &hole_start,
-                                                iter.pos.offset, true))
-                       drop_locks_do(trans,
+                                                iter.pos.offset, true)) {
+                       ret = drop_locks_do(trans,
                                bch2_mark_pagecache_reserved(inode, &hole_start,
                                                             iter.pos.offset, false));
+                       if (ret)
+                               goto bkey_err;
+               }
 bkey_err:
                bch2_quota_reservation_put(c, inode, &quota_res);
                if (bch2_err_matches(ret, BCH_ERR_transaction_restart))