]> www.infradead.org Git - users/hch/dma-mapping.git/commitdiff
bcachefs: Don't use commit_do() unnecessarily
authorKent Overstreet <kent.overstreet@linux.dev>
Mon, 14 Oct 2024 01:53:26 +0000 (21:53 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Fri, 18 Oct 2024 04:49:48 +0000 (00:49 -0400)
Using commit_do() to call alloc_sectors_start_trans() breaks when we're
randomly injecting transaction restarts - the restart in the commit
causes us to leak the lock that alloc_sectorS_start_trans() takes.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
21 files changed:
fs/bcachefs/alloc_background.c
fs/bcachefs/alloc_foreground.c
fs/bcachefs/btree_io.c
fs/bcachefs/btree_iter.h
fs/bcachefs/btree_update.c
fs/bcachefs/btree_update.h
fs/bcachefs/btree_update_interior.c
fs/bcachefs/disk_accounting.c
fs/bcachefs/ec.c
fs/bcachefs/fs.c
fs/bcachefs/fsck.c
fs/bcachefs/inode.c
fs/bcachefs/io_read.c
fs/bcachefs/io_write.c
fs/bcachefs/quota.c
fs/bcachefs/rebalance.c
fs/bcachefs/recovery.c
fs/bcachefs/subvolume.c
fs/bcachefs/super.c
fs/bcachefs/tests.c
fs/bcachefs/xattr.c

index 69c7fc97e467941817a4572ada1aee6538f621e6..c84a91572a1da88b4c5a1aff96a1b6f16ee03a6e 100644 (file)
@@ -1977,7 +1977,7 @@ static void bch2_do_discards_fast_work(struct work_struct *work)
                                             ca->mi.bucket_size,
                                             GFP_KERNEL);
 
-               int ret = bch2_trans_do(c, NULL, NULL,
+               int ret = bch2_trans_commit_do(c, NULL, NULL,
                        BCH_WATERMARK_btree|
                        BCH_TRANS_COMMIT_no_enospc,
                        bch2_clear_bucket_needs_discard(trans, POS(ca->dev_idx, bucket)));
index d0e0b56892e39f86fc00a1936cf3864d110e94eb..5836870ab882e55b322380d15d7a5090872f4270 100644 (file)
@@ -684,7 +684,7 @@ struct open_bucket *bch2_bucket_alloc(struct bch_fs *c, struct bch_dev *ca,
        struct bch_dev_usage usage;
        struct open_bucket *ob;
 
-       bch2_trans_do(c, NULL, NULL, 0,
+       bch2_trans_do(c,
                      PTR_ERR_OR_ZERO(ob = bch2_bucket_alloc_trans(trans, ca, watermark,
                                                        data_type, cl, false, &usage)));
        return ob;
index cf933409d385048f5c305bed1280ba859b7fbf6f..6296a11ccb09023a7940b3a80cef5532d5caaf6c 100644 (file)
@@ -1871,7 +1871,7 @@ static void btree_node_write_work(struct work_struct *work)
 
                }
        } else {
-               ret = bch2_trans_do(c, NULL, NULL, 0,
+               ret = bch2_trans_do(c,
                        bch2_btree_node_update_key_get_iter(trans, b, &wbio->key,
                                        BCH_WATERMARK_interior_updates|
                                        BCH_TRANS_COMMIT_journal_reclaim|
index 31a58bf46fdbfbf2ad66dbca96865ad2aa1df044..0bda054f80d76c609aaeb37f7445b84d82d9dae7 100644 (file)
@@ -912,6 +912,8 @@ struct bkey_s_c bch2_btree_iter_peek_and_restart_outlined(struct btree_iter *);
        _ret;                                                           \
 })
 
+#define bch2_trans_do(_c, _do) bch2_trans_run(_c, lockrestart_do(trans, _do))
+
 struct btree_trans *__bch2_trans_get(struct bch_fs *, unsigned);
 void bch2_trans_put(struct btree_trans *);
 
index 514df618548e28e624c71ba1fbb426d678789a49..5d809e8bd170886a3ec1baeddeb550d38d84a827 100644 (file)
@@ -668,7 +668,7 @@ int bch2_btree_insert(struct bch_fs *c, enum btree_id id, struct bkey_i *k,
                      struct disk_reservation *disk_res, int flags,
                      enum btree_iter_update_trigger_flags iter_flags)
 {
-       return bch2_trans_do(c, disk_res, NULL, flags,
+       return bch2_trans_commit_do(c, disk_res, NULL, flags,
                             bch2_btree_insert_trans(trans, id, k, iter_flags));
 }
 
@@ -865,7 +865,7 @@ __bch2_fs_log_msg(struct bch_fs *c, unsigned commit_flags, const char *fmt,
                memcpy(l->d, buf.buf, buf.pos);
                c->journal.early_journal_entries.nr += jset_u64s(u64s);
        } else {
-               ret = bch2_trans_do(c, NULL, NULL,
+               ret = bch2_trans_commit_do(c, NULL, NULL,
                        BCH_TRANS_COMMIT_lazy_rw|commit_flags,
                        __bch2_trans_log_msg(trans, &buf, u64s));
        }
index 6a454f2fa00534082a8013a3c7db321cabcbf603..70b3c989fac23d23b804062836f555caaeb5b687 100644 (file)
@@ -192,7 +192,7 @@ static inline int bch2_trans_commit(struct btree_trans *trans,
        nested_lockrestart_do(_trans, _do ?: bch2_trans_commit(_trans, (_disk_res),\
                                        (_journal_seq), (_flags)))
 
-#define bch2_trans_do(_c, _disk_res, _journal_seq, _flags, _do)                \
+#define bch2_trans_commit_do(_c, _disk_res, _journal_seq, _flags, _do)         \
        bch2_trans_run(_c, commit_do(trans, _disk_res, _journal_seq, _flags, _do))
 
 #define trans_for_each_update(_trans, _i)                              \
index 190bc1e81756ca9c3c4f48ca41ef4e38bd8e8701..64f0928e113784c5aabda46c0197d0a5882409da 100644 (file)
@@ -2239,10 +2239,8 @@ static void async_btree_node_rewrite_work(struct work_struct *work)
        struct async_btree_rewrite *a =
                container_of(work, struct async_btree_rewrite, work);
        struct bch_fs *c = a->c;
-       int ret;
 
-       ret = bch2_trans_do(c, NULL, NULL, 0,
-                     async_btree_node_rewrite_trans(trans, a));
+       int ret = bch2_trans_do(c, async_btree_node_rewrite_trans(trans, a));
        bch_err_fn_ratelimited(c, ret);
        bch2_write_ref_put(c, BCH_WRITE_REF_node_rewrite);
        kfree(a);
index e309fb78529bd36d619b73a701c67365b42243ed..07eb8fa1b02666acf88494818cc1d3759a75e451 100644 (file)
@@ -856,8 +856,10 @@ int bch2_dev_usage_init(struct bch_dev *ca, bool gc)
        };
        u64 v[3] = { ca->mi.nbuckets - ca->mi.first_bucket, 0, 0 };
 
-       int ret = bch2_trans_do(c, NULL, NULL, 0,
-                       bch2_disk_accounting_mod(trans, &acc, v, ARRAY_SIZE(v), gc));
+       int ret = bch2_trans_do(c, ({
+               bch2_disk_accounting_mod(trans, &acc, v, ARRAY_SIZE(v), gc) ?:
+               (!gc ? bch2_trans_commit(trans, NULL, NULL, 0) : 0);
+       }));
        bch_err_fn(c, ret);
        return ret;
 }
index e410cfe37b1a314d05fde8a0a691833f8983066d..a2303425959dad0e38aaeab29ff1a8959d83ef47 100644 (file)
@@ -1186,7 +1186,7 @@ static void ec_stripe_delete_work(struct work_struct *work)
                if (!idx)
                        break;
 
-               int ret = bch2_trans_do(c, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
+               int ret = bch2_trans_commit_do(c, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
                                        ec_stripe_delete(trans, idx));
                bch_err_fn(c, ret);
                if (ret)
@@ -1519,14 +1519,14 @@ static void ec_stripe_create(struct ec_stripe_new *s)
                goto err;
        }
 
-       ret = bch2_trans_do(c, &s->res, NULL,
-                           BCH_TRANS_COMMIT_no_check_rw|
-                           BCH_TRANS_COMMIT_no_enospc,
-                           ec_stripe_key_update(trans,
-                                       s->have_existing_stripe
-                                       ? bkey_i_to_stripe(&s->existing_stripe.key)
-                                       : NULL,
-                                       bkey_i_to_stripe(&s->new_stripe.key)));
+       ret = bch2_trans_commit_do(c, &s->res, NULL,
+               BCH_TRANS_COMMIT_no_check_rw|
+               BCH_TRANS_COMMIT_no_enospc,
+               ec_stripe_key_update(trans,
+                                    s->have_existing_stripe
+                                    ? bkey_i_to_stripe(&s->existing_stripe.key)
+                                    : NULL,
+                                    bkey_i_to_stripe(&s->new_stripe.key)));
        bch_err_msg(c, ret, "creating stripe key");
        if (ret) {
                goto err;
index 165d95994bd2ebbadb8ca7d3e6241fafd4a42edd..506b9a2b5bd7b77c2dd9a5b6086a7f7c85791043 100644 (file)
@@ -658,7 +658,7 @@ static struct dentry *bch2_lookup(struct inode *vdir, struct dentry *dentry,
        struct bch_hash_info hash = bch2_hash_info_init(c, &dir->ei_inode);
 
        struct bch_inode_info *inode;
-       bch2_trans_do(c, NULL, NULL, 0,
+       bch2_trans_do(c,
                PTR_ERR_OR_ZERO(inode = bch2_lookup_trans(trans, inode_inum(dir),
                                                          &hash, &dentry->d_name)));
        if (IS_ERR(inode))
index a1087fd292e475d9fa5bfbe929d028a17081e82f..807098e76e7aaf9959433893095673c166f5b8a2 100644 (file)
@@ -2509,7 +2509,7 @@ fsck_err:
 /* Get root directory, create if it doesn't exist: */
 int bch2_check_root(struct bch_fs *c)
 {
-       int ret = bch2_trans_do(c, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
+       int ret = bch2_trans_commit_do(c, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
                check_root_trans(trans));
        bch_err_fn(c, ret);
        return ret;
index 2c037e84fbaed43502caf88be221800a9788ebdd..47544dc91d9e3896025430f7c759480f1ac8756c 100644 (file)
@@ -1087,8 +1087,7 @@ int bch2_inode_find_by_inum_trans(struct btree_trans *trans,
 int bch2_inode_find_by_inum(struct bch_fs *c, subvol_inum inum,
                            struct bch_inode_unpacked *inode)
 {
-       return bch2_trans_do(c, NULL, NULL, 0,
-               bch2_inode_find_by_inum_trans(trans, inum, inode));
+       return bch2_trans_do(c, bch2_inode_find_by_inum_trans(trans, inum, inode));
 }
 
 int bch2_inode_nlink_inc(struct bch_inode_unpacked *bi)
index f00beff9ca0efcca7b93ec90402efaf091c06679..fc246f342820f59437888547d0e4e1ca97d94141 100644 (file)
@@ -557,8 +557,8 @@ out:
 
 static noinline void bch2_rbio_narrow_crcs(struct bch_read_bio *rbio)
 {
-       bch2_trans_do(rbio->c, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
-                     __bch2_rbio_narrow_crcs(trans, rbio));
+       bch2_trans_commit_do(rbio->c, NULL, NULL, BCH_TRANS_COMMIT_no_enospc,
+                            __bch2_rbio_narrow_crcs(trans, rbio));
 }
 
 /* Inner part that may run in process context */
index b5fe9e0dc1557c7f52d18fbf60c791940043af32..8609e25e450f599006a480cc2044379781d7144f 100644 (file)
@@ -1437,7 +1437,7 @@ again:
                 * freeing up space on specific disks, which means that
                 * allocations for specific disks may hang arbitrarily long:
                 */
-               ret = bch2_trans_do(c, NULL, NULL, 0,
+               ret = bch2_trans_run(c, lockrestart_do(trans,
                        bch2_alloc_sectors_start_trans(trans,
                                op->target,
                                op->opts.erasure_code && !(op->flags & BCH_WRITE_CACHED),
@@ -1447,7 +1447,7 @@ again:
                                op->nr_replicas_required,
                                op->watermark,
                                op->flags,
-                               &op->cl, &wp));
+                               &op->cl, &wp)));
                if (unlikely(ret)) {
                        if (bch2_err_matches(ret, BCH_ERR_operation_blocked))
                                break;
index c32a05e252e2abcbcc073db148741b531d11dfe8..74f45a8162ad7f649a8157bf7ddfd54c73021061 100644 (file)
@@ -869,7 +869,7 @@ static int bch2_set_quota(struct super_block *sb, struct kqid qid,
        bkey_quota_init(&new_quota.k_i);
        new_quota.k.p = POS(qid.type, from_kqid(&init_user_ns, qid));
 
-       ret = bch2_trans_do(c, NULL, NULL, 0,
+       ret = bch2_trans_commit_do(c, NULL, NULL, 0,
                            bch2_set_quota_trans(trans, &new_quota, qdq)) ?:
                __bch2_quota_set(c, bkey_i_to_s_c(&new_quota.k_i), qdq);
 
index 2d299a37cf07d7ea07290e0d08b543925e06143a..cd6647374353fb167dfb075a58350f33429f6b9d 100644 (file)
@@ -70,7 +70,9 @@ err:
 
 int bch2_set_rebalance_needs_scan(struct bch_fs *c, u64 inum)
 {
-       int ret = bch2_trans_do(c, NULL, NULL, BCH_TRANS_COMMIT_no_enospc|BCH_TRANS_COMMIT_lazy_rw,
+       int ret = bch2_trans_commit_do(c, NULL, NULL,
+                                      BCH_TRANS_COMMIT_no_enospc|
+                                      BCH_TRANS_COMMIT_lazy_rw,
                            __bch2_set_rebalance_needs_scan(trans, inum));
        rebalance_wakeup(c);
        return ret;
index 55e1504a813000e3e863467cf6557669fec4541a..454b5a32dd7fe56a87ec819e3496ca3cca63be1c 100644 (file)
@@ -1091,7 +1091,7 @@ int bch2_fs_initialize(struct bch_fs *c)
 
        bch2_inode_init_early(c, &lostfound_inode);
 
-       ret = bch2_trans_do(c, NULL, NULL, 0,
+       ret = bch2_trans_commit_do(c, NULL, NULL, 0,
                bch2_create_trans(trans,
                                  BCACHEFS_ROOT_SUBVOL_INUM,
                                  &root_inode, &lostfound_inode,
index 91d8187ee168af24544545b17d2a8a008ca5e57e..80e5efaff524be09a421f5dc62c3032c52914b7a 100644 (file)
@@ -319,8 +319,7 @@ int bch2_subvol_is_ro_trans(struct btree_trans *trans, u32 subvol)
 
 int bch2_subvol_is_ro(struct bch_fs *c, u32 subvol)
 {
-       return bch2_trans_do(c, NULL, NULL, 0,
-               bch2_subvol_is_ro_trans(trans, subvol));
+       return bch2_trans_do(c, bch2_subvol_is_ro_trans(trans, subvol));
 }
 
 int bch2_snapshot_get_subvol(struct btree_trans *trans, u32 snapshot,
@@ -676,8 +675,8 @@ err:
 /* set bi_subvol on root inode */
 int bch2_fs_upgrade_for_subvolumes(struct bch_fs *c)
 {
-       int ret = bch2_trans_do(c, NULL, NULL, BCH_TRANS_COMMIT_lazy_rw,
-                               __bch2_fs_upgrade_for_subvolumes(trans));
+       int ret = bch2_trans_commit_do(c, NULL, NULL, BCH_TRANS_COMMIT_lazy_rw,
+                                      __bch2_fs_upgrade_for_subvolumes(trans));
        bch_err_fn(c, ret);
        return ret;
 }
index 77d811a539af475f4f1de2b7894908ee21e0fec3..657fd3759e7b06bb352f25eb80036d59f43901f5 100644 (file)
@@ -1972,7 +1972,7 @@ int bch2_dev_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
                };
                u64 v[3] = { nbuckets - old_nbuckets, 0, 0 };
 
-               ret   = bch2_trans_do(ca->fs, NULL, NULL, 0,
+               ret   = bch2_trans_commit_do(ca->fs, NULL, NULL, 0,
                                bch2_disk_accounting_mod(trans, &acc, v, ARRAY_SIZE(v), false)) ?:
                        bch2_dev_freespace_init(c, ca, old_nbuckets, nbuckets);
                if (ret)
index b2f209743afeb50861e772f3e714fb95823e8a6b..315038a0a92d4df9c945d59c82dbf77889496205 100644 (file)
@@ -450,7 +450,7 @@ static int insert_test_overlapping_extent(struct bch_fs *c, u64 inum, u64 start,
        k.k_i.k.p.snapshot = snapid;
        k.k_i.k.size = len;
 
-       ret = bch2_trans_do(c, NULL, NULL, 0,
+       ret = bch2_trans_commit_do(c, NULL, NULL, 0,
                bch2_btree_insert_nonextent(trans, BTREE_ID_extents, &k.k_i,
                                            BTREE_UPDATE_internal_snapshot_node));
        bch_err_fn(c, ret);
@@ -510,7 +510,7 @@ static int test_snapshots(struct bch_fs *c, u64 nr)
        if (ret)
                return ret;
 
-       ret = bch2_trans_do(c, NULL, NULL, 0,
+       ret = bch2_trans_commit_do(c, NULL, NULL, 0,
                      bch2_snapshot_node_create(trans, U32_MAX,
                                                snapids,
                                                snapid_subvols,
index 56c8d3fe55a4ed065681a8111c1ba32de467ea5d..952aca400faf4f1a6f2d838b809a0a96c62ebd57 100644 (file)
@@ -330,7 +330,7 @@ static int bch2_xattr_get_handler(const struct xattr_handler *handler,
 {
        struct bch_inode_info *inode = to_bch_ei(vinode);
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
-       int ret = bch2_trans_do(c, NULL, NULL, 0,
+       int ret = bch2_trans_do(c,
                bch2_xattr_get_trans(trans, inode, name, buffer, size, handler->flags));
 
        if (ret < 0 && bch2_err_matches(ret, ENOENT))