bcachefs: Heap allocate btree_trans
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 12 Sep 2023 21:16:02 +0000 (17:16 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:10:13 +0000 (17:10 -0400)
We're using more stack than we'd like in a number of functions, and
btree_trans is the biggest object that we stack allocate.

But we have to do a heap allocatation to initialize it anyways, so
there's no real downside to heap allocating the entire thing.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
47 files changed:
fs/bcachefs/acl.c
fs/bcachefs/alloc_background.c
fs/bcachefs/alloc_foreground.c
fs/bcachefs/backpointers.c
fs/bcachefs/bcachefs.h
fs/bcachefs/btree_gc.c
fs/bcachefs/btree_io.c
fs/bcachefs/btree_iter.c
fs/bcachefs/btree_iter.h
fs/bcachefs/btree_key_cache.c
fs/bcachefs/btree_trans_commit.c
fs/bcachefs/btree_types.h
fs/bcachefs/btree_update.c
fs/bcachefs/btree_update.h
fs/bcachefs/btree_update_interior.c
fs/bcachefs/btree_write_buffer.c
fs/bcachefs/buckets.c
fs/bcachefs/data_update.c
fs/bcachefs/debug.c
fs/bcachefs/dirent.c
fs/bcachefs/ec.c
fs/bcachefs/fs-io-buffered.c
fs/bcachefs/fs-io-direct.c
fs/bcachefs/fs-io-pagecache.c
fs/bcachefs/fs-io.c
fs/bcachefs/fs.c
fs/bcachefs/fsck.c
fs/bcachefs/inode.c
fs/bcachefs/io_misc.c
fs/bcachefs/io_read.c
fs/bcachefs/io_write.c
fs/bcachefs/journal.c
fs/bcachefs/journal_seq_blacklist.c
fs/bcachefs/logged_ops.c
fs/bcachefs/lru.c
fs/bcachefs/migrate.c
fs/bcachefs/move.c
fs/bcachefs/movinggc.c
fs/bcachefs/quota.c
fs/bcachefs/recovery.c
fs/bcachefs/reflink.c
fs/bcachefs/snapshot.c
fs/bcachefs/subvolume.c
fs/bcachefs/super.c
fs/bcachefs/sysfs.c
fs/bcachefs/tests.c
fs/bcachefs/xattr.c

index ae2036b..9653401 100644 (file)
@@ -279,18 +279,16 @@ struct posix_acl *bch2_get_acl(struct mnt_idmap *idmap,
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
        struct bch_hash_info hash = bch2_hash_info_init(c, &inode->ei_inode);
        struct xattr_search_key search = X_SEARCH(acl_to_xattr_type(type), "", 0);
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter = { NULL };
        struct bkey_s_c_xattr xattr;
        struct posix_acl *acl = NULL;
        struct bkey_s_c k;
        int ret;
-
-       bch2_trans_init(&trans, c, 0, 0);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
 
-       ret = bch2_hash_lookup(&trans, &iter, bch2_xattr_hash_desc,
+       ret = bch2_hash_lookup(trans, &iter, bch2_xattr_hash_desc,
                        &hash, inode_inum(inode), &search, 0);
        if (ret) {
                if (!bch2_err_matches(ret, ENOENT))
@@ -306,7 +304,7 @@ retry:
        }
 
        xattr = bkey_s_c_to_xattr(k);
-       acl = bch2_acl_from_disk(&trans, xattr_val(xattr.v),
+       acl = bch2_acl_from_disk(trans, xattr_val(xattr.v),
                        le16_to_cpu(xattr.v->x_val_len));
 
        if (!IS_ERR(acl))
@@ -315,8 +313,8 @@ out:
        if (bch2_err_matches(PTR_ERR_OR_ZERO(acl), BCH_ERR_transaction_restart))
                goto retry;
 
-       bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_exit(trans, &iter);
+       bch2_trans_put(trans);
        return acl;
 }
 
@@ -356,7 +354,7 @@ int bch2_set_acl(struct mnt_idmap *idmap,
 {
        struct bch_inode_info *inode = to_bch_ei(dentry->d_inode);
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter inode_iter = { NULL };
        struct bch_inode_unpacked inode_u;
        struct posix_acl *acl;
@@ -364,12 +362,11 @@ int bch2_set_acl(struct mnt_idmap *idmap,
        int ret;
 
        mutex_lock(&inode->ei_update_lock);
-       bch2_trans_init(&trans, c, 0, 0);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
        acl = _acl;
 
-       ret = bch2_inode_peek(&trans, &inode_iter, &inode_u, inode_inum(inode),
+       ret = bch2_inode_peek(trans, &inode_iter, &inode_u, inode_inum(inode),
                              BTREE_ITER_INTENT);
        if (ret)
                goto btree_err;
@@ -382,30 +379,30 @@ retry:
                        goto btree_err;
        }
 
-       ret = bch2_set_acl_trans(&trans, inode_inum(inode), &inode_u, acl, type);
+       ret = bch2_set_acl_trans(trans, inode_inum(inode), &inode_u, acl, type);
        if (ret)
                goto btree_err;
 
        inode_u.bi_ctime        = bch2_current_time(c);
        inode_u.bi_mode         = mode;
 
-       ret =   bch2_inode_write(&trans, &inode_iter, &inode_u) ?:
-               bch2_trans_commit(&trans, NULL, NULL, 0);
+       ret =   bch2_inode_write(trans, &inode_iter, &inode_u) ?:
+               bch2_trans_commit(trans, NULL, NULL, 0);
 btree_err:
-       bch2_trans_iter_exit(&trans, &inode_iter);
+       bch2_trans_iter_exit(trans, &inode_iter);
 
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
        if (unlikely(ret))
                goto err;
 
-       bch2_inode_update_after_write(&trans, inode, &inode_u,
+       bch2_inode_update_after_write(trans, inode, &inode_u,
                                      ATTR_CTIME|ATTR_MODE);
 
        set_cached_acl(&inode->v, type, acl);
 err:
-       bch2_trans_exit(&trans);
        mutex_unlock(&inode->ei_update_lock);
+       bch2_trans_put(trans);
 
        return ret;
 }
index 4eab7e5..19ef7a4 100644 (file)
@@ -548,7 +548,7 @@ void bch2_bucket_gens_to_text(struct printbuf *out, struct bch_fs *c, struct bke
 
 int bch2_bucket_gens_init(struct bch_fs *c)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bch_alloc_v4 a;
@@ -559,9 +559,7 @@ int bch2_bucket_gens_init(struct bch_fs *c)
        u8 gen;
        int ret;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
-       for_each_btree_key(&trans, iter, BTREE_ID_alloc, POS_MIN,
+       for_each_btree_key(trans, iter, BTREE_ID_alloc, POS_MIN,
                           BTREE_ITER_PREFETCH, k, ret) {
                /*
                 * Not a fsck error because this is checked/repaired by
@@ -574,10 +572,10 @@ int bch2_bucket_gens_init(struct bch_fs *c)
                pos = alloc_gens_pos(iter.pos, &offset);
 
                if (have_bucket_gens_key && bkey_cmp(iter.pos, pos)) {
-                       ret = commit_do(&trans, NULL, NULL,
+                       ret = commit_do(trans, NULL, NULL,
                                        BTREE_INSERT_NOFAIL|
                                        BTREE_INSERT_LAZY_RW,
-                               bch2_btree_insert_trans(&trans, BTREE_ID_bucket_gens, &g.k_i, 0));
+                               bch2_btree_insert_trans(trans, BTREE_ID_bucket_gens, &g.k_i, 0));
                        if (ret)
                                break;
                        have_bucket_gens_key = false;
@@ -591,15 +589,15 @@ int bch2_bucket_gens_init(struct bch_fs *c)
 
                g.v.gens[offset] = gen;
        }
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 
        if (have_bucket_gens_key && !ret)
-               ret = commit_do(&trans, NULL, NULL,
+               ret = commit_do(trans, NULL, NULL,
                                BTREE_INSERT_NOFAIL|
                                BTREE_INSERT_LAZY_RW,
-                       bch2_btree_insert_trans(&trans, BTREE_ID_bucket_gens, &g.k_i, 0));
+                       bch2_btree_insert_trans(trans, BTREE_ID_bucket_gens, &g.k_i, 0));
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        if (ret)
                bch_err_fn(c, ret);
@@ -608,20 +606,19 @@ int bch2_bucket_gens_init(struct bch_fs *c)
 
 int bch2_alloc_read(struct bch_fs *c)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bch_dev *ca;
        int ret;
 
        down_read(&c->gc_lock);
-       bch2_trans_init(&trans, c, 0, 0);
 
        if (c->sb.version_upgrade_complete >= bcachefs_metadata_version_bucket_gens) {
                const struct bch_bucket_gens *g;
                u64 b;
 
-               for_each_btree_key(&trans, iter, BTREE_ID_bucket_gens, POS_MIN,
+               for_each_btree_key(trans, iter, BTREE_ID_bucket_gens, POS_MIN,
                                   BTREE_ITER_PREFETCH, k, ret) {
                        u64 start = bucket_gens_pos_to_alloc(k.k->p, 0).offset;
                        u64 end = bucket_gens_pos_to_alloc(bpos_nosnap_successor(k.k->p), 0).offset;
@@ -645,11 +642,11 @@ int bch2_alloc_read(struct bch_fs *c)
                             b++)
                                *bucket_gen(ca, b) = g->gens[b & KEY_TYPE_BUCKET_GENS_MASK];
                }
-               bch2_trans_iter_exit(&trans, &iter);
+               bch2_trans_iter_exit(trans, &iter);
        } else {
                struct bch_alloc_v4 a;
 
-               for_each_btree_key(&trans, iter, BTREE_ID_alloc, POS_MIN,
+               for_each_btree_key(trans, iter, BTREE_ID_alloc, POS_MIN,
                                   BTREE_ITER_PREFETCH, k, ret) {
                        /*
                         * Not a fsck error because this is checked/repaired by
@@ -662,10 +659,10 @@ int bch2_alloc_read(struct bch_fs *c)
 
                        *bucket_gen(ca, k.k->p.offset) = bch2_alloc_to_v4(k, &a)->gen;
                }
-               bch2_trans_iter_exit(&trans, &iter);
+               bch2_trans_iter_exit(trans, &iter);
        }
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        up_read(&c->gc_lock);
 
        if (ret)
@@ -1371,27 +1368,25 @@ fsck_err:
 
 int bch2_check_alloc_info(struct bch_fs *c)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter, discard_iter, freespace_iter, bucket_gens_iter;
        struct bkey hole;
        struct bkey_s_c k;
        int ret = 0;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_alloc, POS_MIN,
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_alloc, POS_MIN,
                             BTREE_ITER_PREFETCH);
-       bch2_trans_iter_init(&trans, &discard_iter, BTREE_ID_need_discard, POS_MIN,
+       bch2_trans_iter_init(trans, &discard_iter, BTREE_ID_need_discard, POS_MIN,
                             BTREE_ITER_PREFETCH);
-       bch2_trans_iter_init(&trans, &freespace_iter, BTREE_ID_freespace, POS_MIN,
+       bch2_trans_iter_init(trans, &freespace_iter, BTREE_ID_freespace, POS_MIN,
                             BTREE_ITER_PREFETCH);
-       bch2_trans_iter_init(&trans, &bucket_gens_iter, BTREE_ID_bucket_gens, POS_MIN,
+       bch2_trans_iter_init(trans, &bucket_gens_iter, BTREE_ID_bucket_gens, POS_MIN,
                             BTREE_ITER_PREFETCH);
 
        while (1) {
                struct bpos next;
 
-               bch2_trans_begin(&trans);
+               bch2_trans_begin(trans);
 
                k = bch2_get_key_or_real_bucket_hole(&iter, &hole);
                ret = bkey_err(k);
@@ -1404,7 +1399,7 @@ int bch2_check_alloc_info(struct bch_fs *c)
                if (k.k->type) {
                        next = bpos_nosnap_successor(k.k->p);
 
-                       ret = bch2_check_alloc_key(&trans,
+                       ret = bch2_check_alloc_key(trans,
                                                   k, &iter,
                                                   &discard_iter,
                                                   &freespace_iter,
@@ -1414,11 +1409,11 @@ int bch2_check_alloc_info(struct bch_fs *c)
                } else {
                        next = k.k->p;
 
-                       ret = bch2_check_alloc_hole_freespace(&trans,
+                       ret = bch2_check_alloc_hole_freespace(trans,
                                                    bkey_start_pos(k.k),
                                                    &next,
                                                    &freespace_iter) ?:
-                               bch2_check_alloc_hole_bucket_gens(&trans,
+                               bch2_check_alloc_hole_bucket_gens(trans,
                                                    bkey_start_pos(k.k),
                                                    &next,
                                                    &bucket_gens_iter);
@@ -1426,7 +1421,7 @@ int bch2_check_alloc_info(struct bch_fs *c)
                                goto bkey_err;
                }
 
-               ret = bch2_trans_commit(&trans, NULL, NULL,
+               ret = bch2_trans_commit(trans, NULL, NULL,
                                        BTREE_INSERT_NOFAIL|
                                        BTREE_INSERT_LAZY_RW);
                if (ret)
@@ -1439,29 +1434,29 @@ bkey_err:
                if (ret)
                        break;
        }
-       bch2_trans_iter_exit(&trans, &bucket_gens_iter);
-       bch2_trans_iter_exit(&trans, &freespace_iter);
-       bch2_trans_iter_exit(&trans, &discard_iter);
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &bucket_gens_iter);
+       bch2_trans_iter_exit(trans, &freespace_iter);
+       bch2_trans_iter_exit(trans, &discard_iter);
+       bch2_trans_iter_exit(trans, &iter);
 
        if (ret < 0)
                goto err;
 
-       ret = for_each_btree_key2(&trans, iter,
+       ret = for_each_btree_key2(trans, iter,
                        BTREE_ID_need_discard, POS_MIN,
                        BTREE_ITER_PREFETCH, k,
-               bch2_check_discard_freespace_key(&trans, &iter, k.k->p)) ?:
-             for_each_btree_key2(&trans, iter,
+               bch2_check_discard_freespace_key(trans, &iter, k.k->p)) ?:
+             for_each_btree_key2(trans, iter,
                        BTREE_ID_freespace, POS_MIN,
                        BTREE_ITER_PREFETCH, k,
-               bch2_check_discard_freespace_key(&trans, &iter, k.k->p)) ?:
-             for_each_btree_key_commit(&trans, iter,
+               bch2_check_discard_freespace_key(trans, &iter, k.k->p)) ?:
+             for_each_btree_key_commit(trans, iter,
                        BTREE_ID_bucket_gens, POS_MIN,
                        BTREE_ITER_PREFETCH, k,
                        NULL, NULL, BTREE_INSERT_NOFAIL|BTREE_INSERT_LAZY_RW,
-               bch2_check_bucket_gens_key(&trans, &iter, k));
+               bch2_check_bucket_gens_key(trans, &iter, k));
 err:
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        if (ret)
                bch_err_fn(c, ret);
        return ret;
@@ -1547,10 +1542,10 @@ int bch2_check_alloc_to_lru_refs(struct bch_fs *c)
        int ret = 0;
 
        ret = bch2_trans_run(c,
-               for_each_btree_key_commit(&trans, iter, BTREE_ID_alloc,
+               for_each_btree_key_commit(trans, iter, BTREE_ID_alloc,
                                POS_MIN, BTREE_ITER_PREFETCH, k,
                                NULL, NULL, BTREE_INSERT_NOFAIL|BTREE_INSERT_LAZY_RW,
-                       bch2_check_alloc_to_lru_ref(&trans, &iter)));
+                       bch2_check_alloc_to_lru_ref(trans, &iter)));
        if (ret)
                bch_err_fn(c, ret);
        return ret;
@@ -1675,29 +1670,25 @@ out:
 static void bch2_do_discards_work(struct work_struct *work)
 {
        struct bch_fs *c = container_of(work, struct bch_fs, discard_work);
-       struct btree_trans trans;
        struct btree_iter iter;
        struct bkey_s_c k;
        u64 seen = 0, open = 0, need_journal_commit = 0, discarded = 0;
        struct bpos discard_pos_done = POS_MAX;
        int ret;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
        /*
         * We're doing the commit in bch2_discard_one_bucket instead of using
         * for_each_btree_key_commit() so that we can increment counters after
         * successful commit:
         */
-       ret = for_each_btree_key2(&trans, iter,
-                       BTREE_ID_need_discard, POS_MIN, 0, k,
-               bch2_discard_one_bucket(&trans, &iter, &discard_pos_done,
-                                       &seen,
-                                       &open,
-                                       &need_journal_commit,
-                                       &discarded));
-
-       bch2_trans_exit(&trans);
+       ret = bch2_trans_run(c,
+               for_each_btree_key2(trans, iter,
+                               BTREE_ID_need_discard, POS_MIN, 0, k,
+                       bch2_discard_one_bucket(trans, &iter, &discard_pos_done,
+                                               &seen,
+                                               &open,
+                                               &need_journal_commit,
+                                               &discarded)));
 
        if (need_journal_commit * 2 > seen)
                bch2_journal_flush_async(&c->journal, NULL);
@@ -1803,15 +1794,13 @@ static void bch2_do_invalidates_work(struct work_struct *work)
 {
        struct bch_fs *c = container_of(work, struct bch_fs, invalidate_work);
        struct bch_dev *ca;
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        unsigned i;
        int ret = 0;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
-       ret = bch2_btree_write_buffer_flush(&trans);
+       ret = bch2_btree_write_buffer_flush(trans);
        if (ret)
                goto err;
 
@@ -1819,11 +1808,11 @@ static void bch2_do_invalidates_work(struct work_struct *work)
                s64 nr_to_invalidate =
                        should_invalidate_buckets(ca, bch2_dev_usage_read(ca));
 
-               ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_lru,
+               ret = for_each_btree_key2_upto(trans, iter, BTREE_ID_lru,
                                lru_pos(ca->dev_idx, 0, 0),
                                lru_pos(ca->dev_idx, U64_MAX, LRU_TIME_MAX),
                                BTREE_ITER_INTENT, k,
-                       invalidate_one_bucket(&trans, &iter, k, &nr_to_invalidate));
+                       invalidate_one_bucket(trans, &iter, k, &nr_to_invalidate));
 
                if (ret < 0) {
                        percpu_ref_put(&ca->ref);
@@ -1831,7 +1820,7 @@ static void bch2_do_invalidates_work(struct work_struct *work)
                }
        }
 err:
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        bch2_write_ref_put(c, BCH_WRITE_REF_invalidate);
 }
 
@@ -1845,7 +1834,7 @@ void bch2_do_invalidates(struct bch_fs *c)
 static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca,
                                   unsigned long *last_updated)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bkey hole;
@@ -1853,9 +1842,7 @@ static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca,
        struct bch_member *m;
        int ret;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_alloc,
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_alloc,
                             POS(ca->dev_idx, ca->mi.first_bucket),
                             BTREE_ITER_PREFETCH);
        /*
@@ -1869,7 +1856,7 @@ static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca,
                        *last_updated = jiffies;
                }
 
-               bch2_trans_begin(&trans);
+               bch2_trans_begin(trans);
 
                if (bkey_ge(iter.pos, end)) {
                        ret = 0;
@@ -1889,8 +1876,8 @@ static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca,
                        struct bch_alloc_v4 a_convert;
                        const struct bch_alloc_v4 *a = bch2_alloc_to_v4(k, &a_convert);
 
-                       ret =   bch2_bucket_do_index(&trans, k, a, true) ?:
-                               bch2_trans_commit(&trans, NULL, NULL,
+                       ret =   bch2_bucket_do_index(trans, k, a, true) ?:
+                               bch2_trans_commit(trans, NULL, NULL,
                                                  BTREE_INSERT_LAZY_RW|
                                                  BTREE_INSERT_NOFAIL);
                        if (ret)
@@ -1900,7 +1887,7 @@ static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca,
                } else {
                        struct bkey_i *freespace;
 
-                       freespace = bch2_trans_kmalloc(&trans, sizeof(*freespace));
+                       freespace = bch2_trans_kmalloc(trans, sizeof(*freespace));
                        ret = PTR_ERR_OR_ZERO(freespace);
                        if (ret)
                                goto bkey_err;
@@ -1910,8 +1897,8 @@ static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca,
                        freespace->k.p          = k.k->p;
                        freespace->k.size       = k.k->size;
 
-                       ret = bch2_btree_insert_trans(&trans, BTREE_ID_freespace, freespace, 0) ?:
-                               bch2_trans_commit(&trans, NULL, NULL,
+                       ret = bch2_btree_insert_trans(trans, BTREE_ID_freespace, freespace, 0) ?:
+                               bch2_trans_commit(trans, NULL, NULL,
                                                  BTREE_INSERT_LAZY_RW|
                                                  BTREE_INSERT_NOFAIL);
                        if (ret)
@@ -1926,8 +1913,8 @@ bkey_err:
                        break;
        }
 
-       bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_exit(trans, &iter);
+       bch2_trans_put(trans);
 
        if (ret < 0) {
                bch_err_msg(ca, ret, "initializing free space");
index e73b6c8..3bc4abd 100644 (file)
@@ -602,7 +602,7 @@ struct open_bucket *bch2_bucket_alloc(struct bch_fs *c, struct bch_dev *ca,
        struct open_bucket *ob;
 
        bch2_trans_do(c, NULL, NULL, 0,
-                     PTR_ERR_OR_ZERO(ob = bch2_bucket_alloc_trans(&trans, ca, watermark,
+                     PTR_ERR_OR_ZERO(ob = bch2_bucket_alloc_trans(trans, ca, watermark,
                                                        cl, &usage)));
        return ob;
 }
index 8210958..43defea 100644 (file)
@@ -390,10 +390,10 @@ int bch2_check_btree_backpointers(struct bch_fs *c)
        int ret;
 
        ret = bch2_trans_run(c,
-               for_each_btree_key_commit(&trans, iter,
+               for_each_btree_key_commit(trans, iter,
                        BTREE_ID_backpointers, POS_MIN, 0, k,
                        NULL, NULL, BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
-                 bch2_check_btree_backpointer(&trans, &iter, k)));
+                 bch2_check_btree_backpointer(trans, &iter, k)));
        if (ret)
                bch_err_fn(c, ret);
        return ret;
@@ -723,13 +723,12 @@ static int bch2_get_alloc_in_memory_pos(struct btree_trans *trans,
 
 int bch2_check_extents_to_backpointers(struct bch_fs *c)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct bpos start = POS_MIN, end;
        int ret;
 
-       bch2_trans_init(&trans, c, 0, 0);
        while (1) {
-               ret = bch2_get_alloc_in_memory_pos(&trans, start, &end);
+               ret = bch2_get_alloc_in_memory_pos(trans, start, &end);
                if (ret)
                        break;
 
@@ -749,13 +748,13 @@ int bch2_check_extents_to_backpointers(struct bch_fs *c)
                        printbuf_exit(&buf);
                }
 
-               ret = bch2_check_extents_to_backpointers_pass(&trans, start, end);
+               ret = bch2_check_extents_to_backpointers_pass(trans, start, end);
                if (ret || bpos_eq(end, SPOS_MAX))
                        break;
 
                start = bpos_successor(end);
        }
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        if (ret)
                bch_err_fn(c, ret);
@@ -824,13 +823,12 @@ static int bch2_check_backpointers_to_extents_pass(struct btree_trans *trans,
 
 int bch2_check_backpointers_to_extents(struct bch_fs *c)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct bbpos start = (struct bbpos) { .btree = 0, .pos = POS_MIN, }, end;
        int ret;
 
-       bch2_trans_init(&trans, c, 0, 0);
        while (1) {
-               ret = bch2_get_btree_in_memory_pos(&trans,
+               ret = bch2_get_btree_in_memory_pos(trans,
                                                   (1U << BTREE_ID_extents)|
                                                   (1U << BTREE_ID_reflink),
                                                   ~0,
@@ -856,13 +854,13 @@ int bch2_check_backpointers_to_extents(struct bch_fs *c)
                        printbuf_exit(&buf);
                }
 
-               ret = bch2_check_backpointers_to_extents_pass(&trans, start, end);
+               ret = bch2_check_backpointers_to_extents_pass(trans, start, end);
                if (ret || !bbpos_cmp(end, BBPOS_MAX))
                        break;
 
                start = bbpos_successor(end);
        }
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        if (ret)
                bch_err_fn(c, ret);
index 9fe3dac..ad18f3b 100644 (file)
@@ -627,8 +627,8 @@ struct journal_keys {
        size_t                  size;
 };
 
-struct btree_path_buf {
-       struct btree_path       *path;
+struct btree_trans_buf {
+       struct btree_trans      *trans;
 };
 
 #define REPLICAS_DELTA_LIST_MAX        (1U << 16)
@@ -787,9 +787,9 @@ struct bch_fs {
        /* btree_iter.c: */
        struct seqmutex         btree_trans_lock;
        struct list_head        btree_trans_list;
-       mempool_t               btree_paths_pool;
+       mempool_t               btree_trans_pool;
        mempool_t               btree_trans_mem_pool;
-       struct btree_path_buf  __percpu *btree_paths_bufs;
+       struct btree_trans_buf  __percpu        *btree_trans_bufs;
 
        struct srcu_struct      btree_trans_barrier;
        bool                    btree_trans_barrier_initialized;
index 9496ff1..693ed06 100644 (file)
@@ -529,13 +529,11 @@ fsck_err:
 
 int bch2_check_topology(struct bch_fs *c)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree *b;
        unsigned i;
        int ret = 0;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
        for (i = 0; i < btree_id_nr_alive(c) && !ret; i++) {
                struct btree_root *r = bch2_btree_id_root(c, i);
 
@@ -546,8 +544,8 @@ int bch2_check_topology(struct bch_fs *c)
                if (btree_node_fake(b))
                        continue;
 
-               btree_node_lock_nopath_nofail(&trans, &b->c, SIX_LOCK_read);
-               ret = bch2_btree_repair_topology_recurse(&trans, b);
+               btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read);
+               ret = bch2_btree_repair_topology_recurse(trans, b);
                six_unlock_read(&b->c.lock);
 
                if (ret == DROP_THIS_NODE) {
@@ -556,7 +554,7 @@ int bch2_check_topology(struct bch_fs *c)
                }
        }
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        return ret;
 }
@@ -1068,35 +1066,33 @@ static inline int btree_id_gc_phase_cmp(enum btree_id l, enum btree_id r)
 
 static int bch2_gc_btrees(struct bch_fs *c, bool initial, bool metadata_only)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        enum btree_id ids[BTREE_ID_NR];
        unsigned i;
        int ret = 0;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
        for (i = 0; i < BTREE_ID_NR; i++)
                ids[i] = i;
        bubble_sort(ids, BTREE_ID_NR, btree_id_gc_phase_cmp);
 
        for (i = 0; i < BTREE_ID_NR && !ret; i++)
                ret = initial
-                       ? bch2_gc_btree_init(&trans, ids[i], metadata_only)
-                       : bch2_gc_btree(&trans, ids[i], initial, metadata_only);
+                       ? bch2_gc_btree_init(trans, ids[i], metadata_only)
+                       : bch2_gc_btree(trans, ids[i], initial, metadata_only);
 
        for (i = BTREE_ID_NR; i < btree_id_nr_alive(c) && !ret; i++) {
                if (!bch2_btree_id_root(c, i)->alive)
                        continue;
 
                ret = initial
-                       ? bch2_gc_btree_init(&trans, i, metadata_only)
-                       : bch2_gc_btree(&trans, i, initial, metadata_only);
+                       ? bch2_gc_btree_init(trans, i, metadata_only)
+                       : bch2_gc_btree(trans, i, initial, metadata_only);
        }
 
        if (ret < 0)
                bch_err_fn(c, ret);
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        return ret;
 }
 
@@ -1458,21 +1454,19 @@ fsck_err:
 
 static int bch2_gc_alloc_done(struct bch_fs *c, bool metadata_only)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bch_dev *ca;
        unsigned i;
        int ret = 0;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
        for_each_member_device(ca, c, i) {
-               ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_alloc,
+               ret = for_each_btree_key_commit(trans, iter, BTREE_ID_alloc,
                                POS(ca->dev_idx, ca->mi.first_bucket),
                                BTREE_ITER_SLOTS|BTREE_ITER_PREFETCH, k,
                                NULL, NULL, BTREE_INSERT_LAZY_RW,
-                       bch2_alloc_write_key(&trans, &iter, k, metadata_only));
+                       bch2_alloc_write_key(trans, &iter, k, metadata_only));
 
                if (ret < 0) {
                        bch_err_fn(c, ret);
@@ -1481,14 +1475,14 @@ static int bch2_gc_alloc_done(struct bch_fs *c, bool metadata_only)
                }
        }
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        return ret < 0 ? ret : 0;
 }
 
 static int bch2_gc_alloc_start(struct bch_fs *c, bool metadata_only)
 {
        struct bch_dev *ca;
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bucket *g;
@@ -1504,7 +1498,8 @@ static int bch2_gc_alloc_start(struct bch_fs *c, bool metadata_only)
                if (!buckets) {
                        percpu_ref_put(&ca->ref);
                        bch_err(c, "error allocating ca->buckets[gc]");
-                       return -BCH_ERR_ENOMEM_gc_alloc_start;
+                       ret = -BCH_ERR_ENOMEM_gc_alloc_start;
+                       goto err;
                }
 
                buckets->first_bucket   = ca->mi.first_bucket;
@@ -1512,9 +1507,7 @@ static int bch2_gc_alloc_start(struct bch_fs *c, bool metadata_only)
                rcu_assign_pointer(ca->buckets_gc, buckets);
        }
 
-       bch2_trans_init(&trans, c, 0, 0);
-
-       for_each_btree_key(&trans, iter, BTREE_ID_alloc, POS_MIN,
+       for_each_btree_key(trans, iter, BTREE_ID_alloc, POS_MIN,
                           BTREE_ITER_PREFETCH, k, ret) {
                ca = bch_dev_bkey_exists(c, k.k->p.inode);
                g = gc_bucket(ca, k.k->p.offset);
@@ -1535,13 +1528,11 @@ static int bch2_gc_alloc_start(struct bch_fs *c, bool metadata_only)
                        g->stripe_redundancy    = a->stripe_redundancy;
                }
        }
-       bch2_trans_iter_exit(&trans, &iter);
-
-       bch2_trans_exit(&trans);
-
+       bch2_trans_iter_exit(trans, &iter);
+err:
+       bch2_trans_put(trans);
        if (ret)
                bch_err_fn(c, ret);
-
        return ret;
 }
 
@@ -1616,7 +1607,7 @@ fsck_err:
 
 static int bch2_gc_reflink_done(struct bch_fs *c, bool metadata_only)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter iter;
        struct bkey_s_c k;
        size_t idx = 0;
@@ -1625,23 +1616,23 @@ static int bch2_gc_reflink_done(struct bch_fs *c, bool metadata_only)
        if (metadata_only)
                return 0;
 
-       bch2_trans_init(&trans, c, 0, 0);
+       trans = bch2_trans_get(c);
 
-       ret = for_each_btree_key_commit(&trans, iter,
+       ret = for_each_btree_key_commit(trans, iter,
                        BTREE_ID_reflink, POS_MIN,
                        BTREE_ITER_PREFETCH, k,
                        NULL, NULL, BTREE_INSERT_NOFAIL,
-               bch2_gc_write_reflink_key(&trans, &iter, k, &idx));
+               bch2_gc_write_reflink_key(trans, &iter, k, &idx));
 
        c->reflink_gc_nr = 0;
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        return ret;
 }
 
 static int bch2_gc_reflink_start(struct bch_fs *c,
                                 bool metadata_only)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter iter;
        struct bkey_s_c k;
        struct reflink_gc *r;
@@ -1650,10 +1641,10 @@ static int bch2_gc_reflink_start(struct bch_fs *c,
        if (metadata_only)
                return 0;
 
-       bch2_trans_init(&trans, c, 0, 0);
+       trans = bch2_trans_get(c);
        c->reflink_gc_nr = 0;
 
-       for_each_btree_key(&trans, iter, BTREE_ID_reflink, POS_MIN,
+       for_each_btree_key(trans, iter, BTREE_ID_reflink, POS_MIN,
                           BTREE_ITER_PREFETCH, k, ret) {
                const __le64 *refcount = bkey_refcount_c(k);
 
@@ -1671,9 +1662,9 @@ static int bch2_gc_reflink_start(struct bch_fs *c,
                r->size         = k.k->size;
                r->refcount     = 0;
        }
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        return ret;
 }
 
@@ -1740,7 +1731,7 @@ fsck_err:
 
 static int bch2_gc_stripes_done(struct bch_fs *c, bool metadata_only)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter iter;
        struct bkey_s_c k;
        int ret = 0;
@@ -1748,15 +1739,15 @@ static int bch2_gc_stripes_done(struct bch_fs *c, bool metadata_only)
        if (metadata_only)
                return 0;
 
-       bch2_trans_init(&trans, c, 0, 0);
+       trans = bch2_trans_get(c);
 
-       ret = for_each_btree_key_commit(&trans, iter,
+       ret = for_each_btree_key_commit(trans, iter,
                        BTREE_ID_stripes, POS_MIN,
                        BTREE_ITER_PREFETCH, k,
                        NULL, NULL, BTREE_INSERT_NOFAIL,
-               bch2_gc_write_stripes_key(&trans, &iter, k));
+               bch2_gc_write_stripes_key(trans, &iter, k));
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        return ret;
 }
 
@@ -1942,7 +1933,7 @@ static int bch2_alloc_write_oldest_gen(struct btree_trans *trans, struct btree_i
 
 int bch2_gc_gens(struct bch_fs *c)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bch_dev *ca;
@@ -1960,7 +1951,7 @@ int bch2_gc_gens(struct bch_fs *c)
 
        trace_and_count(c, gc_gens_start, c);
        down_read(&c->gc_lock);
-       bch2_trans_init(&trans, c, 0, 0);
+       trans = bch2_trans_get(c);
 
        for_each_member_device(ca, c, i) {
                struct bucket_gens *gens;
@@ -1986,26 +1977,26 @@ int bch2_gc_gens(struct bch_fs *c)
                        c->gc_gens_btree = i;
                        c->gc_gens_pos = POS_MIN;
 
-                       ret = for_each_btree_key_commit(&trans, iter, i,
+                       ret = for_each_btree_key_commit(trans, iter, i,
                                        POS_MIN,
                                        BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS,
                                        k,
                                        NULL, NULL,
                                        BTREE_INSERT_NOFAIL,
-                               gc_btree_gens_key(&trans, &iter, k));
+                               gc_btree_gens_key(trans, &iter, k));
                        if (ret && !bch2_err_matches(ret, EROFS))
                                bch_err_fn(c, ret);
                        if (ret)
                                goto err;
                }
 
-       ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_alloc,
+       ret = for_each_btree_key_commit(trans, iter, BTREE_ID_alloc,
                        POS_MIN,
                        BTREE_ITER_PREFETCH,
                        k,
                        NULL, NULL,
                        BTREE_INSERT_NOFAIL,
-               bch2_alloc_write_oldest_gen(&trans, &iter, k));
+               bch2_alloc_write_oldest_gen(trans, &iter, k));
        if (ret && !bch2_err_matches(ret, EROFS))
                bch_err_fn(c, ret);
        if (ret)
@@ -2024,7 +2015,7 @@ err:
                ca->oldest_gen = NULL;
        }
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        up_read(&c->gc_lock);
        mutex_unlock(&c->gc_gens_lock);
        return ret;
index 9fa9ed6..a869cf6 100644 (file)
@@ -1628,8 +1628,7 @@ err:
 int bch2_btree_root_read(struct bch_fs *c, enum btree_id id,
                        const struct bkey_i *k, unsigned level)
 {
-       return bch2_trans_run(c, __bch2_btree_root_read(&trans, id, k, level));
-
+       return bch2_trans_run(c, __bch2_btree_root_read(trans, id, k, level));
 }
 
 void bch2_btree_complete_write(struct bch_fs *c, struct btree *b,
@@ -1691,15 +1690,13 @@ static void __btree_node_write_done(struct bch_fs *c, struct btree *b)
 
 static void btree_node_write_done(struct bch_fs *c, struct btree *b)
 {
-       struct btree_trans trans;
-
-       bch2_trans_init(&trans, c, 0, 0);
+       struct btree_trans *trans = bch2_trans_get(c);
 
-       btree_node_lock_nopath_nofail(&trans, &b->c, SIX_LOCK_read);
+       btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read);
        __btree_node_write_done(c, b);
        six_unlock_read(&b->c.lock);
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 }
 
 static void btree_node_write_work(struct work_struct *work)
@@ -1728,7 +1725,7 @@ static void btree_node_write_work(struct work_struct *work)
                }
        } else {
                ret = bch2_trans_do(c, NULL, NULL, 0,
-                       bch2_btree_node_update_key_get_iter(&trans, b, &wbio->key,
+                       bch2_btree_node_update_key_get_iter(trans, b, &wbio->key,
                                        BCH_WATERMARK_reclaim|
                                        BTREE_INSERT_JOURNAL_RECLAIM|
                                        BTREE_INSERT_NOFAIL|
index 6c064e8..1d79514 100644 (file)
@@ -2906,28 +2906,23 @@ u32 bch2_trans_begin(struct btree_trans *trans)
        return trans->restart_count;
 }
 
-static void bch2_trans_alloc_paths(struct btree_trans *trans, struct bch_fs *c)
+static struct btree_trans *bch2_trans_alloc(struct bch_fs *c)
 {
-       size_t paths_bytes      = sizeof(struct btree_path) * BTREE_ITER_MAX;
-       size_t updates_bytes    = sizeof(struct btree_insert_entry) * BTREE_ITER_MAX;
-       void *p = NULL;
+       struct btree_trans *trans;
 
-       BUG_ON(trans->used_mempool);
-
-#ifdef __KERNEL__
-       p = this_cpu_xchg(c->btree_paths_bufs->path, NULL);
-#endif
-       if (!p) {
-               p = mempool_alloc(&trans->c->btree_paths_pool, GFP_NOFS);
-               /*
-                * paths need to be zeroed, bch2_check_for_deadlock looks at
-                * paths in other threads
-                */
-               memset(p, 0, paths_bytes);
+       if (IS_ENABLED(__KERNEL__)) {
+               trans = this_cpu_xchg(c->btree_trans_bufs->trans, NULL);
+               if (trans)
+                       return trans;
        }
 
-       trans->paths            = p; p += paths_bytes;
-       trans->updates          = p; p += updates_bytes;
+       trans = mempool_alloc(&c->btree_trans_pool, GFP_NOFS);
+       /*
+        * paths need to be zeroed, bch2_check_for_deadlock looks at
+        * paths in other threads
+        */
+       memset(&trans->paths, 0, sizeof(trans->paths));
+       return trans;
 }
 
 const char *bch2_btree_transaction_fns[BCH_TRANSACTIONS_NR];
@@ -2947,11 +2942,14 @@ unsigned bch2_trans_get_fn_idx(const char *fn)
        return i;
 }
 
-void __bch2_trans_init(struct btree_trans *trans, struct bch_fs *c, unsigned fn_idx)
+struct btree_trans *__bch2_trans_get(struct bch_fs *c, unsigned fn_idx)
        __acquires(&c->btree_trans_barrier)
 {
+       struct btree_trans *trans;
        struct btree_transaction_stats *s;
 
+       trans = bch2_trans_alloc(c);
+
        memset(trans, 0, sizeof(*trans));
        trans->c                = c;
        trans->fn               = fn_idx < ARRAY_SIZE(bch2_btree_transaction_fns)
@@ -2963,8 +2961,6 @@ void __bch2_trans_init(struct btree_trans *trans, struct bch_fs *c, unsigned fn_
                !test_bit(JOURNAL_REPLAY_DONE, &c->journal.flags);
        closure_init_stack(&trans->ref);
 
-       bch2_trans_alloc_paths(trans, c);
-
        s = btree_trans_stats(trans);
        if (s && s->max_mem) {
                unsigned expected_mem_bytes = roundup_pow_of_two(s->max_mem);
@@ -3010,6 +3006,8 @@ void __bch2_trans_init(struct btree_trans *trans, struct bch_fs *c, unsigned fn_
 list_add_done:
                seqmutex_unlock(&c->btree_trans_lock);
        }
+
+       return trans;
 }
 
 static void check_btree_paths_leaked(struct btree_trans *trans)
@@ -3034,7 +3032,7 @@ leaked:
 #endif
 }
 
-void bch2_trans_exit(struct btree_trans *trans)
+void bch2_trans_put(struct btree_trans *trans)
        __releases(&c->btree_trans_barrier)
 {
        struct btree_insert_entry *i;
@@ -3080,18 +3078,11 @@ void bch2_trans_exit(struct btree_trans *trans)
        else
                kfree(trans->mem);
 
-#ifdef __KERNEL__
-       /*
-        * Userspace doesn't have a real percpu implementation:
-        */
-       trans->paths = this_cpu_xchg(c->btree_paths_bufs->path, trans->paths);
-#endif
-
-       if (trans->paths)
-               mempool_free(trans->paths, &c->btree_paths_pool);
-
-       trans->mem      = (void *) 0x1;
-       trans->paths    = (void *) 0x1;
+       /* Userspace doesn't have a real percpu implementation: */
+       if (IS_ENABLED(__KERNEL__))
+               trans = this_cpu_xchg(c->btree_trans_bufs->trans, trans);
+       if (trans)
+               mempool_free(trans, &c->btree_trans_pool);
 }
 
 static void __maybe_unused
@@ -3169,6 +3160,17 @@ void bch2_btree_trans_to_text(struct printbuf *out, struct btree_trans *trans)
 void bch2_fs_btree_iter_exit(struct bch_fs *c)
 {
        struct btree_transaction_stats *s;
+       struct btree_trans *trans;
+       int cpu;
+
+       trans = list_first_entry_or_null(&c->btree_trans_list, struct btree_trans, list);
+       if (trans)
+               panic("%s leaked btree_trans\n", trans->fn);
+
+       if (c->btree_trans_bufs)
+               for_each_possible_cpu(cpu)
+                       kfree(per_cpu_ptr(c->btree_trans_bufs, cpu)->trans);
+       free_percpu(c->btree_trans_bufs);
 
        for (s = c->btree_transaction_stats;
             s < c->btree_transaction_stats + ARRAY_SIZE(c->btree_transaction_stats);
@@ -3180,13 +3182,12 @@ void bch2_fs_btree_iter_exit(struct bch_fs *c)
        if (c->btree_trans_barrier_initialized)
                cleanup_srcu_struct(&c->btree_trans_barrier);
        mempool_exit(&c->btree_trans_mem_pool);
-       mempool_exit(&c->btree_paths_pool);
+       mempool_exit(&c->btree_trans_pool);
 }
 
 int bch2_fs_btree_iter_init(struct bch_fs *c)
 {
        struct btree_transaction_stats *s;
-       unsigned nr = BTREE_ITER_MAX;
        int ret;
 
        for (s = c->btree_transaction_stats;
@@ -3199,9 +3200,12 @@ int bch2_fs_btree_iter_init(struct bch_fs *c)
        INIT_LIST_HEAD(&c->btree_trans_list);
        seqmutex_init(&c->btree_trans_lock);
 
-       ret   = mempool_init_kmalloc_pool(&c->btree_paths_pool, 1,
-                       sizeof(struct btree_path) * nr +
-                       sizeof(struct btree_insert_entry) * nr) ?:
+       c->btree_trans_bufs = alloc_percpu(struct btree_trans_buf);
+       if (!c->btree_trans_bufs)
+               return -ENOMEM;
+
+       ret   = mempool_init_kmalloc_pool(&c->btree_trans_pool, 1,
+                                         sizeof(struct btree_trans)) ?:
                mempool_init_kmalloc_pool(&c->btree_trans_mem_pool, 1,
                                          BTREE_TRANS_MEM_MAX) ?:
                init_srcu_struct(&c->btree_trans_barrier);
index 360a26b..fbe2734 100644 (file)
@@ -915,21 +915,21 @@ void bch2_btree_path_to_text(struct printbuf *, struct btree_path *);
 void bch2_trans_paths_to_text(struct printbuf *, struct btree_trans *);
 void bch2_dump_trans_updates(struct btree_trans *);
 void bch2_dump_trans_paths_updates(struct btree_trans *);
-void __bch2_trans_init(struct btree_trans *, struct bch_fs *, unsigned);
-void bch2_trans_exit(struct btree_trans *);
+
+struct btree_trans *__bch2_trans_get(struct bch_fs *, unsigned);
+void bch2_trans_put(struct btree_trans *);
 
 extern const char *bch2_btree_transaction_fns[BCH_TRANSACTIONS_NR];
 unsigned bch2_trans_get_fn_idx(const char *);
 
-#define bch2_trans_init(_trans, _c, _nr_iters, _mem)                   \
-do {                                                                   \
+#define bch2_trans_get(_c)                                             \
+({                                                                     \
        static unsigned trans_fn_idx;                                   \
                                                                        \
        if (unlikely(!trans_fn_idx))                                    \
                trans_fn_idx = bch2_trans_get_fn_idx(__func__);         \
-                                                                       \
-       __bch2_trans_init(_trans, _c, trans_fn_idx);                    \
-} while (0)
+       __bch2_trans_get(_c, trans_fn_idx);                             \
+})
 
 void bch2_btree_trans_to_text(struct printbuf *, struct btree_trans *);
 
index 784f889..29a0b56 100644 (file)
@@ -704,13 +704,11 @@ int bch2_btree_key_cache_journal_flush(struct journal *j,
        struct bkey_cached *ck =
                container_of(pin, struct bkey_cached, journal);
        struct bkey_cached_key key;
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        int srcu_idx = srcu_read_lock(&c->btree_trans_barrier);
        int ret = 0;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
-       btree_node_lock_nopath_nofail(&trans, &ck->c, SIX_LOCK_read);
+       btree_node_lock_nopath_nofail(trans, &ck->c, SIX_LOCK_read);
        key = ck->key;
 
        if (ck->journal.seq != seq ||
@@ -727,13 +725,13 @@ int bch2_btree_key_cache_journal_flush(struct journal *j,
        }
        six_unlock_read(&ck->c.lock);
 
-       ret = commit_do(&trans, NULL, NULL, 0,
-               btree_key_cache_flush_pos(&trans, key, seq,
+       ret = commit_do(trans, NULL, NULL, 0,
+               btree_key_cache_flush_pos(trans, key, seq,
                                BTREE_INSERT_JOURNAL_RECLAIM, false));
 unlock:
        srcu_read_unlock(&c->btree_trans_barrier, srcu_idx);
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        return ret;
 }
 
index e3a0b10..183db5d 100644 (file)
@@ -163,13 +163,11 @@ static int __btree_node_flush(struct journal *j, struct journal_entry_pin *pin,
        struct bch_fs *c = container_of(j, struct bch_fs, journal);
        struct btree_write *w = container_of(pin, struct btree_write, journal);
        struct btree *b = container_of(w, struct btree, writes[i]);
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        unsigned long old, new, v;
        unsigned idx = w - b->writes;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
-       btree_node_lock_nopath_nofail(&trans, &b->c, SIX_LOCK_read);
+       btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read);
        v = READ_ONCE(b->flags);
 
        do {
@@ -188,7 +186,7 @@ static int __btree_node_flush(struct journal *j, struct journal_entry_pin *pin,
        btree_node_write_if_need(c, b, SIX_LOCK_read);
        six_unlock_read(&b->c.lock);
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        return 0;
 }
 
index 96a03f4..c9a38e2 100644 (file)
@@ -452,8 +452,8 @@ struct btree_trans {
        void                    *mem;
 
        u8                      sorted[BTREE_ITER_MAX + 8];
-       struct btree_path       *paths;
-       struct btree_insert_entry *updates;
+       struct btree_path       paths[BTREE_ITER_MAX];
+       struct btree_insert_entry updates[BTREE_ITER_MAX];
        struct btree_write_buffered_key *wb_updates;
 
        /* update path: */
index 3d126f0..3342718 100644 (file)
@@ -692,7 +692,7 @@ int bch2_btree_insert(struct bch_fs *c, enum btree_id id, struct bkey_i *k,
                      struct disk_reservation *disk_res, int flags)
 {
        return bch2_trans_do(c, disk_res, NULL, flags,
-                            bch2_btree_insert_trans(&trans, id, k, 0));
+                            bch2_btree_insert_trans(trans, id, k, 0));
 }
 
 int bch2_btree_delete_extent_at(struct btree_trans *trans, struct btree_iter *iter,
@@ -824,7 +824,7 @@ int bch2_btree_delete_range(struct bch_fs *c, enum btree_id id,
                            u64 *journal_seq)
 {
        int ret = bch2_trans_run(c,
-                       bch2_btree_delete_range_trans(&trans, id, start, end,
+                       bch2_btree_delete_range_trans(trans, id, start, end,
                                                      update_flags, journal_seq));
        if (ret == -BCH_ERR_transaction_restart_nested)
                ret = 0;
@@ -898,7 +898,7 @@ __bch2_fs_log_msg(struct bch_fs *c, unsigned commit_flags, const char *fmt,
        } else {
                ret = bch2_trans_do(c, NULL, NULL,
                        BTREE_INSERT_LAZY_RW|commit_flags,
-                       __bch2_trans_log_msg(&trans.extra_journal_entries, fmt, args));
+                       __bch2_trans_log_msg(&trans->extra_journal_entries, fmt, args));
        }
 
        return ret;
index 0be980d..4bfe602 100644 (file)
@@ -146,30 +146,17 @@ 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)                \
-({                                                                     \
-       struct btree_trans trans;                                       \
-       int _ret;                                                       \
-                                                                       \
-       bch2_trans_init(&trans, (_c), 0, 0);                            \
-       _ret = commit_do(&trans, _disk_res, _journal_seq, _flags, _do); \
-       bch2_trans_exit(&trans);                                        \
-                                                                       \
-       _ret;                                                           \
-})
-
 #define bch2_trans_run(_c, _do)                                                \
 ({                                                                     \
-       struct btree_trans trans;                                       \
-       int _ret;                                                       \
-                                                                       \
-       bch2_trans_init(&trans, (_c), 0, 0);                            \
-       _ret = (_do);                                                   \
-       bch2_trans_exit(&trans);                                        \
-                                                                       \
+       struct btree_trans *trans = bch2_trans_get(_c);                 \
+       int _ret = (_do);                                               \
+       bch2_trans_put(trans);                                          \
        _ret;                                                           \
 })
 
+#define bch2_trans_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)                              \
        for ((_i) = (_trans)->updates;                                  \
             (_i) < (_trans)->updates + (_trans)->nr_updates;           \
index bac495b..7dbf6b6 100644 (file)
@@ -597,12 +597,11 @@ static void btree_update_nodes_written(struct btree_update *as)
 {
        struct bch_fs *c = as->c;
        struct btree *b;
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        u64 journal_seq = 0;
        unsigned i;
        int ret;
 
-       bch2_trans_init(&trans, c, 0, 512);
        /*
         * If we're already in an error state, it might be because a btree node
         * was never written, and we might be trying to free that same btree
@@ -623,7 +622,7 @@ static void btree_update_nodes_written(struct btree_update *as)
 
                b = as->old_nodes[i];
 
-               btree_node_lock_nopath_nofail(&trans, &b->c, SIX_LOCK_read);
+               btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read);
                seq = b->data ? b->data->keys.seq : 0;
                six_unlock_read(&b->c.lock);
 
@@ -645,13 +644,13 @@ static void btree_update_nodes_written(struct btree_update *as)
         * journal reclaim does btree updates when flushing bkey_cached entries,
         * which may require allocations as well.
         */
-       ret = commit_do(&trans, &as->disk_res, &journal_seq,
+       ret = commit_do(trans, &as->disk_res, &journal_seq,
                        BCH_WATERMARK_reclaim|
                        BTREE_INSERT_NOFAIL|
                        BTREE_INSERT_NOCHECK_RW|
                        BTREE_INSERT_JOURNAL_RECLAIM,
-                       btree_update_nodes_written_trans(&trans, as));
-       bch2_trans_unlock(&trans);
+                       btree_update_nodes_written_trans(trans, as));
+       bch2_trans_unlock(trans);
 
        bch2_fs_fatal_err_on(ret && !bch2_journal_error(&c->journal), c,
                             "%s(): error %s", __func__, bch2_err_str(ret));
@@ -660,7 +659,7 @@ err:
                struct btree_path *path;
 
                b = as->b;
-               path = get_unlocked_mut_path(&trans, as->btree_id, b->c.level, b->key.k.p);
+               path = get_unlocked_mut_path(trans, as->btree_id, b->c.level, b->key.k.p);
                /*
                 * @b is the node we did the final insert into:
                 *
@@ -683,13 +682,13 @@ err:
                 * we may rarely end up with a locked path besides the one we
                 * have here:
                 */
-               bch2_trans_unlock(&trans);
-               btree_node_lock_nopath_nofail(&trans, &b->c, SIX_LOCK_intent);
-               mark_btree_node_locked(&trans, path, b->c.level, BTREE_NODE_INTENT_LOCKED);
+               bch2_trans_unlock(trans);
+               btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_intent);
+               mark_btree_node_locked(trans, path, b->c.level, BTREE_NODE_INTENT_LOCKED);
                path->l[b->c.level].lock_seq = six_lock_seq(&b->c.lock);
                path->l[b->c.level].b = b;
 
-               bch2_btree_node_lock_write_nofail(&trans, path, &b->c);
+               bch2_btree_node_lock_write_nofail(trans, path, &b->c);
 
                mutex_lock(&c->btree_interior_update_lock);
 
@@ -729,8 +728,8 @@ err:
                six_unlock_write(&b->c.lock);
 
                btree_node_write_if_need(c, b, SIX_LOCK_intent);
-               btree_node_unlock(&trans, path, b->c.level);
-               bch2_path_put(&trans, path, true);
+               btree_node_unlock(trans, path, b->c.level);
+               bch2_path_put(trans, path, true);
        }
 
        bch2_journal_pin_drop(&c->journal, &as->journal);
@@ -750,7 +749,7 @@ err:
        for (i = 0; i < as->nr_new_nodes; i++) {
                b = as->new_nodes[i];
 
-               btree_node_lock_nopath_nofail(&trans, &b->c, SIX_LOCK_read);
+               btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read);
                btree_node_write_if_need(c, b, SIX_LOCK_read);
                six_unlock_read(&b->c.lock);
        }
@@ -758,8 +757,8 @@ err:
        for (i = 0; i < as->nr_open_buckets; i++)
                bch2_open_bucket_put(c, c->open_buckets + as->open_buckets[i]);
 
-       bch2_btree_update_free(as, &trans);
-       bch2_trans_exit(&trans);
+       bch2_btree_update_free(as, trans);
+       bch2_trans_put(trans);
 }
 
 static void btree_interior_update_work(struct work_struct *work)
@@ -2049,7 +2048,7 @@ static void async_btree_node_rewrite_work(struct work_struct *work)
        int ret;
 
        ret = bch2_trans_do(c, NULL, NULL, 0,
-                     async_btree_node_rewrite_trans(&trans, a));
+                     async_btree_node_rewrite_trans(trans, a));
        if (ret)
                bch_err_fn(c, ret);
        bch2_write_ref_put(c, BCH_WRITE_REF_node_rewrite);
@@ -2365,7 +2364,7 @@ static int __bch2_btree_root_alloc(struct btree_trans *trans, enum btree_id id)
 
 void bch2_btree_root_alloc(struct bch_fs *c, enum btree_id id)
 {
-       bch2_trans_run(c, __bch2_btree_root_alloc(&trans, id));
+       bch2_trans_run(c, __bch2_btree_root_alloc(trans, id));
 }
 
 void bch2_btree_updates_to_text(struct printbuf *out, struct bch_fs *c)
index 6d2d43b..4e6241d 100644 (file)
@@ -296,7 +296,7 @@ static int bch2_btree_write_buffer_journal_flush(struct journal *j,
        mutex_lock(&wb->flush_lock);
 
        return bch2_trans_run(c,
-                       __bch2_btree_write_buffer_flush(&trans, BTREE_INSERT_NOCHECK_RW, true));
+                       __bch2_btree_write_buffer_flush(trans, BTREE_INSERT_NOCHECK_RW, true));
 }
 
 static inline u64 btree_write_buffer_ref(int idx)
index 78139f7..9941291 100644 (file)
@@ -1923,7 +1923,7 @@ static int __bch2_trans_mark_dev_sb(struct btree_trans *trans,
 
 int bch2_trans_mark_dev_sb(struct bch_fs *c, struct bch_dev *ca)
 {
-       int ret = bch2_trans_run(c, __bch2_trans_mark_dev_sb(&trans, ca));
+       int ret = bch2_trans_run(c, __bch2_trans_mark_dev_sb(trans, ca));
 
        if (ret)
                bch_err_fn(c, ret);
index 84ca128..899ff46 100644 (file)
@@ -303,7 +303,7 @@ out:
 
 int bch2_data_update_index_update(struct bch_write_op *op)
 {
-       return bch2_trans_run(op->c, __bch2_data_update_index_update(&trans, op));
+       return bch2_trans_run(op->c, __bch2_data_update_index_update(trans, op));
 }
 
 void bch2_data_update_read_done(struct data_update *m,
index 7593ba0..404148b 100644 (file)
@@ -366,7 +366,7 @@ static ssize_t bch2_read_btree(struct file *file, char __user *buf,
                               size_t size, loff_t *ppos)
 {
        struct dump_iter *i = file->private_data;
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter iter;
        struct bkey_s_c k;
        ssize_t ret;
@@ -379,17 +379,17 @@ static ssize_t bch2_read_btree(struct file *file, char __user *buf,
        if (ret)
                return ret;
 
-       bch2_trans_init(&trans, i->c, 0, 0);
-       ret = for_each_btree_key2(&trans, iter, i->id, i->from,
+       trans = bch2_trans_get(i->c);
+       ret = for_each_btree_key2(trans, iter, i->id, i->from,
                                  BTREE_ITER_PREFETCH|
                                  BTREE_ITER_ALL_SNAPSHOTS, k, ({
                bch2_bkey_val_to_text(&i->buf, i->c, k);
                prt_newline(&i->buf);
-               drop_locks_do(&trans, flush_buf(i));
+               drop_locks_do(trans, flush_buf(i));
        }));
        i->from = iter.pos;
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        if (!ret)
                ret = flush_buf(i);
@@ -408,7 +408,7 @@ static ssize_t bch2_read_btree_formats(struct file *file, char __user *buf,
                                       size_t size, loff_t *ppos)
 {
        struct dump_iter *i = file->private_data;
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter iter;
        struct btree *b;
        ssize_t ret;
@@ -424,26 +424,26 @@ static ssize_t bch2_read_btree_formats(struct file *file, char __user *buf,
        if (bpos_eq(SPOS_MAX, i->from))
                return i->ret;
 
-       bch2_trans_init(&trans, i->c, 0, 0);
+       trans = bch2_trans_get(i->c);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
 
-       for_each_btree_node(&trans, iter, i->id, i->from, 0, b, ret) {
+       for_each_btree_node(trans, iter, i->id, i->from, 0, b, ret) {
                bch2_btree_node_to_text(&i->buf, i->c, b);
                i->from = !bpos_eq(SPOS_MAX, b->key.k.p)
                        ? bpos_successor(b->key.k.p)
                        : b->key.k.p;
 
-               ret = drop_locks_do(&trans, flush_buf(i));
+               ret = drop_locks_do(trans, flush_buf(i));
                if (ret)
                        break;
        }
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        if (!ret)
                ret = flush_buf(i);
@@ -462,7 +462,7 @@ static ssize_t bch2_read_bfloat_failed(struct file *file, char __user *buf,
                                       size_t size, loff_t *ppos)
 {
        struct dump_iter *i = file->private_data;
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter iter;
        struct bkey_s_c k;
        ssize_t ret;
@@ -475,9 +475,9 @@ static ssize_t bch2_read_bfloat_failed(struct file *file, char __user *buf,
        if (ret)
                return ret;
 
-       bch2_trans_init(&trans, i->c, 0, 0);
+       trans = bch2_trans_get(i->c);
 
-       ret = for_each_btree_key2(&trans, iter, i->id, i->from,
+       ret = for_each_btree_key2(trans, iter, i->id, i->from,
                                  BTREE_ITER_PREFETCH|
                                  BTREE_ITER_ALL_SNAPSHOTS, k, ({
                struct btree_path_level *l = &iter.path->l[0];
@@ -490,11 +490,11 @@ static ssize_t bch2_read_bfloat_failed(struct file *file, char __user *buf,
                }
 
                bch2_bfloat_to_text(&i->buf, l->b, _k);
-               drop_locks_do(&trans, flush_buf(i));
+               drop_locks_do(trans, flush_buf(i));
        }));
        i->from = iter.pos;
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        if (!ret)
                ret = flush_buf(i);
index a7559ab..6c6c8d5 100644 (file)
@@ -479,21 +479,19 @@ u64 bch2_dirent_lookup(struct bch_fs *c, subvol_inum dir,
                       const struct bch_hash_info *hash_info,
                       const struct qstr *name, subvol_inum *inum)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        int ret;
-
-       bch2_trans_init(&trans, c, 0, 0);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
 
-       ret = __bch2_dirent_lookup_trans(&trans, &iter, dir, hash_info,
+       ret = __bch2_dirent_lookup_trans(trans, &iter, dir, hash_info,
                                          name, inum, 0);
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
        if (!ret)
-               bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
+               bch2_trans_iter_exit(trans, &iter);
+       bch2_trans_put(trans);
        return ret;
 }
 
@@ -522,7 +520,7 @@ int bch2_empty_dir_trans(struct btree_trans *trans, subvol_inum dir)
 
 int bch2_readdir(struct bch_fs *c, subvol_inum inum, struct dir_context *ctx)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bkey_s_c_dirent dirent;
@@ -533,15 +531,14 @@ int bch2_readdir(struct bch_fs *c, subvol_inum inum, struct dir_context *ctx)
        int ret;
 
        bch2_bkey_buf_init(&sk);
-       bch2_trans_init(&trans, c, 0, 0);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
 
-       ret = bch2_subvolume_get_snapshot(&trans, inum.subvol, &snapshot);
+       ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
        if (ret)
                goto err;
 
-       for_each_btree_key_upto_norestart(&trans, iter, BTREE_ID_dirents,
+       for_each_btree_key_upto_norestart(trans, iter, BTREE_ID_dirents,
                           SPOS(inum.inum, ctx->pos, snapshot),
                           POS(inum.inum, U64_MAX), 0, k, ret) {
                if (k.k->type != KEY_TYPE_dirent)
@@ -549,7 +546,7 @@ retry:
 
                dirent = bkey_s_c_to_dirent(k);
 
-               ret = bch2_dirent_read_target(&trans, inum, dirent, &target);
+               ret = bch2_dirent_read_target(trans, inum, dirent, &target);
                if (ret < 0)
                        break;
                if (ret)
@@ -558,7 +555,7 @@ retry:
                /* dir_emit() can fault and block: */
                bch2_bkey_buf_reassemble(&sk, c, k);
                dirent = bkey_i_to_s_c_dirent(sk.k);
-               bch2_trans_unlock(&trans);
+               bch2_trans_unlock(trans);
 
                name = bch2_dirent_get_name(dirent);
 
@@ -574,16 +571,16 @@ retry:
                 * read_target looks up subvolumes, we can overflow paths if the
                 * directory has many subvolumes in it
                 */
-               ret = btree_trans_too_many_iters(&trans);
+               ret = btree_trans_too_many_iters(trans);
                if (ret)
                        break;
        }
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 err:
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        bch2_bkey_buf_exit(&sk, c);
 
        return ret;
index 40e72b9..8646856 100644 (file)
@@ -476,7 +476,7 @@ err:
 
 static int get_stripe_key(struct bch_fs *c, u64 idx, struct ec_stripe_buf *stripe)
 {
-       return bch2_trans_run(c, get_stripe_key_trans(&trans, idx, stripe));
+       return bch2_trans_run(c, get_stripe_key_trans(trans, idx, stripe));
 }
 
 /* recovery read path: */
@@ -788,12 +788,10 @@ static void ec_stripe_delete_work(struct work_struct *work)
 {
        struct bch_fs *c =
                container_of(work, struct bch_fs, ec_stripe_delete_work);
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        int ret;
        u64 idx;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
        while (1) {
                mutex_lock(&c->ec_stripes_heap_lock);
                idx = stripe_idx_to_delete(c);
@@ -802,15 +800,15 @@ static void ec_stripe_delete_work(struct work_struct *work)
                if (!idx)
                        break;
 
-               ret = commit_do(&trans, NULL, NULL, BTREE_INSERT_NOFAIL,
-                               ec_stripe_delete(&trans, idx));
+               ret = commit_do(trans, NULL, NULL, BTREE_INSERT_NOFAIL,
+                               ec_stripe_delete(trans, idx));
                if (ret) {
                        bch_err_fn(c, ret);
                        break;
                }
        }
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        bch2_write_ref_put(c, BCH_WRITE_REF_stripe_delete);
 }
@@ -999,24 +997,22 @@ static int ec_stripe_update_bucket(struct btree_trans *trans, struct ec_stripe_b
 
 static int ec_stripe_update_extents(struct bch_fs *c, struct ec_stripe_buf *s)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct bch_stripe *v = &bkey_i_to_stripe(&s->key)->v;
        unsigned i, nr_data = v->nr_blocks - v->nr_redundant;
        int ret = 0;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
-       ret = bch2_btree_write_buffer_flush(&trans);
+       ret = bch2_btree_write_buffer_flush(trans);
        if (ret)
                goto err;
 
        for (i = 0; i < nr_data; i++) {
-               ret = ec_stripe_update_bucket(&trans, s, i);
+               ret = ec_stripe_update_bucket(trans, s, i);
                if (ret)
                        break;
        }
 err:
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        return ret;
 }
@@ -1124,7 +1120,7 @@ static void ec_stripe_create(struct ec_stripe_new *s)
        ret = bch2_trans_do(c, &s->res, NULL,
                            BTREE_INSERT_NOCHECK_RW|
                            BTREE_INSERT_NOFAIL,
-                           ec_stripe_key_update(&trans,
+                           ec_stripe_key_update(trans,
                                        bkey_i_to_stripe(&s->new_stripe.key),
                                        !s->have_existing_stripe));
        if (ret) {
@@ -1822,7 +1818,7 @@ void bch2_fs_ec_flush(struct bch_fs *c)
 
 int bch2_stripes_read(struct bch_fs *c)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        const struct bch_stripe *s;
@@ -1830,9 +1826,7 @@ int bch2_stripes_read(struct bch_fs *c)
        unsigned i;
        int ret;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
-       for_each_btree_key(&trans, iter, BTREE_ID_stripes, POS_MIN,
+       for_each_btree_key(trans, iter, BTREE_ID_stripes, POS_MIN,
                           BTREE_ITER_PREFETCH, k, ret) {
                if (k.k->type != KEY_TYPE_stripe)
                        continue;
@@ -1855,9 +1849,9 @@ int bch2_stripes_read(struct bch_fs *c)
 
                bch2_stripes_heap_insert(c, m, k.k->p.offset);
        }
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        if (ret)
                bch_err_fn(c, ret);
index 7650d8b..58ccc7b 100644 (file)
@@ -270,7 +270,7 @@ void bch2_readahead(struct readahead_control *ractl)
        struct bch_inode_info *inode = to_bch_ei(ractl->mapping->host);
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
        struct bch_io_opts opts;
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct folio *folio;
        struct readpages_iter readpages_iter;
        int ret;
@@ -280,8 +280,6 @@ void bch2_readahead(struct readahead_control *ractl)
        ret = readpages_iter_init(&readpages_iter, ractl);
        BUG_ON(ret);
 
-       bch2_trans_init(&trans, c, 0, 0);
-
        bch2_pagecache_add_get(inode);
 
        while ((folio = readpage_iter_peek(&readpages_iter))) {
@@ -300,31 +298,27 @@ void bch2_readahead(struct readahead_control *ractl)
                rbio->bio.bi_end_io = bch2_readpages_end_io;
                BUG_ON(!bio_add_folio(&rbio->bio, folio, folio_size(folio), 0));
 
-               bchfs_read(&trans, rbio, inode_inum(inode),
+               bchfs_read(trans, rbio, inode_inum(inode),
                           &readpages_iter);
-               bch2_trans_unlock(&trans);
+               bch2_trans_unlock(trans);
        }
 
        bch2_pagecache_add_put(inode);
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        darray_exit(&readpages_iter.folios);
 }
 
 static void __bchfs_readfolio(struct bch_fs *c, struct bch_read_bio *rbio,
                             subvol_inum inum, struct folio *folio)
 {
-       struct btree_trans trans;
-
        bch2_folio_create(folio, __GFP_NOFAIL);
 
        rbio->bio.bi_opf = REQ_OP_READ|REQ_SYNC;
        rbio->bio.bi_iter.bi_sector = folio_sector(folio);
        BUG_ON(!bio_add_folio(&rbio->bio, folio, folio_size(folio), 0));
 
-       bch2_trans_init(&trans, c, 0, 0);
-       bchfs_read(&trans, rbio, inum, NULL);
-       bch2_trans_exit(&trans);
+       bch2_trans_run(c, (bchfs_read(trans, rbio, inum, NULL), 0));
 }
 
 static void bch2_read_single_folio_end_io(struct bio *bio)
index 4c61cb1..6a9557e 100644 (file)
@@ -234,23 +234,21 @@ static bool bch2_check_range_allocated(struct bch_fs *c, subvol_inum inum,
                                       u64 offset, u64 size,
                                       unsigned nr_replicas, bool compressed)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        u64 end = offset + size;
        u32 snapshot;
        bool ret = true;
        int err;
-
-       bch2_trans_init(&trans, c, 0, 0);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
 
-       err = bch2_subvolume_get_snapshot(&trans, inum.subvol, &snapshot);
+       err = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
        if (err)
                goto err;
 
-       for_each_btree_key_norestart(&trans, iter, BTREE_ID_extents,
+       for_each_btree_key_norestart(trans, iter, BTREE_ID_extents,
                           SPOS(inum.inum, offset, snapshot),
                           BTREE_ITER_SLOTS, k, err) {
                if (bkey_ge(bkey_start_pos(k.k), POS(inum.inum, end)))
@@ -265,11 +263,11 @@ retry:
        }
 
        offset = iter.pos.offset;
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 err:
        if (bch2_err_matches(err, BCH_ERR_transaction_restart))
                goto retry;
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        return err ? false : ret;
 }
index 4d1612e..8bd9bcd 100644 (file)
@@ -182,7 +182,7 @@ static void __bch2_folio_set(struct folio *folio,
 int bch2_folio_set(struct bch_fs *c, subvol_inum inum,
                   struct folio **fs, unsigned nr_folios)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bch_folio *s;
@@ -204,15 +204,15 @@ int bch2_folio_set(struct bch_fs *c, subvol_inum inum,
                return 0;
 
        folio_idx = 0;
-       bch2_trans_init(&trans, c, 0, 0);
+       trans = bch2_trans_get(c);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
 
-       ret = bch2_subvolume_get_snapshot(&trans, inum.subvol, &snapshot);
+       ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
        if (ret)
                goto err;
 
-       for_each_btree_key_norestart(&trans, iter, BTREE_ID_extents,
+       for_each_btree_key_norestart(trans, iter, BTREE_ID_extents,
                           SPOS(inum.inum, offset, snapshot),
                           BTREE_ITER_SLOTS, k, ret) {
                unsigned nr_ptrs = bch2_bkey_nr_ptrs_fully_allocated(k);
@@ -243,11 +243,11 @@ retry:
        }
 
        offset = iter.pos.offset;
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 err:
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        return ret;
 }
index ffe9206..b0e8144 100644 (file)
@@ -207,31 +207,29 @@ static inline int range_has_data(struct bch_fs *c, u32 subvol,
                                 struct bpos start,
                                 struct bpos end)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        int ret = 0;
-
-       bch2_trans_init(&trans, c, 0, 0);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
 
-       ret = bch2_subvolume_get_snapshot(&trans, subvol, &start.snapshot);
+       ret = bch2_subvolume_get_snapshot(trans, subvol, &start.snapshot);
        if (ret)
                goto err;
 
-       for_each_btree_key_upto_norestart(&trans, iter, BTREE_ID_extents, start, end, 0, k, ret)
+       for_each_btree_key_upto_norestart(trans, iter, BTREE_ID_extents, start, end, 0, k, ret)
                if (bkey_extent_is_data(k.k) && !bkey_extent_is_unwritten(k)) {
                        ret = 1;
                        break;
                }
        start = iter.pos;
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 err:
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        return ret;
 }
 
@@ -582,16 +580,15 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
                             u64 start_sector, u64 end_sector)
 {
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bpos end_pos = POS(inode->v.i_ino, end_sector);
        struct bch_io_opts opts;
        int ret = 0;
 
        bch2_inode_opts_get(&opts, c, &inode->ei_inode);
-       bch2_trans_init(&trans, c, BTREE_ITER_MAX, 512);
 
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
                        POS(inode->v.i_ino, start_sector),
                        BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
 
@@ -604,9 +601,9 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
                u64 hole_start, hole_end;
                u32 snapshot;
 
-               bch2_trans_begin(&trans);
+               bch2_trans_begin(trans);
 
-               ret = bch2_subvolume_get_snapshot(&trans,
+               ret = bch2_subvolume_get_snapshot(trans,
                                        inode->ei_subvol, &snapshot);
                if (ret)
                        goto bkey_err;
@@ -643,7 +640,7 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
                                                 &hole_start,
                                                 &hole_end,
                                                 opts.data_replicas, true))
-                               ret = drop_locks_do(&trans,
+                               ret = drop_locks_do(trans,
                                        (bch2_clamp_data_hole(&inode->v,
                                                              &hole_start,
                                                              &hole_end,
@@ -666,7 +663,7 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
                                goto bkey_err;
                }
 
-               ret = bch2_extent_fallocate(&trans, inode_inum(inode), &iter,
+               ret = bch2_extent_fallocate(trans, inode_inum(inode), &iter,
                                            sectors, opts, &i_sectors_delta,
                                            writepoint_hashed((unsigned long) current));
                if (ret)
@@ -674,7 +671,7 @@ static int __bchfs_fallocate(struct bch_inode_info *inode, int mode,
 
                bch2_i_sectors_acct(c, inode, &quota_res, i_sectors_delta);
 
-               drop_locks_do(&trans,
+               drop_locks_do(trans,
                        (bch2_mark_pagecache_reserved(inode, hole_start, iter.pos.offset), 0));
 bkey_err:
                bch2_quota_reservation_put(c, inode, &quota_res);
@@ -686,14 +683,14 @@ bkey_err:
                struct quota_res quota_res = { 0 };
                s64 i_sectors_delta = 0;
 
-               bch2_fpunch_at(&trans, &iter, inode_inum(inode),
+               bch2_fpunch_at(trans, &iter, inode_inum(inode),
                               end_sector, &i_sectors_delta);
                bch2_i_sectors_acct(c, inode, &quota_res, i_sectors_delta);
                bch2_quota_reservation_put(c, inode, &quota_res);
        }
 
-       bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_exit(trans, &iter);
+       bch2_trans_put(trans);
        return ret;
 }
 
@@ -799,26 +796,24 @@ static int quota_reserve_range(struct bch_inode_info *inode,
                               u64 start, u64 end)
 {
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        u32 snapshot;
        u64 sectors = end - start;
        u64 pos = start;
        int ret;
-
-       bch2_trans_init(&trans, c, 0, 0);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
 
-       ret = bch2_subvolume_get_snapshot(&trans, inode->ei_subvol, &snapshot);
+       ret = bch2_subvolume_get_snapshot(trans, inode->ei_subvol, &snapshot);
        if (ret)
                goto err;
 
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
                             SPOS(inode->v.i_ino, pos, snapshot), 0);
 
-       while (!(ret = btree_trans_too_many_iters(&trans)) &&
+       while (!(ret = btree_trans_too_many_iters(trans)) &&
               (k = bch2_btree_iter_peek_upto(&iter, POS(inode->v.i_ino, end - 1))).k &&
               !(ret = bkey_err(k))) {
                if (bkey_extent_is_allocation(k.k)) {
@@ -830,17 +825,14 @@ retry:
                bch2_btree_iter_advance(&iter);
        }
        pos = iter.pos.offset;
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 err:
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
 
-       bch2_trans_exit(&trans);
-
-       if (ret)
-               return ret;
+       bch2_trans_put(trans);
 
-       return bch2_quota_reservation_add(c, inode, res, sectors, true);
+       return ret ?: bch2_quota_reservation_add(c, inode, res, sectors, true);
 }
 
 loff_t bch2_remap_file_range(struct file *file_src, loff_t pos_src,
@@ -933,7 +925,7 @@ static loff_t bch2_seek_data(struct file *file, u64 offset)
 {
        struct bch_inode_info *inode = file_bch_inode(file);
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter iter;
        struct bkey_s_c k;
        subvol_inum inum = inode_inum(inode);
@@ -945,15 +937,15 @@ static loff_t bch2_seek_data(struct file *file, u64 offset)
        if (offset >= isize)
                return -ENXIO;
 
-       bch2_trans_init(&trans, c, 0, 0);
+       trans = bch2_trans_get(c);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
 
-       ret = bch2_subvolume_get_snapshot(&trans, inum.subvol, &snapshot);
+       ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
        if (ret)
                goto err;
 
-       for_each_btree_key_upto_norestart(&trans, iter, BTREE_ID_extents,
+       for_each_btree_key_upto_norestart(trans, iter, BTREE_ID_extents,
                           SPOS(inode->v.i_ino, offset >> 9, snapshot),
                           POS(inode->v.i_ino, U64_MAX),
                           0, k, ret) {
@@ -963,12 +955,12 @@ retry:
                } else if (k.k->p.offset >> 9 > isize)
                        break;
        }
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 err:
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        if (ret)
                return ret;
 
@@ -986,7 +978,7 @@ static loff_t bch2_seek_hole(struct file *file, u64 offset)
 {
        struct bch_inode_info *inode = file_bch_inode(file);
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter iter;
        struct bkey_s_c k;
        subvol_inum inum = inode_inum(inode);
@@ -998,15 +990,15 @@ static loff_t bch2_seek_hole(struct file *file, u64 offset)
        if (offset >= isize)
                return -ENXIO;
 
-       bch2_trans_init(&trans, c, 0, 0);
+       trans = bch2_trans_get(c);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
 
-       ret = bch2_subvolume_get_snapshot(&trans, inum.subvol, &snapshot);
+       ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
        if (ret)
                goto err;
 
-       for_each_btree_key_norestart(&trans, iter, BTREE_ID_extents,
+       for_each_btree_key_norestart(trans, iter, BTREE_ID_extents,
                           SPOS(inode->v.i_ino, offset >> 9, snapshot),
                           BTREE_ITER_SLOTS, k, ret) {
                if (k.k->p.inode != inode->v.i_ino) {
@@ -1024,12 +1016,12 @@ retry:
                        offset = max(offset, bkey_start_offset(k.k) << 9);
                }
        }
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 err:
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        if (ret)
                return ret;
 
index f814e9e..bfbd4f0 100644 (file)
@@ -82,29 +82,27 @@ int __must_check bch2_write_inode(struct bch_fs *c,
                                  inode_set_fn set,
                                  void *p, unsigned fields)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter = { NULL };
        struct bch_inode_unpacked inode_u;
        int ret;
-
-       bch2_trans_init(&trans, c, 0, 512);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
 
-       ret   = bch2_inode_peek(&trans, &iter, &inode_u, inode_inum(inode),
+       ret   = bch2_inode_peek(trans, &iter, &inode_u, inode_inum(inode),
                                BTREE_ITER_INTENT) ?:
-               (set ? set(&trans, inode, &inode_u, p) : 0) ?:
-               bch2_inode_write(&trans, &iter, &inode_u) ?:
-               bch2_trans_commit(&trans, NULL, NULL, BTREE_INSERT_NOFAIL);
+               (set ? set(trans, inode, &inode_u, p) : 0) ?:
+               bch2_inode_write(trans, &iter, &inode_u) ?:
+               bch2_trans_commit(trans, NULL, NULL, BTREE_INSERT_NOFAIL);
 
        /*
         * the btree node lock protects inode->ei_inode, not ei_update_lock;
         * this is important for inode updates via bchfs_write_index_update
         */
        if (!ret)
-               bch2_inode_update_after_write(&trans, inode, &inode_u, fields);
+               bch2_inode_update_after_write(trans, inode, &inode_u, fields);
 
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
@@ -114,7 +112,7 @@ retry:
                             inode_inum(inode).subvol,
                             inode_inum(inode).inum);
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        return ret < 0 ? ret : 0;
 }
 
@@ -182,7 +180,7 @@ struct inode *bch2_vfs_inode_get(struct bch_fs *c, subvol_inum inum)
 {
        struct bch_inode_unpacked inode_u;
        struct bch_inode_info *inode;
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct bch_subvolume subvol;
        int ret;
 
@@ -196,14 +194,14 @@ struct inode *bch2_vfs_inode_get(struct bch_fs *c, subvol_inum inum)
        if (!(inode->v.i_state & I_NEW))
                return &inode->v;
 
-       bch2_trans_init(&trans, c, 8, 0);
-       ret = lockrestart_do(&trans,
-               bch2_subvolume_get(&trans, inum.subvol, true, 0, &subvol) ?:
-               bch2_inode_find_by_inum_trans(&trans, inum, &inode_u));
+       trans = bch2_trans_get(c);
+       ret = lockrestart_do(trans,
+               bch2_subvolume_get(trans, inum.subvol, true, 0, &subvol) ?:
+               bch2_inode_find_by_inum_trans(trans, inum, &inode_u));
 
        if (!ret)
-               bch2_vfs_inode_init(&trans, inum, inode, &inode_u, &subvol);
-       bch2_trans_exit(&trans);
+               bch2_vfs_inode_init(trans, inum, inode, &inode_u, &subvol);
+       bch2_trans_put(trans);
 
        if (ret) {
                iget_failed(&inode->v);
@@ -226,7 +224,7 @@ __bch2_create(struct mnt_idmap *idmap,
              unsigned flags)
 {
        struct bch_fs *c = dir->v.i_sb->s_fs_info;
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct bch_inode_unpacked dir_u;
        struct bch_inode_info *inode, *old;
        struct bch_inode_unpacked inode_u;
@@ -256,13 +254,11 @@ __bch2_create(struct mnt_idmap *idmap,
        if (!(flags & BCH_CREATE_TMPFILE))
                mutex_lock(&dir->ei_update_lock);
 
-       bch2_trans_init(&trans, c, 8,
-                       2048 + (!(flags & BCH_CREATE_TMPFILE)
-                               ? dentry->d_name.len : 0));
+       trans = bch2_trans_get(c);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
 
-       ret   = bch2_create_trans(&trans,
+       ret   = bch2_create_trans(trans,
                                  inode_inum(dir), &dir_u, &inode_u,
                                  !(flags & BCH_CREATE_TMPFILE)
                                  ? &dentry->d_name : NULL,
@@ -278,9 +274,9 @@ retry:
        inum.subvol = inode_u.bi_subvol ?: dir->ei_subvol;
        inum.inum = inode_u.bi_inum;
 
-       ret   = bch2_subvolume_get(&trans, inum.subvol, true,
+       ret   = bch2_subvolume_get(trans, inum.subvol, true,
                                   BTREE_ITER_WITH_UPDATES, &subvol) ?:
-               bch2_trans_commit(&trans, NULL, &journal_seq, 0);
+               bch2_trans_commit(trans, NULL, &journal_seq, 0);
        if (unlikely(ret)) {
                bch2_quota_acct(c, bch_qid(&inode_u), Q_INO, -1,
                                KEY_TYPE_QUOTA_WARN);
@@ -291,13 +287,13 @@ err_before_quota:
        }
 
        if (!(flags & BCH_CREATE_TMPFILE)) {
-               bch2_inode_update_after_write(&trans, dir, &dir_u,
+               bch2_inode_update_after_write(trans, dir, &dir_u,
                                              ATTR_MTIME|ATTR_CTIME);
                mutex_unlock(&dir->ei_update_lock);
        }
 
        bch2_iget5_set(&inode->v, &inum);
-       bch2_vfs_inode_init(&trans, inum, inode, &inode_u, &subvol);
+       bch2_vfs_inode_init(trans, inum, inode, &inode_u, &subvol);
 
        set_cached_acl(&inode->v, ACL_TYPE_ACCESS, acl);
        set_cached_acl(&inode->v, ACL_TYPE_DEFAULT, default_acl);
@@ -337,7 +333,7 @@ err_before_quota:
                unlock_new_inode(&inode->v);
        }
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 err:
        posix_acl_release(default_acl);
        posix_acl_release(acl);
@@ -346,7 +342,7 @@ err_trans:
        if (!(flags & BCH_CREATE_TMPFILE))
                mutex_unlock(&dir->ei_update_lock);
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        make_bad_inode(&inode->v);
        iput(&inode->v);
        inode = ERR_PTR(ret);
@@ -401,26 +397,25 @@ static int __bch2_link(struct bch_fs *c,
                       struct bch_inode_info *dir,
                       struct dentry *dentry)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct bch_inode_unpacked dir_u, inode_u;
        int ret;
 
        mutex_lock(&inode->ei_update_lock);
-       bch2_trans_init(&trans, c, 4, 1024);
 
-       ret = commit_do(&trans, NULL, NULL, 0,
-                       bch2_link_trans(&trans,
+       ret = commit_do(trans, NULL, NULL, 0,
+                       bch2_link_trans(trans,
                                        inode_inum(dir),   &dir_u,
                                        inode_inum(inode), &inode_u,
                                        &dentry->d_name));
 
        if (likely(!ret)) {
-               bch2_inode_update_after_write(&trans, dir, &dir_u,
+               bch2_inode_update_after_write(trans, dir, &dir_u,
                                              ATTR_MTIME|ATTR_CTIME);
-               bch2_inode_update_after_write(&trans, inode, &inode_u, ATTR_CTIME);
+               bch2_inode_update_after_write(trans, inode, &inode_u, ATTR_CTIME);
        }
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        mutex_unlock(&inode->ei_update_lock);
        return ret;
 }
@@ -451,24 +446,23 @@ int __bch2_unlink(struct inode *vdir, struct dentry *dentry,
        struct bch_inode_info *dir = to_bch_ei(vdir);
        struct bch_inode_info *inode = to_bch_ei(dentry->d_inode);
        struct bch_inode_unpacked dir_u, inode_u;
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        int ret;
 
        bch2_lock_inodes(INODE_UPDATE_LOCK, dir, inode);
-       bch2_trans_init(&trans, c, 4, 1024);
 
-       ret = commit_do(&trans, NULL, NULL,
+       ret = commit_do(trans, NULL, NULL,
                        BTREE_INSERT_NOFAIL,
-               bch2_unlink_trans(&trans,
+               bch2_unlink_trans(trans,
                                  inode_inum(dir), &dir_u,
                                  &inode_u, &dentry->d_name,
                                  deleting_snapshot));
        if (unlikely(ret))
                goto err;
 
-       bch2_inode_update_after_write(&trans, dir, &dir_u,
+       bch2_inode_update_after_write(trans, dir, &dir_u,
                                      ATTR_MTIME|ATTR_CTIME);
-       bch2_inode_update_after_write(&trans, inode, &inode_u,
+       bch2_inode_update_after_write(trans, inode, &inode_u,
                                      ATTR_MTIME);
 
        if (inode_u.bi_subvol) {
@@ -479,8 +473,8 @@ int __bch2_unlink(struct inode *vdir, struct dentry *dentry,
                set_nlink(&inode->v, 0);
        }
 err:
-       bch2_trans_exit(&trans);
        bch2_unlock_inodes(INODE_UPDATE_LOCK, dir, inode);
+       bch2_trans_put(trans);
 
        return ret;
 }
@@ -543,7 +537,7 @@ static int bch2_rename2(struct mnt_idmap *idmap,
        struct bch_inode_info *dst_inode = to_bch_ei(dst_dentry->d_inode);
        struct bch_inode_unpacked dst_dir_u, src_dir_u;
        struct bch_inode_unpacked src_inode_u, dst_inode_u;
-       struct btree_trans trans;
+       struct btree_trans *trans;
        enum bch_rename_mode mode = flags & RENAME_EXCHANGE
                ? BCH_RENAME_EXCHANGE
                : dst_dentry->d_inode
@@ -560,7 +554,7 @@ static int bch2_rename2(struct mnt_idmap *idmap,
                        return ret;
        }
 
-       bch2_trans_init(&trans, c, 8, 2048);
+       trans = bch2_trans_get(c);
 
        bch2_lock_inodes(INODE_UPDATE_LOCK,
                         src_dir,
@@ -587,8 +581,8 @@ static int bch2_rename2(struct mnt_idmap *idmap,
                        goto err;
        }
 
-       ret = commit_do(&trans, NULL, NULL, 0,
-                       bch2_rename_trans(&trans,
+       ret = commit_do(trans, NULL, NULL, 0,
+                       bch2_rename_trans(trans,
                                          inode_inum(src_dir), &src_dir_u,
                                          inode_inum(dst_dir), &dst_dir_u,
                                          &src_inode_u,
@@ -603,21 +597,21 @@ static int bch2_rename2(struct mnt_idmap *idmap,
        BUG_ON(dst_inode &&
               dst_inode->v.i_ino != dst_inode_u.bi_inum);
 
-       bch2_inode_update_after_write(&trans, src_dir, &src_dir_u,
+       bch2_inode_update_after_write(trans, src_dir, &src_dir_u,
                                      ATTR_MTIME|ATTR_CTIME);
 
        if (src_dir != dst_dir)
-               bch2_inode_update_after_write(&trans, dst_dir, &dst_dir_u,
+               bch2_inode_update_after_write(trans, dst_dir, &dst_dir_u,
                                              ATTR_MTIME|ATTR_CTIME);
 
-       bch2_inode_update_after_write(&trans, src_inode, &src_inode_u,
+       bch2_inode_update_after_write(trans, src_inode, &src_inode_u,
                                      ATTR_CTIME);
 
        if (dst_inode)
-               bch2_inode_update_after_write(&trans, dst_inode, &dst_inode_u,
+               bch2_inode_update_after_write(trans, dst_inode, &dst_inode_u,
                                              ATTR_CTIME);
 err:
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        bch2_fs_quota_transfer(c, src_inode,
                               bch_qid(&src_inode->ei_inode),
@@ -680,7 +674,7 @@ int bch2_setattr_nonsize(struct mnt_idmap *idmap,
 {
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
        struct bch_qid qid;
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter inode_iter = { NULL };
        struct bch_inode_unpacked inode_u;
        struct posix_acl *acl = NULL;
@@ -701,13 +695,13 @@ int bch2_setattr_nonsize(struct mnt_idmap *idmap,
        if (ret)
                goto err;
 
-       bch2_trans_init(&trans, c, 0, 0);
+       trans = bch2_trans_get(c);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
        kfree(acl);
        acl = NULL;
 
-       ret = bch2_inode_peek(&trans, &inode_iter, &inode_u, inode_inum(inode),
+       ret = bch2_inode_peek(trans, &inode_iter, &inode_u, inode_inum(inode),
                              BTREE_ITER_INTENT);
        if (ret)
                goto btree_err;
@@ -715,29 +709,29 @@ retry:
        bch2_setattr_copy(idmap, inode, &inode_u, attr);
 
        if (attr->ia_valid & ATTR_MODE) {
-               ret = bch2_acl_chmod(&trans, inode_inum(inode), &inode_u,
+               ret = bch2_acl_chmod(trans, inode_inum(inode), &inode_u,
                                     inode_u.bi_mode, &acl);
                if (ret)
                        goto btree_err;
        }
 
-       ret =   bch2_inode_write(&trans, &inode_iter, &inode_u) ?:
-               bch2_trans_commit(&trans, NULL, NULL,
+       ret =   bch2_inode_write(trans, &inode_iter, &inode_u) ?:
+               bch2_trans_commit(trans, NULL, NULL,
                                  BTREE_INSERT_NOFAIL);
 btree_err:
-       bch2_trans_iter_exit(&trans, &inode_iter);
+       bch2_trans_iter_exit(trans, &inode_iter);
 
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
        if (unlikely(ret))
                goto err_trans;
 
-       bch2_inode_update_after_write(&trans, inode, &inode_u, attr->ia_valid);
+       bch2_inode_update_after_write(trans, inode, &inode_u, attr->ia_valid);
 
        if (acl)
                set_cached_acl(&inode->v, ACL_TYPE_ACCESS, acl);
 err_trans:
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 err:
        mutex_unlock(&inode->ei_update_lock);
 
@@ -879,7 +873,7 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
 {
        struct bch_fs *c = vinode->i_sb->s_fs_info;
        struct bch_inode_info *ei = to_bch_ei(vinode);
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bkey_buf cur, prev;
@@ -900,18 +894,18 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
 
        bch2_bkey_buf_init(&cur);
        bch2_bkey_buf_init(&prev);
-       bch2_trans_init(&trans, c, 0, 0);
+       trans = bch2_trans_get(c);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
 
-       ret = bch2_subvolume_get_snapshot(&trans, ei->ei_subvol, &snapshot);
+       ret = bch2_subvolume_get_snapshot(trans, ei->ei_subvol, &snapshot);
        if (ret)
                goto err;
 
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
                             SPOS(ei->v.i_ino, start, snapshot), 0);
 
-       while (!(ret = btree_trans_too_many_iters(&trans)) &&
+       while (!(ret = btree_trans_too_many_iters(trans)) &&
               (k = bch2_btree_iter_peek_upto(&iter, end)).k &&
               !(ret = bkey_err(k))) {
                enum btree_id data_btree = BTREE_ID_extents;
@@ -928,7 +922,7 @@ retry:
 
                bch2_bkey_buf_reassemble(&cur, c, k);
 
-               ret = bch2_read_indirect_extent(&trans, &data_btree,
+               ret = bch2_read_indirect_extent(trans, &data_btree,
                                        &offset_into_extent, &cur);
                if (ret)
                        break;
@@ -947,7 +941,7 @@ retry:
                cur.k->k.p.offset += cur.k->k.size;
 
                if (have_extent) {
-                       bch2_trans_unlock(&trans);
+                       bch2_trans_unlock(trans);
                        ret = bch2_fill_extent(c, info,
                                        bkey_i_to_s_c(prev.k), 0);
                        if (ret)
@@ -961,18 +955,18 @@ retry:
                        POS(iter.pos.inode, iter.pos.offset + sectors));
        }
        start = iter.pos.offset;
-       bch2_trans_iter_exit(&trans, &iter);
+       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);
+               bch2_trans_unlock(trans);
                ret = bch2_fill_extent(c, info, bkey_i_to_s_c(prev.k),
                                       FIEMAP_EXTENT_LAST);
        }
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        bch2_bkey_buf_exit(&cur, c);
        bch2_bkey_buf_exit(&prev, c);
        return ret < 0 ? ret : 0;
@@ -1230,7 +1224,7 @@ static int bch2_get_name(struct dentry *parent, char *name, struct dentry *child
        struct bch_inode_info *inode    = to_bch_ei(child->d_inode);
        struct bch_inode_info *dir      = to_bch_ei(parent->d_inode);
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter iter1;
        struct btree_iter iter2;
        struct bkey_s_c k;
@@ -1245,23 +1239,23 @@ static int bch2_get_name(struct dentry *parent, char *name, struct dentry *child
        if (!S_ISDIR(dir->v.i_mode))
                return -EINVAL;
 
-       bch2_trans_init(&trans, c, 0, 0);
+       trans = bch2_trans_get(c);
 
-       bch2_trans_iter_init(&trans, &iter1, BTREE_ID_dirents,
+       bch2_trans_iter_init(trans, &iter1, BTREE_ID_dirents,
                             POS(dir->ei_inode.bi_inum, 0), 0);
-       bch2_trans_iter_init(&trans, &iter2, BTREE_ID_dirents,
+       bch2_trans_iter_init(trans, &iter2, BTREE_ID_dirents,
                             POS(dir->ei_inode.bi_inum, 0), 0);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
 
-       ret = bch2_subvolume_get_snapshot(&trans, dir->ei_subvol, &snapshot);
+       ret = bch2_subvolume_get_snapshot(trans, dir->ei_subvol, &snapshot);
        if (ret)
                goto err;
 
        bch2_btree_iter_set_snapshot(&iter1, snapshot);
        bch2_btree_iter_set_snapshot(&iter2, snapshot);
 
-       ret = bch2_inode_find_by_inum_trans(&trans, inode_inum(inode), &inode_u);
+       ret = bch2_inode_find_by_inum_trans(trans, inode_inum(inode), &inode_u);
        if (ret)
                goto err;
 
@@ -1279,7 +1273,7 @@ retry:
                }
 
                d = bkey_s_c_to_dirent(k);
-               ret = bch2_dirent_read_target(&trans, inode_inum(dir), d, &target);
+               ret = bch2_dirent_read_target(trans, inode_inum(dir), d, &target);
                if (ret > 0)
                        ret = -BCH_ERR_ENOENT_dirent_doesnt_match_inode;
                if (ret)
@@ -1301,7 +1295,7 @@ retry:
                                continue;
 
                        d = bkey_s_c_to_dirent(k);
-                       ret = bch2_dirent_read_target(&trans, inode_inum(dir), d, &target);
+                       ret = bch2_dirent_read_target(trans, inode_inum(dir), d, &target);
                        if (ret < 0)
                                break;
                        if (ret)
@@ -1325,9 +1319,9 @@ err:
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
 
-       bch2_trans_iter_exit(&trans, &iter1);
-       bch2_trans_iter_exit(&trans, &iter2);
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_exit(trans, &iter1);
+       bch2_trans_iter_exit(trans, &iter2);
+       bch2_trans_put(trans);
 
        return ret;
 }
index b9c9ece..e3d6808 100644 (file)
@@ -987,7 +987,7 @@ noinline_for_stack
 int bch2_check_inodes(struct bch_fs *c)
 {
        bool full = c->opts.fsck;
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bch_inode_unpacked prev = { 0 };
        struct snapshots_seen s;
@@ -995,16 +995,15 @@ int bch2_check_inodes(struct bch_fs *c)
        int ret;
 
        snapshots_seen_init(&s);
-       bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
 
-       ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_inodes,
+       ret = for_each_btree_key_commit(trans, iter, BTREE_ID_inodes,
                        POS_MIN,
                        BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
                        NULL, NULL, BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
-               check_inode(&trans, &iter, k, &prev, &s, full));
+               check_inode(trans, &iter, k, &prev, &s, full));
 
-       bch2_trans_exit(&trans);
        snapshots_seen_exit(&s);
+       bch2_trans_put(trans);
        if (ret)
                bch_err_fn(c, ret);
        return ret;
@@ -1437,7 +1436,7 @@ int bch2_check_extents(struct bch_fs *c)
 {
        struct inode_walker w = inode_walker_init();
        struct snapshots_seen s;
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        struct extent_ends extent_ends;
@@ -1446,23 +1445,22 @@ int bch2_check_extents(struct bch_fs *c)
 
        snapshots_seen_init(&s);
        extent_ends_init(&extent_ends);
-       bch2_trans_init(&trans, c, BTREE_ITER_MAX, 4096);
 
-       ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_extents,
+       ret = for_each_btree_key_commit(trans, iter, BTREE_ID_extents,
                        POS(BCACHEFS_ROOT_INO, 0),
                        BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
                        &res, NULL,
                        BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL, ({
                bch2_disk_reservation_put(c, &res);
-               check_extent(&trans, &iter, k, &w, &s, &extent_ends);
+               check_extent(trans, &iter, k, &w, &s, &extent_ends);
        })) ?:
-       check_i_sectors(&trans, &w);
+       check_i_sectors(trans, &w);
 
        bch2_disk_reservation_put(c, &res);
        extent_ends_exit(&extent_ends);
        inode_walker_exit(&w);
-       bch2_trans_exit(&trans);
        snapshots_seen_exit(&s);
+       bch2_trans_put(trans);
 
        if (ret)
                bch_err_fn(c, ret);
@@ -1803,23 +1801,22 @@ int bch2_check_dirents(struct bch_fs *c)
        struct inode_walker target = inode_walker_init();
        struct snapshots_seen s;
        struct bch_hash_info hash_info;
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        int ret = 0;
 
        snapshots_seen_init(&s);
-       bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
 
-       ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_dirents,
+       ret = for_each_btree_key_commit(trans, iter, BTREE_ID_dirents,
                        POS(BCACHEFS_ROOT_INO, 0),
                        BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS,
                        k,
                        NULL, NULL,
                        BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
-               check_dirent(&trans, &iter, k, &hash_info, &dir, &target, &s));
+               check_dirent(trans, &iter, k, &hash_info, &dir, &target, &s));
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        snapshots_seen_exit(&s);
        inode_walker_exit(&dir);
        inode_walker_exit(&target);
@@ -1873,23 +1870,18 @@ int bch2_check_xattrs(struct bch_fs *c)
 {
        struct inode_walker inode = inode_walker_init();
        struct bch_hash_info hash_info;
-       struct btree_trans trans;
        struct btree_iter iter;
        struct bkey_s_c k;
        int ret = 0;
 
-       bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
-
-       ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_xattrs,
+       ret = bch2_trans_run(c,
+               for_each_btree_key_commit(trans, iter, BTREE_ID_xattrs,
                        POS(BCACHEFS_ROOT_INO, 0),
                        BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS,
                        k,
                        NULL, NULL,
                        BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
-               check_xattr(&trans, &iter, k, &hash_info, &inode));
-
-       bch2_trans_exit(&trans);
-
+               check_xattr(trans, &iter, k, &hash_info, &inode)));
        if (ret)
                bch_err_fn(c, ret);
        return ret;
@@ -1958,7 +1950,7 @@ int bch2_check_root(struct bch_fs *c)
        ret = bch2_trans_do(c, NULL, NULL,
                             BTREE_INSERT_NOFAIL|
                             BTREE_INSERT_LAZY_RW,
-               check_root_trans(&trans));
+               check_root_trans(trans));
 
        if (ret)
                bch_err_fn(c, ret);
@@ -2110,16 +2102,14 @@ fsck_err:
  */
 int bch2_check_directory_structure(struct bch_fs *c)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bch_inode_unpacked u;
        pathbuf path = { 0, };
        int ret;
 
-       bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
-
-       for_each_btree_key(&trans, iter, BTREE_ID_inodes, POS_MIN,
+       for_each_btree_key(trans, iter, BTREE_ID_inodes, POS_MIN,
                           BTREE_ITER_INTENT|
                           BTREE_ITER_PREFETCH|
                           BTREE_ITER_ALL_SNAPSHOTS, k, ret) {
@@ -2136,12 +2126,12 @@ int bch2_check_directory_structure(struct bch_fs *c)
                if (u.bi_flags & BCH_INODE_UNLINKED)
                        continue;
 
-               ret = check_path(&trans, &path, &u, iter.pos.snapshot);
+               ret = check_path(trans, &path, &u, iter.pos.snapshot);
                if (ret)
                        break;
        }
-       bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_exit(trans, &iter);
+       bch2_trans_put(trans);
        darray_exit(&path);
 
        if (ret)
@@ -2230,15 +2220,13 @@ static int check_nlinks_find_hardlinks(struct bch_fs *c,
                                       struct nlink_table *t,
                                       u64 start, u64 *end)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bch_inode_unpacked u;
        int ret = 0;
 
-       bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
-
-       for_each_btree_key(&trans, iter, BTREE_ID_inodes,
+       for_each_btree_key(trans, iter, BTREE_ID_inodes,
                           POS(0, start),
                           BTREE_ITER_INTENT|
                           BTREE_ITER_PREFETCH|
@@ -2267,8 +2255,8 @@ static int check_nlinks_find_hardlinks(struct bch_fs *c,
                }
 
        }
-       bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_exit(trans, &iter);
+       bch2_trans_put(trans);
 
        if (ret)
                bch_err(c, "error in fsck: btree error %i while walking inodes", ret);
@@ -2280,7 +2268,7 @@ noinline_for_stack
 static int check_nlinks_walk_dirents(struct bch_fs *c, struct nlink_table *links,
                                     u64 range_start, u64 range_end)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct snapshots_seen s;
        struct btree_iter iter;
        struct bkey_s_c k;
@@ -2289,9 +2277,7 @@ static int check_nlinks_walk_dirents(struct bch_fs *c, struct nlink_table *links
 
        snapshots_seen_init(&s);
 
-       bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
-
-       for_each_btree_key(&trans, iter, BTREE_ID_dirents, POS_MIN,
+       for_each_btree_key(trans, iter, BTREE_ID_dirents, POS_MIN,
                           BTREE_ITER_INTENT|
                           BTREE_ITER_PREFETCH|
                           BTREE_ITER_ALL_SNAPSHOTS, k, ret) {
@@ -2311,12 +2297,12 @@ static int check_nlinks_walk_dirents(struct bch_fs *c, struct nlink_table *links
                        break;
                }
        }
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 
        if (ret)
                bch_err(c, "error in fsck: btree error %i while walking dirents", ret);
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        snapshots_seen_exit(&s);
        return ret;
 }
@@ -2367,22 +2353,17 @@ static int check_nlinks_update_hardlinks(struct bch_fs *c,
                               struct nlink_table *links,
                               u64 range_start, u64 range_end)
 {
-       struct btree_trans trans;
        struct btree_iter iter;
        struct bkey_s_c k;
        size_t idx = 0;
        int ret = 0;
 
-       bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
-
-       ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_inodes,
-                       POS(0, range_start),
-                       BTREE_ITER_INTENT|BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
-                       NULL, NULL, BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
-               check_nlinks_update_inode(&trans, &iter, k, links, &idx, range_end));
-
-       bch2_trans_exit(&trans);
-
+       ret = bch2_trans_run(c,
+               for_each_btree_key_commit(trans, iter, BTREE_ID_inodes,
+                               POS(0, range_start),
+                               BTREE_ITER_INTENT|BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
+                               NULL, NULL, BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
+                       check_nlinks_update_inode(trans, &iter, k, links, &idx, range_end)));
        if (ret < 0) {
                bch_err(c, "error in fsck: btree error %i while walking inodes", ret);
                return ret;
@@ -2464,13 +2445,12 @@ int bch2_fix_reflink_p(struct bch_fs *c)
                return 0;
 
        ret = bch2_trans_run(c,
-               for_each_btree_key_commit(&trans, iter,
+               for_each_btree_key_commit(trans, iter,
                                BTREE_ID_extents, POS_MIN,
                                BTREE_ITER_INTENT|BTREE_ITER_PREFETCH|
                                BTREE_ITER_ALL_SNAPSHOTS, k,
                                NULL, NULL, BTREE_INSERT_NOFAIL|BTREE_INSERT_LAZY_RW,
-                       fix_reflink_p_key(&trans, &iter, k)));
-
+                       fix_reflink_p_key(trans, &iter, k)));
        if (ret)
                bch_err_fn(c, ret);
        return ret;
index 81ff272..8bfd99c 100644 (file)
@@ -826,7 +826,7 @@ err:
 
 int bch2_inode_rm(struct bch_fs *c, subvol_inum inum)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter = { NULL };
        struct bkey_i_inode_generation delete;
        struct bch_inode_unpacked inode_u;
@@ -834,8 +834,6 @@ int bch2_inode_rm(struct bch_fs *c, subvol_inum inum)
        u32 snapshot;
        int ret;
 
-       bch2_trans_init(&trans, c, 0, 1024);
-
        /*
         * If this was a directory, there shouldn't be any real dirents left -
         * but there could be whiteouts (from hash collisions) that we should
@@ -844,19 +842,19 @@ int bch2_inode_rm(struct bch_fs *c, subvol_inum inum)
         * XXX: the dirent could ideally would delete whiteouts when they're no
         * longer needed
         */
-       ret   = bch2_inode_delete_keys(&trans, inum, BTREE_ID_extents) ?:
-               bch2_inode_delete_keys(&trans, inum, BTREE_ID_xattrs) ?:
-               bch2_inode_delete_keys(&trans, inum, BTREE_ID_dirents);
+       ret   = bch2_inode_delete_keys(trans, inum, BTREE_ID_extents) ?:
+               bch2_inode_delete_keys(trans, inum, BTREE_ID_xattrs) ?:
+               bch2_inode_delete_keys(trans, inum, BTREE_ID_dirents);
        if (ret)
                goto err;
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
 
-       ret = bch2_subvolume_get_snapshot(&trans, inum.subvol, &snapshot);
+       ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
        if (ret)
                goto err;
 
-       k = bch2_bkey_get_iter(&trans, &iter, BTREE_ID_inodes,
+       k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_inodes,
                               SPOS(0, inum.inum, snapshot),
                               BTREE_ITER_INTENT|BTREE_ITER_CACHED);
        ret = bkey_err(k);
@@ -864,7 +862,7 @@ retry:
                goto err;
 
        if (!bkey_is_inode(k.k)) {
-               bch2_fs_inconsistent(trans.c,
+               bch2_fs_inconsistent(c,
                                     "inode %llu:%u not found when deleting",
                                     inum.inum, snapshot);
                ret = -EIO;
@@ -877,15 +875,15 @@ retry:
        delete.k.p = iter.pos;
        delete.v.bi_generation = cpu_to_le32(inode_u.bi_generation + 1);
 
-       ret   = bch2_trans_update(&trans, &iter, &delete.k_i, 0) ?:
-               bch2_trans_commit(&trans, NULL, NULL,
+       ret   = bch2_trans_update(trans, &iter, &delete.k_i, 0) ?:
+               bch2_trans_commit(trans, NULL, NULL,
                                BTREE_INSERT_NOFAIL);
 err:
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        return ret;
 }
 
@@ -919,7 +917,7 @@ 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));
+               bch2_inode_find_by_inum_trans(trans, inum, inode));
 }
 
 int bch2_inode_nlink_inc(struct bch_inode_unpacked *bi)
@@ -1091,14 +1089,12 @@ delete:
 
 int bch2_delete_dead_inodes(struct bch_fs *c)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        int ret;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
-       ret = bch2_btree_write_buffer_flush_sync(&trans);
+       ret = bch2_btree_write_buffer_flush_sync(trans);
        if (ret)
                goto err;
 
@@ -1108,26 +1104,26 @@ int bch2_delete_dead_inodes(struct bch_fs *c)
         * but we can't retry because the btree write buffer won't have been
         * flushed and we'd spin:
         */
-       for_each_btree_key(&trans, iter, BTREE_ID_deleted_inodes, POS_MIN,
+       for_each_btree_key(trans, iter, BTREE_ID_deleted_inodes, POS_MIN,
                           BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k, ret) {
-               ret = lockrestart_do(&trans, may_delete_deleted_inode(&trans, k.k->p));
+               ret = lockrestart_do(trans, may_delete_deleted_inode(trans, k.k->p));
                if (ret < 0)
                        break;
 
                if (ret) {
                        if (!test_bit(BCH_FS_RW, &c->flags)) {
-                               bch2_trans_unlock(&trans);
+                               bch2_trans_unlock(trans);
                                bch2_fs_lazy_rw(c);
                        }
 
-                       ret = bch2_inode_rm_snapshot(&trans, k.k->p.offset, k.k->p.snapshot);
+                       ret = bch2_inode_rm_snapshot(trans, k.k->p.offset, k.k->p.snapshot);
                        if (ret && !bch2_err_matches(ret, BCH_ERR_transaction_restart))
                                break;
                }
        }
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 err:
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        return ret;
 }
index b1be70e..668493b 100644 (file)
@@ -198,19 +198,18 @@ int bch2_fpunch_at(struct btree_trans *trans, struct btree_iter *iter,
 int bch2_fpunch(struct bch_fs *c, subvol_inum inum, u64 start, u64 end,
                s64 *i_sectors_delta)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        int ret;
 
-       bch2_trans_init(&trans, c, BTREE_ITER_MAX, 1024);
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
                             POS(inum.inum, start),
                             BTREE_ITER_INTENT);
 
-       ret = bch2_fpunch_at(&trans, &iter, inum, end, i_sectors_delta);
+       ret = bch2_fpunch_at(trans, &iter, inum, end, i_sectors_delta);
 
-       bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_exit(trans, &iter);
+       bch2_trans_put(trans);
 
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                ret = 0;
@@ -289,8 +288,8 @@ int bch2_truncate(struct bch_fs *c, subvol_inum inum, u64 new_i_size, u64 *i_sec
        op.v.new_i_size = cpu_to_le64(new_i_size);
 
        return bch2_trans_run(c,
-               bch2_logged_op_start(&trans, &op.k_i) ?:
-               __bch2_resume_logged_op_truncate(&trans, &op.k_i, i_sectors_delta));
+               bch2_logged_op_start(trans, &op.k_i) ?:
+               __bch2_resume_logged_op_truncate(trans, &op.k_i, i_sectors_delta));
 }
 
 /* finsert/fcollapse: */
@@ -493,6 +492,6 @@ int bch2_fcollapse_finsert(struct bch_fs *c, subvol_inum inum,
        op.v.pos        = cpu_to_le64(insert ? U64_MAX : offset);
 
        return bch2_trans_run(c,
-               bch2_logged_op_start(&trans, &op.k_i) ?:
-               __bch2_resume_logged_op_finsert(&trans, &op.k_i, i_sectors_delta));
+               bch2_logged_op_start(trans, &op.k_i) ?:
+               __bch2_resume_logged_op_finsert(trans, &op.k_i, i_sectors_delta));
 }
index 3c6c139..9a57da0 100644 (file)
@@ -359,7 +359,7 @@ static void bch2_read_retry_nodecode(struct bch_fs *c, struct bch_read_bio *rbio
                                     struct bch_io_failures *failed,
                                     unsigned flags)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_buf sk;
        struct bkey_s_c k;
@@ -369,9 +369,8 @@ static void bch2_read_retry_nodecode(struct bch_fs *c, struct bch_read_bio *rbio
        flags |= BCH_READ_MUST_CLONE;
 
        bch2_bkey_buf_init(&sk);
-       bch2_trans_init(&trans, c, 0, 0);
 
-       bch2_trans_iter_init(&trans, &iter, rbio->data_btree,
+       bch2_trans_iter_init(trans, &iter, rbio->data_btree,
                             rbio->read_pos, BTREE_ITER_SLOTS);
 retry:
        rbio->bio.bi_status = 0;
@@ -382,7 +381,7 @@ retry:
 
        bch2_bkey_buf_reassemble(&sk, c, k);
        k = bkey_i_to_s_c(sk.k);
-       bch2_trans_unlock(&trans);
+       bch2_trans_unlock(trans);
 
        if (!bch2_bkey_matches_ptr(c, k,
                                   rbio->pick.ptr,
@@ -393,7 +392,7 @@ retry:
                goto out;
        }
 
-       ret = __bch2_read_extent(&trans, rbio, bvec_iter,
+       ret = __bch2_read_extent(trans, rbio, bvec_iter,
                                 rbio->read_pos,
                                 rbio->data_btree,
                                 k, 0, failed, flags);
@@ -403,8 +402,8 @@ retry:
                goto err;
 out:
        bch2_rbio_done(rbio);
-       bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_exit(trans, &iter);
+       bch2_trans_put(trans);
        bch2_bkey_buf_exit(&sk, c);
        return;
 err:
@@ -526,7 +525,7 @@ out:
 static noinline void bch2_rbio_narrow_crcs(struct bch_read_bio *rbio)
 {
        bch2_trans_do(rbio->c, NULL, NULL, BTREE_INSERT_NOFAIL,
-                     __bch2_rbio_narrow_crcs(&trans, rbio));
+                     __bch2_rbio_narrow_crcs(trans, rbio));
 }
 
 /* Inner part that may run in process context */
@@ -1082,7 +1081,7 @@ void __bch2_read(struct bch_fs *c, struct bch_read_bio *rbio,
                 struct bvec_iter bvec_iter, subvol_inum inum,
                 struct bch_io_failures *failed, unsigned flags)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_buf sk;
        struct bkey_s_c k;
@@ -1092,16 +1091,15 @@ void __bch2_read(struct bch_fs *c, struct bch_read_bio *rbio,
        BUG_ON(flags & BCH_READ_NODECODE);
 
        bch2_bkey_buf_init(&sk);
-       bch2_trans_init(&trans, c, 0, 0);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
        iter = (struct btree_iter) { NULL };
 
-       ret = bch2_subvolume_get_snapshot(&trans, inum.subvol, &snapshot);
+       ret = bch2_subvolume_get_snapshot(trans, inum.subvol, &snapshot);
        if (ret)
                goto err;
 
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
                             SPOS(inum.inum, bvec_iter.bi_sector, snapshot),
                             BTREE_ITER_SLOTS);
        while (1) {
@@ -1112,7 +1110,7 @@ retry:
                 * read_extent -> io_time_reset may cause a transaction restart
                 * without returning an error, we need to check for that here:
                 */
-               ret = bch2_trans_relock(&trans);
+               ret = bch2_trans_relock(trans);
                if (ret)
                        break;
 
@@ -1130,7 +1128,7 @@ retry:
 
                bch2_bkey_buf_reassemble(&sk, c, k);
 
-               ret = bch2_read_indirect_extent(&trans, &data_btree,
+               ret = bch2_read_indirect_extent(trans, &data_btree,
                                        &offset_into_extent, &sk);
                if (ret)
                        break;
@@ -1149,7 +1147,7 @@ retry:
                if (bvec_iter.bi_size == bytes)
                        flags |= BCH_READ_LAST_FRAGMENT;
 
-               ret = __bch2_read_extent(&trans, rbio, bvec_iter, iter.pos,
+               ret = __bch2_read_extent(trans, rbio, bvec_iter, iter.pos,
                                         data_btree, k,
                                         offset_into_extent, failed, flags);
                if (ret)
@@ -1161,19 +1159,19 @@ retry:
                swap(bvec_iter.bi_size, bytes);
                bio_advance_iter(&rbio->bio, &bvec_iter, bytes);
 
-               ret = btree_trans_too_many_iters(&trans);
+               ret = btree_trans_too_many_iters(trans);
                if (ret)
                        break;
        }
 err:
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart) ||
            ret == READ_RETRY ||
            ret == READ_RETRY_AVOID)
                goto retry;
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        bch2_bkey_buf_exit(&sk, c);
 
        if (ret) {
index 3439e95..659330c 100644 (file)
@@ -322,7 +322,7 @@ static int bch2_write_index_default(struct bch_write_op *op)
        struct bkey_buf sk;
        struct keylist *keys = &op->insert_keys;
        struct bkey_i *k = bch2_keylist_front(keys);
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        subvol_inum inum = {
                .subvol = op->subvol,
@@ -333,30 +333,29 @@ static int bch2_write_index_default(struct bch_write_op *op)
        BUG_ON(!inum.subvol);
 
        bch2_bkey_buf_init(&sk);
-       bch2_trans_init(&trans, c, BTREE_ITER_MAX, 1024);
 
        do {
-               bch2_trans_begin(&trans);
+               bch2_trans_begin(trans);
 
                k = bch2_keylist_front(keys);
                bch2_bkey_buf_copy(&sk, c, k);
 
-               ret = bch2_subvolume_get_snapshot(&trans, inum.subvol,
+               ret = bch2_subvolume_get_snapshot(trans, inum.subvol,
                                                  &sk.k->k.p.snapshot);
                if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                        continue;
                if (ret)
                        break;
 
-               bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
+               bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
                                     bkey_start_pos(&sk.k->k),
                                     BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
 
-               ret = bch2_extent_update(&trans, inum, &iter, sk.k,
+               ret = bch2_extent_update(trans, inum, &iter, sk.k,
                                         &op->res,
                                         op->new_i_size, &op->i_sectors_delta,
                                         op->flags & BCH_WRITE_CHECK_ENOSPC);
-               bch2_trans_iter_exit(&trans, &iter);
+               bch2_trans_iter_exit(trans, &iter);
 
                if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                        continue;
@@ -369,7 +368,7 @@ static int bch2_write_index_default(struct bch_write_op *op)
                        bch2_cut_front(iter.pos, k);
        } while (!bch2_keylist_empty(keys));
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        bch2_bkey_buf_exit(&sk, c);
 
        return ret;
@@ -1163,20 +1162,18 @@ static int bch2_nocow_write_convert_one_unwritten(struct btree_trans *trans,
 static void bch2_nocow_write_convert_unwritten(struct bch_write_op *op)
 {
        struct bch_fs *c = op->c;
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_i *orig;
        struct bkey_s_c k;
        int ret;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
        for_each_keylist_key(&op->insert_keys, orig) {
-               ret = for_each_btree_key_upto_commit(&trans, iter, BTREE_ID_extents,
+               ret = for_each_btree_key_upto_commit(trans, iter, BTREE_ID_extents,
                                     bkey_start_pos(&orig->k), orig->k.p,
                                     BTREE_ITER_INTENT, k,
                                     NULL, NULL, BTREE_INSERT_NOFAIL, ({
-                       bch2_nocow_write_convert_one_unwritten(&trans, &iter, orig, k, op->new_i_size);
+                       bch2_nocow_write_convert_one_unwritten(trans, &iter, orig, k, op->new_i_size);
                }));
 
                if (ret && !bch2_err_matches(ret, EROFS)) {
@@ -1194,7 +1191,7 @@ static void bch2_nocow_write_convert_unwritten(struct bch_write_op *op)
                }
        }
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 }
 
 static void __bch2_nocow_write_done(struct bch_write_op *op)
@@ -1218,7 +1215,7 @@ static void bch2_nocow_write_done(struct closure *cl)
 static void bch2_nocow_write(struct bch_write_op *op)
 {
        struct bch_fs *c = op->c;
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bkey_ptrs_c ptrs;
@@ -1235,15 +1232,15 @@ static void bch2_nocow_write(struct bch_write_op *op)
        if (op->flags & BCH_WRITE_MOVE)
                return;
 
-       bch2_trans_init(&trans, c, 0, 0);
+       trans = bch2_trans_get(c);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
 
-       ret = bch2_subvolume_get_snapshot(&trans, op->subvol, &snapshot);
+       ret = bch2_subvolume_get_snapshot(trans, op->subvol, &snapshot);
        if (unlikely(ret))
                goto err;
 
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
                             SPOS(op->pos.inode, op->pos.offset, snapshot),
                             BTREE_ITER_SLOTS);
        while (1) {
@@ -1289,7 +1286,7 @@ retry:
 
                /* Unlock before taking nocow locks, doing IO: */
                bkey_reassemble(op->insert_keys.top, k);
-               bch2_trans_unlock(&trans);
+               bch2_trans_unlock(trans);
 
                bch2_cut_front(op->pos, op->insert_keys.top);
                if (op->flags & BCH_WRITE_CONVERT_UNWRITTEN)
@@ -1338,7 +1335,7 @@ retry:
                bch2_btree_iter_advance(&iter);
        }
 out:
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 err:
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
@@ -1353,7 +1350,7 @@ err:
                op->flags |= BCH_WRITE_DONE;
        }
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        /* fallback to cow write path? */
        if (!(op->flags & BCH_WRITE_DONE)) {
@@ -1431,7 +1428,7 @@ again:
                 * allocations for specific disks may hang arbitrarily long:
                 */
                ret = bch2_trans_do(c, NULL, NULL, 0,
-                       bch2_alloc_sectors_start_trans(&trans,
+                       bch2_alloc_sectors_start_trans(trans,
                                op->target,
                                op->opts.erasure_code && !(op->flags & BCH_WRITE_CACHED),
                                op->write_point,
index 40455e8..ad80618 100644 (file)
@@ -834,7 +834,7 @@ static int __bch2_set_nr_journal_buckets(struct bch_dev *ca, unsigned nr,
                                break;
 
                        ret = bch2_trans_run(c,
-                               bch2_trans_mark_metadata_bucket(&trans, ca,
+                               bch2_trans_mark_metadata_bucket(trans, ca,
                                                ob[nr_got]->bucket, BCH_DATA_journal,
                                                ca->mi.bucket_size));
                        if (ret) {
@@ -915,7 +915,7 @@ err_unblock:
        if (ret && !new_fs)
                for (i = 0; i < nr_got; i++)
                        bch2_trans_run(c,
-                               bch2_trans_mark_metadata_bucket(&trans, ca,
+                               bch2_trans_mark_metadata_bucket(trans, ca,
                                                bu[i], BCH_DATA_free, 0));
 err_free:
        if (!new_fs)
index d6b9f2c..1e1a794 100644 (file)
@@ -250,20 +250,18 @@ void bch2_blacklist_entries_gc(struct work_struct *work)
        struct journal_seq_blacklist_table *t;
        struct bch_sb_field_journal_seq_blacklist *bl;
        struct journal_seq_blacklist_entry *src, *dst;
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        unsigned i, nr, new_nr;
        int ret;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
        for (i = 0; i < BTREE_ID_NR; i++) {
                struct btree_iter iter;
                struct btree *b;
 
-               bch2_trans_node_iter_init(&trans, &iter, i, POS_MIN,
+               bch2_trans_node_iter_init(trans, &iter, i, POS_MIN,
                                          0, 0, BTREE_ITER_PREFETCH);
 retry:
-               bch2_trans_begin(&trans);
+               bch2_trans_begin(trans);
 
                b = bch2_btree_iter_peek_node(&iter);
 
@@ -275,10 +273,10 @@ retry:
                if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                        goto retry;
 
-               bch2_trans_iter_exit(&trans, &iter);
+               bch2_trans_iter_exit(trans, &iter);
        }
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        if (ret)
                return;
 
index e133c23..8640f7d 100644 (file)
@@ -59,9 +59,9 @@ int bch2_resume_logged_ops(struct bch_fs *c)
        int ret;
 
        ret = bch2_trans_run(c,
-               for_each_btree_key2(&trans, iter,
+               for_each_btree_key2(trans, iter,
                                BTREE_ID_logged_ops, POS_MIN, BTREE_ITER_PREFETCH, k,
-                       resume_logged_op(&trans, &iter, k)));
+                       resume_logged_op(trans, &iter, k)));
        if (ret)
                bch_err_fn(c, ret);
        return ret;
index 3e8b8f2..215a653 100644 (file)
@@ -151,10 +151,10 @@ int bch2_check_lrus(struct bch_fs *c)
        int ret = 0;
 
        ret = bch2_trans_run(c,
-               for_each_btree_key_commit(&trans, iter,
+               for_each_btree_key_commit(trans, iter,
                                BTREE_ID_lru, POS_MIN, BTREE_ITER_PREFETCH, k,
                                NULL, NULL, BTREE_INSERT_NOFAIL|BTREE_INSERT_LAZY_RW,
-                       bch2_check_lru_key(&trans, &iter, k, &last_flushed_pos)));
+                       bch2_check_lru_key(trans, &iter, k, &last_flushed_pos)));
        if (ret)
                bch_err_fn(c, ret);
        return ret;
index 4746dfa..e3a51f6 100644 (file)
@@ -78,34 +78,32 @@ static int bch2_dev_usrdata_drop_key(struct btree_trans *trans,
 
 static int bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        enum btree_id id;
        int ret = 0;
 
-       bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
-
        for (id = 0; id < BTREE_ID_NR; id++) {
                if (!btree_type_has_ptrs(id))
                        continue;
 
-               ret = for_each_btree_key_commit(&trans, iter, id, POS_MIN,
+               ret = for_each_btree_key_commit(trans, iter, id, POS_MIN,
                                BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
                                NULL, NULL, BTREE_INSERT_NOFAIL,
-                       bch2_dev_usrdata_drop_key(&trans, &iter, k, dev_idx, flags));
+                       bch2_dev_usrdata_drop_key(trans, &iter, k, dev_idx, flags));
                if (ret)
                        break;
        }
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        return ret;
 }
 
 static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter iter;
        struct closure cl;
        struct btree *b;
@@ -117,16 +115,16 @@ static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags)
        if (flags & BCH_FORCE_IF_METADATA_LOST)
                return -EINVAL;
 
+       trans = bch2_trans_get(c);
        bch2_bkey_buf_init(&k);
-       bch2_trans_init(&trans, c, 0, 0);
        closure_init_stack(&cl);
 
        for (id = 0; id < BTREE_ID_NR; id++) {
-               bch2_trans_node_iter_init(&trans, &iter, id, POS_MIN, 0, 0,
+               bch2_trans_node_iter_init(trans, &iter, id, POS_MIN, 0, 0,
                                          BTREE_ITER_PREFETCH);
 retry:
                ret = 0;
-               while (bch2_trans_begin(&trans),
+               while (bch2_trans_begin(trans),
                       (b = bch2_btree_iter_peek_node(&iter)) &&
                       !(ret = PTR_ERR_OR_ZERO(b))) {
                        if (!bch2_bkey_has_device_c(bkey_i_to_s_c(&b->key), dev_idx))
@@ -141,7 +139,7 @@ retry:
                                break;
                        }
 
-                       ret = bch2_btree_node_update_key(&trans, &iter, b, k.k, 0, false);
+                       ret = bch2_btree_node_update_key(trans, &iter, b, k.k, 0, false);
                        if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) {
                                ret = 0;
                                continue;
@@ -157,7 +155,7 @@ next:
                if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                        goto retry;
 
-               bch2_trans_iter_exit(&trans, &iter);
+               bch2_trans_iter_exit(trans, &iter);
 
                if (ret)
                        goto err;
@@ -166,8 +164,8 @@ next:
        bch2_btree_interior_updates_flush(c);
        ret = 0;
 err:
-       bch2_trans_exit(&trans);
        bch2_bkey_buf_exit(&k, c);
+       bch2_trans_put(trans);
 
        BUG_ON(bch2_err_matches(ret, BCH_ERR_transaction_restart));
 
index d62b757..c1aa76f 100644 (file)
@@ -525,7 +525,7 @@ static int __bch2_move_data(struct moving_context *ctxt,
        struct bch_fs *c = ctxt->c;
        struct bch_io_opts io_opts = bch2_opts_to_inode_opts(c->opts);
        struct bkey_buf sk;
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        struct data_update_opts data_opts;
@@ -533,7 +533,6 @@ static int __bch2_move_data(struct moving_context *ctxt,
        int ret = 0, ret2;
 
        bch2_bkey_buf_init(&sk);
-       bch2_trans_init(&trans, c, 0, 0);
 
        if (ctxt->stats) {
                ctxt->stats->data_type  = BCH_DATA_user;
@@ -541,15 +540,15 @@ static int __bch2_move_data(struct moving_context *ctxt,
                ctxt->stats->pos        = start;
        }
 
-       bch2_trans_iter_init(&trans, &iter, btree_id, start,
+       bch2_trans_iter_init(trans, &iter, btree_id, start,
                             BTREE_ITER_PREFETCH|
                             BTREE_ITER_ALL_SNAPSHOTS);
 
        if (ctxt->rate)
                bch2_ratelimit_reset(ctxt->rate);
 
-       while (!move_ratelimit(&trans, ctxt)) {
-               bch2_trans_begin(&trans);
+       while (!move_ratelimit(trans, ctxt)) {
+               bch2_trans_begin(trans);
 
                k = bch2_btree_iter_peek(&iter);
                if (!k.k)
@@ -570,7 +569,7 @@ static int __bch2_move_data(struct moving_context *ctxt,
                if (!bkey_extent_is_direct_data(k.k))
                        goto next_nondata;
 
-               ret = move_get_io_opts(&trans, &io_opts, k, &cur_inum);
+               ret = move_get_io_opts(trans, &io_opts, k, &cur_inum);
                if (ret)
                        continue;
 
@@ -585,7 +584,7 @@ static int __bch2_move_data(struct moving_context *ctxt,
                bch2_bkey_buf_reassemble(&sk, c, k);
                k = bkey_i_to_s_c(sk.k);
 
-               ret2 = bch2_move_extent(&trans, &iter, ctxt, NULL,
+               ret2 = bch2_move_extent(trans, &iter, ctxt, NULL,
                                        io_opts, btree_id, k, data_opts);
                if (ret2) {
                        if (bch2_err_matches(ret2, BCH_ERR_transaction_restart))
@@ -593,7 +592,7 @@ static int __bch2_move_data(struct moving_context *ctxt,
 
                        if (ret2 == -ENOMEM) {
                                /* memory allocation failure, wait for some IO to finish */
-                               bch2_move_ctxt_wait_for_io(ctxt, &trans);
+                               bch2_move_ctxt_wait_for_io(ctxt, trans);
                                continue;
                        }
 
@@ -610,8 +609,8 @@ next_nondata:
                bch2_btree_iter_advance(&iter);
        }
 
-       bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_exit(trans, &iter);
+       bch2_trans_put(trans);
        bch2_bkey_buf_exit(&sk, c);
 
        return ret;
@@ -826,15 +825,14 @@ int bch2_evacuate_bucket(struct bch_fs *c,
                         struct write_point_specifier wp,
                         bool wait_on_copygc)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct moving_context ctxt;
        int ret;
 
-       bch2_trans_init(&trans, c, 0, 0);
        bch2_moving_ctxt_init(&ctxt, c, rate, stats, wp, wait_on_copygc);
-       ret = __bch2_evacuate_bucket(&trans, &ctxt, NULL, bucket, gen, data_opts);
+       ret = __bch2_evacuate_bucket(trans, &ctxt, NULL, bucket, gen, data_opts);
        bch2_moving_ctxt_exit(&ctxt);
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        return ret;
 }
@@ -851,14 +849,13 @@ static int bch2_move_btree(struct bch_fs *c,
 {
        bool kthread = (current->flags & PF_KTHREAD) != 0;
        struct bch_io_opts io_opts = bch2_opts_to_inode_opts(c->opts);
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct btree *b;
        enum btree_id id;
        struct data_update_opts data_opts;
        int ret = 0;
 
-       bch2_trans_init(&trans, c, 0, 0);
        progress_list_add(c, stats);
 
        stats->data_type = BCH_DATA_btree;
@@ -871,11 +868,11 @@ static int bch2_move_btree(struct bch_fs *c,
                if (!bch2_btree_id_root(c, id)->b)
                        continue;
 
-               bch2_trans_node_iter_init(&trans, &iter, id, POS_MIN, 0, 0,
+               bch2_trans_node_iter_init(trans, &iter, id, POS_MIN, 0, 0,
                                          BTREE_ITER_PREFETCH);
 retry:
                ret = 0;
-               while (bch2_trans_begin(&trans),
+               while (bch2_trans_begin(trans),
                       (b = bch2_btree_iter_peek_node(&iter)) &&
                       !(ret = PTR_ERR_OR_ZERO(b))) {
                        if (kthread && kthread_should_stop())
@@ -890,7 +887,7 @@ retry:
                        if (!pred(c, arg, b, &io_opts, &data_opts))
                                goto next;
 
-                       ret = bch2_btree_node_rewrite(&trans, &iter, b, 0) ?: ret;
+                       ret = bch2_btree_node_rewrite(trans, &iter, b, 0) ?: ret;
                        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                                continue;
                        if (ret)
@@ -901,13 +898,13 @@ next:
                if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                        goto retry;
 
-               bch2_trans_iter_exit(&trans, &iter);
+               bch2_trans_iter_exit(trans, &iter);
 
                if (kthread && kthread_should_stop())
                        break;
        }
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        if (ret)
                bch_err_fn(c, ret);
index 874c932..4017120 100644 (file)
@@ -300,7 +300,7 @@ void bch2_copygc_wait_to_text(struct printbuf *out, struct bch_fs *c)
 static int bch2_copygc_thread(void *arg)
 {
        struct bch_fs *c = arg;
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct moving_context ctxt;
        struct bch_move_stats move_stats;
        struct io_clock *clock = &c->io_clock[WRITE];
@@ -317,7 +317,7 @@ static int bch2_copygc_thread(void *arg)
        }
 
        set_freezable();
-       bch2_trans_init(&trans, c, 0, 0);
+       trans = bch2_trans_get(c);
 
        bch2_move_stats_init(&move_stats, "copygc");
        bch2_moving_ctxt_init(&ctxt, c, NULL, &move_stats,
@@ -325,16 +325,16 @@ static int bch2_copygc_thread(void *arg)
                              false);
 
        while (!ret && !kthread_should_stop()) {
-               bch2_trans_unlock(&trans);
+               bch2_trans_unlock(trans);
                cond_resched();
 
                if (!c->copy_gc_enabled) {
-                       move_buckets_wait(&trans, &ctxt, &buckets, true);
+                       move_buckets_wait(trans, &ctxt, &buckets, true);
                        kthread_wait_freezable(c->copy_gc_enabled);
                }
 
                if (unlikely(freezing(current))) {
-                       move_buckets_wait(&trans, &ctxt, &buckets, true);
+                       move_buckets_wait(trans, &ctxt, &buckets, true);
                        __refrigerator(false);
                        continue;
                }
@@ -345,7 +345,7 @@ static int bch2_copygc_thread(void *arg)
                if (wait > clock->max_slop) {
                        c->copygc_wait_at = last;
                        c->copygc_wait = last + wait;
-                       move_buckets_wait(&trans, &ctxt, &buckets, true);
+                       move_buckets_wait(trans, &ctxt, &buckets, true);
                        trace_and_count(c, copygc_wait, c, wait, last + wait);
                        bch2_kthread_io_clock_wait(clock, last + wait,
                                        MAX_SCHEDULE_TIMEOUT);
@@ -355,15 +355,15 @@ static int bch2_copygc_thread(void *arg)
                c->copygc_wait = 0;
 
                c->copygc_running = true;
-               ret = bch2_copygc(&trans, &ctxt, &buckets);
+               ret = bch2_copygc(trans, &ctxt, &buckets);
                c->copygc_running = false;
 
                wake_up(&c->copygc_running_wq);
        }
 
-       move_buckets_wait(&trans, &ctxt, &buckets, true);
+       move_buckets_wait(trans, &ctxt, &buckets, true);
        rhashtable_destroy(&buckets.table);
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        bch2_moving_ctxt_exit(&ctxt);
 
        return 0;
index f16aa3b..36de2f0 100644 (file)
@@ -599,7 +599,7 @@ advance:
 int bch2_fs_quota_read(struct bch_fs *c)
 {
        struct bch_sb_field_quota *sb_quota;
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter iter;
        struct bkey_s_c k;
        int ret;
@@ -614,16 +614,16 @@ int bch2_fs_quota_read(struct bch_fs *c)
        bch2_sb_quota_read(c);
        mutex_unlock(&c->sb_lock);
 
-       bch2_trans_init(&trans, c, 0, 0);
+       trans = bch2_trans_get(c);
 
-       ret = for_each_btree_key2(&trans, iter, BTREE_ID_quotas,
+       ret = for_each_btree_key2(trans, iter, BTREE_ID_quotas,
                        POS_MIN, BTREE_ITER_PREFETCH, k,
                __bch2_quota_set(c, k, NULL)) ?:
-             for_each_btree_key2(&trans, iter, BTREE_ID_inodes,
+             for_each_btree_key2(trans, iter, BTREE_ID_inodes,
                        POS_MIN, BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
-               bch2_fs_quota_read_inode(&trans, &iter, k));
+               bch2_fs_quota_read_inode(trans, &iter, k));
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        if (ret)
                bch_err_fn(c, ret);
@@ -956,7 +956,7 @@ static int bch2_set_quota(struct super_block *sb, struct kqid qid,
        new_quota.k.p = POS(qid.type, from_kqid(&init_user_ns, qid));
 
        ret = bch2_trans_do(c, NULL, NULL, 0,
-                           bch2_set_quota_trans(&trans, &new_quota, qdq)) ?:
+                           bch2_set_quota_trans(trans, &new_quota, qdq)) ?:
                __bch2_quota_set(c, bkey_i_to_s_c(&new_quota.k_i), qdq);
 
        return bch2_err_class(ret);
index f566c94..1dceb7e 100644 (file)
@@ -165,7 +165,7 @@ static int bch2_journal_replay(struct bch_fs *c)
                                    (!k->allocated
                                     ? BTREE_INSERT_JOURNAL_REPLAY|BCH_WATERMARK_reclaim
                                     : 0),
-                            bch2_journal_replay_key(&trans, k));
+                            bch2_journal_replay_key(trans, k));
                if (ret) {
                        bch_err(c, "journal replay: error while replaying key at btree %s level %u: %s",
                                bch2_btree_ids[k->btree_id], k->level, bch2_err_str(ret));
@@ -466,7 +466,7 @@ noinline_for_stack
 static int bch2_fs_upgrade_for_subvolumes(struct bch_fs *c)
 {
        int ret = bch2_trans_do(c, NULL, NULL, BTREE_INSERT_LAZY_RW,
-                               __bch2_fs_upgrade_for_subvolumes(&trans));
+                               __bch2_fs_upgrade_for_subvolumes(trans));
        if (ret)
                bch_err_fn(c, ret);
        return ret;
@@ -1013,7 +1013,7 @@ int bch2_fs_initialize(struct bch_fs *c)
        bch2_inode_init_early(c, &lostfound_inode);
 
        ret = bch2_trans_do(c, NULL, NULL, 0,
-               bch2_create_trans(&trans,
+               bch2_create_trans(trans,
                                  BCACHEFS_ROOT_SUBVOL_INUM,
                                  &root_inode, &lostfound_inode,
                                  &lostfound,
index fb605b2..d77d0ea 100644 (file)
@@ -253,7 +253,7 @@ s64 bch2_remap_range(struct bch_fs *c,
                     u64 remap_sectors,
                     u64 new_i_size, s64 *i_sectors_delta)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter dst_iter, src_iter;
        struct bkey_s_c src_k;
        struct bkey_buf new_dst, new_src;
@@ -275,11 +275,11 @@ s64 bch2_remap_range(struct bch_fs *c,
 
        bch2_bkey_buf_init(&new_dst);
        bch2_bkey_buf_init(&new_src);
-       bch2_trans_init(&trans, c, BTREE_ITER_MAX, 4096);
+       trans = bch2_trans_get(c);
 
-       bch2_trans_iter_init(&trans, &src_iter, BTREE_ID_extents, src_start,
+       bch2_trans_iter_init(trans, &src_iter, BTREE_ID_extents, src_start,
                             BTREE_ITER_INTENT);
-       bch2_trans_iter_init(&trans, &dst_iter, BTREE_ID_extents, dst_start,
+       bch2_trans_iter_init(trans, &dst_iter, BTREE_ID_extents, dst_start,
                             BTREE_ITER_INTENT);
 
        while ((ret == 0 ||
@@ -287,21 +287,21 @@ s64 bch2_remap_range(struct bch_fs *c,
               bkey_lt(dst_iter.pos, dst_end)) {
                struct disk_reservation disk_res = { 0 };
 
-               bch2_trans_begin(&trans);
+               bch2_trans_begin(trans);
 
                if (fatal_signal_pending(current)) {
                        ret = -EINTR;
                        break;
                }
 
-               ret = bch2_subvolume_get_snapshot(&trans, src_inum.subvol,
+               ret = bch2_subvolume_get_snapshot(trans, src_inum.subvol,
                                                  &src_snapshot);
                if (ret)
                        continue;
 
                bch2_btree_iter_set_snapshot(&src_iter, src_snapshot);
 
-               ret = bch2_subvolume_get_snapshot(&trans, dst_inum.subvol,
+               ret = bch2_subvolume_get_snapshot(trans, dst_inum.subvol,
                                                  &dst_snapshot);
                if (ret)
                        continue;
@@ -318,7 +318,7 @@ s64 bch2_remap_range(struct bch_fs *c,
                        continue;
 
                if (bkey_lt(src_want, src_iter.pos)) {
-                       ret = bch2_fpunch_at(&trans, &dst_iter, dst_inum,
+                       ret = bch2_fpunch_at(trans, &dst_iter, dst_inum,
                                        min(dst_end.offset,
                                            dst_iter.pos.offset +
                                            src_iter.pos.offset - src_want.offset),
@@ -332,7 +332,7 @@ s64 bch2_remap_range(struct bch_fs *c,
                        bch2_bkey_buf_reassemble(&new_src, c, src_k);
                        src_k = bkey_i_to_s_c(new_src.k);
 
-                       ret = bch2_make_extent_indirect(&trans, &src_iter,
+                       ret = bch2_make_extent_indirect(trans, &src_iter,
                                                new_src.k);
                        if (ret)
                                continue;
@@ -360,14 +360,14 @@ s64 bch2_remap_range(struct bch_fs *c,
                                min(src_k.k->p.offset - src_want.offset,
                                    dst_end.offset - dst_iter.pos.offset));
 
-               ret = bch2_extent_update(&trans, dst_inum, &dst_iter,
+               ret = bch2_extent_update(trans, dst_inum, &dst_iter,
                                         new_dst.k, &disk_res,
                                         new_i_size, i_sectors_delta,
                                         true);
                bch2_disk_reservation_put(c, &disk_res);
        }
-       bch2_trans_iter_exit(&trans, &dst_iter);
-       bch2_trans_iter_exit(&trans, &src_iter);
+       bch2_trans_iter_exit(trans, &dst_iter);
+       bch2_trans_iter_exit(trans, &src_iter);
 
        BUG_ON(!ret && !bkey_eq(dst_iter.pos, dst_end));
        BUG_ON(bkey_gt(dst_iter.pos, dst_end));
@@ -379,23 +379,23 @@ s64 bch2_remap_range(struct bch_fs *c,
                struct bch_inode_unpacked inode_u;
                struct btree_iter inode_iter = { NULL };
 
-               bch2_trans_begin(&trans);
+               bch2_trans_begin(trans);
 
-               ret2 = bch2_inode_peek(&trans, &inode_iter, &inode_u,
+               ret2 = bch2_inode_peek(trans, &inode_iter, &inode_u,
                                       dst_inum, BTREE_ITER_INTENT);
 
                if (!ret2 &&
                    inode_u.bi_size < new_i_size) {
                        inode_u.bi_size = new_i_size;
-                       ret2  = bch2_inode_write(&trans, &inode_iter, &inode_u) ?:
-                               bch2_trans_commit(&trans, NULL, NULL,
+                       ret2  = bch2_inode_write(trans, &inode_iter, &inode_u) ?:
+                               bch2_trans_commit(trans, NULL, NULL,
                                                  BTREE_INSERT_NOFAIL);
                }
 
-               bch2_trans_iter_exit(&trans, &inode_iter);
+               bch2_trans_iter_exit(trans, &inode_iter);
        } while (bch2_err_matches(ret2, BCH_ERR_transaction_restart));
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        bch2_bkey_buf_exit(&new_src, c);
        bch2_bkey_buf_exit(&new_dst, c);
 
index 73fca04..ff7f715 100644 (file)
@@ -610,11 +610,11 @@ int bch2_check_snapshot_trees(struct bch_fs *c)
        int ret;
 
        ret = bch2_trans_run(c,
-               for_each_btree_key_commit(&trans, iter,
+               for_each_btree_key_commit(trans, iter,
                        BTREE_ID_snapshot_trees, POS_MIN,
                        BTREE_ITER_PREFETCH, k,
                        NULL, NULL, BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
-               check_snapshot_tree(&trans, &iter, k)));
+               check_snapshot_tree(trans, &iter, k)));
 
        if (ret)
                bch_err(c, "error %i checking snapshot trees", ret);
@@ -883,11 +883,11 @@ int bch2_check_snapshots(struct bch_fs *c)
         * the parent's depth already be correct:
         */
        ret = bch2_trans_run(c,
-               for_each_btree_key_reverse_commit(&trans, iter,
+               for_each_btree_key_reverse_commit(trans, iter,
                        BTREE_ID_snapshots, POS_MAX,
                        BTREE_ITER_PREFETCH, k,
                        NULL, NULL, BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
-               check_snapshot(&trans, &iter, k)));
+               check_snapshot(trans, &iter, k)));
        if (ret)
                bch_err_fn(c, ret);
        return ret;
@@ -1373,7 +1373,7 @@ static int bch2_fix_child_of_deleted_snapshot(struct btree_trans *trans,
 
 int bch2_delete_dead_snapshots(struct bch_fs *c)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bkey_s_c_snapshot snap;
@@ -1390,30 +1390,30 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
                }
        }
 
-       bch2_trans_init(&trans, c, 0, 0);
+       trans = bch2_trans_get(c);
 
        /*
         * For every snapshot node: If we have no live children and it's not
         * pointed to by a subvolume, delete it:
         */
-       ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_snapshots,
+       ret = for_each_btree_key_commit(trans, iter, BTREE_ID_snapshots,
                        POS_MIN, 0, k,
                        NULL, NULL, 0,
-               bch2_delete_redundant_snapshot(&trans, &iter, k));
+               bch2_delete_redundant_snapshot(trans, &iter, k));
        if (ret) {
                bch_err_msg(c, ret, "deleting redundant snapshots");
                goto err;
        }
 
-       for_each_btree_key2(&trans, iter, BTREE_ID_snapshots,
+       for_each_btree_key2(trans, iter, BTREE_ID_snapshots,
                           POS_MIN, 0, k,
-               bch2_snapshot_set_equiv(&trans, k));
+               bch2_snapshot_set_equiv(trans, k));
        if (ret) {
                bch_err_msg(c, ret, "in bch2_snapshots_set_equiv");
                goto err;
        }
 
-       for_each_btree_key(&trans, iter, BTREE_ID_snapshots,
+       for_each_btree_key(trans, iter, BTREE_ID_snapshots,
                           POS_MIN, 0, k, ret) {
                if (k.k->type != KEY_TYPE_snapshot)
                        continue;
@@ -1425,7 +1425,7 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
                                break;
                }
        }
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 
        if (ret) {
                bch_err_msg(c, ret, "walking snapshots");
@@ -1440,16 +1440,16 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
                if (!btree_type_has_snapshots(id))
                        continue;
 
-               ret = for_each_btree_key_commit(&trans, iter,
+               ret = for_each_btree_key_commit(trans, iter,
                                id, POS_MIN,
                                BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
                                &res, NULL, BTREE_INSERT_NOFAIL,
-                       snapshot_delete_key(&trans, &iter, k, &deleted, &equiv_seen, &last_pos)) ?:
-                     for_each_btree_key_commit(&trans, iter,
+                       snapshot_delete_key(trans, &iter, k, &deleted, &equiv_seen, &last_pos)) ?:
+                     for_each_btree_key_commit(trans, iter,
                                id, POS_MIN,
                                BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
                                &res, NULL, BTREE_INSERT_NOFAIL,
-                       move_key_to_correct_snapshot(&trans, &iter, k));
+                       move_key_to_correct_snapshot(trans, &iter, k));
 
                bch2_disk_reservation_put(c, &res);
                darray_exit(&equiv_seen);
@@ -1460,7 +1460,7 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
                }
        }
 
-       for_each_btree_key(&trans, iter, BTREE_ID_snapshots,
+       for_each_btree_key(trans, iter, BTREE_ID_snapshots,
                           POS_MIN, 0, k, ret) {
                u32 snapshot = k.k->p.offset;
                u32 equiv = bch2_snapshot_equiv(c, snapshot);
@@ -1468,23 +1468,23 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
                if (equiv != snapshot)
                        snapshot_list_add(c, &deleted_interior, snapshot);
        }
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 
        /*
         * Fixing children of deleted snapshots can't be done completely
         * atomically, if we crash between here and when we delete the interior
         * nodes some depth fields will be off:
         */
-       ret = for_each_btree_key_commit(&trans, iter, BTREE_ID_snapshots, POS_MIN,
+       ret = for_each_btree_key_commit(trans, iter, BTREE_ID_snapshots, POS_MIN,
                                  BTREE_ITER_INTENT, k,
                                  NULL, NULL, BTREE_INSERT_NOFAIL,
-               bch2_fix_child_of_deleted_snapshot(&trans, &iter, k, &deleted_interior));
+               bch2_fix_child_of_deleted_snapshot(trans, &iter, k, &deleted_interior));
        if (ret)
                goto err;
 
        darray_for_each(deleted, i) {
-               ret = commit_do(&trans, NULL, NULL, 0,
-                       bch2_snapshot_node_delete(&trans, *i));
+               ret = commit_do(trans, NULL, NULL, 0,
+                       bch2_snapshot_node_delete(trans, *i));
                if (ret) {
                        bch_err_msg(c, ret, "deleting snapshot %u", *i);
                        goto err;
@@ -1492,8 +1492,8 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
        }
 
        darray_for_each(deleted_interior, i) {
-               ret = commit_do(&trans, NULL, NULL, 0,
-                       bch2_snapshot_node_delete(&trans, *i));
+               ret = commit_do(trans, NULL, NULL, 0,
+                       bch2_snapshot_node_delete(trans, *i));
                if (ret) {
                        bch_err_msg(c, ret, "deleting snapshot %u", *i);
                        goto err;
@@ -1504,7 +1504,7 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
 err:
        darray_exit(&deleted_interior);
        darray_exit(&deleted);
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        if (ret)
                bch_err_fn(c, ret);
        return ret;
@@ -1671,11 +1671,11 @@ int bch2_snapshots_read(struct bch_fs *c)
        int ret = 0;
 
        ret = bch2_trans_run(c,
-               for_each_btree_key2(&trans, iter, BTREE_ID_snapshots,
+               for_each_btree_key2(trans, iter, BTREE_ID_snapshots,
                           POS_MIN, 0, k,
-                       bch2_mark_snapshot(&trans, BTREE_ID_snapshots, 0, bkey_s_c_null, k, 0) ?:
-                       bch2_snapshot_set_equiv(&trans, k)) ?:
-               for_each_btree_key2(&trans, iter, BTREE_ID_snapshots,
+                       bch2_mark_snapshot(trans, BTREE_ID_snapshots, 0, bkey_s_c_null, k, 0) ?:
+                       bch2_snapshot_set_equiv(trans, k)) ?:
+               for_each_btree_key2(trans, iter, BTREE_ID_snapshots,
                           POS_MIN, 0, k,
                           (set_is_ancestor_bitmap(c, k.k->p.offset), 0)));
        if (ret)
index ca03d58..caf2dd7 100644 (file)
@@ -86,10 +86,10 @@ int bch2_check_subvols(struct bch_fs *c)
        int ret;
 
        ret = bch2_trans_run(c,
-               for_each_btree_key_commit(&trans, iter,
+               for_each_btree_key_commit(trans, iter,
                        BTREE_ID_subvolumes, POS_MIN, BTREE_ITER_PREFETCH, k,
                        NULL, NULL, BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL,
-               check_subvol(&trans, &iter, k)));
+               check_subvol(trans, &iter, k)));
        if (ret)
                bch_err_fn(c, ret);
        return ret;
@@ -293,7 +293,7 @@ static void bch2_subvolume_wait_for_pagecache_and_delete(struct work_struct *wor
                bch2_evict_subvolume_inodes(c, &s);
 
                for (id = s.data; id < s.data + s.nr; id++) {
-                       ret = bch2_trans_run(c, bch2_subvolume_delete(&trans, *id));
+                       ret = bch2_trans_run(c, bch2_subvolume_delete(trans, *id));
                        if (ret) {
                                bch_err_msg(c, ret, "deleting subvolume %u", *id);
                                break;
index 332951b..a00dc4a 100644 (file)
@@ -470,7 +470,6 @@ int bch2_fs_read_write_early(struct bch_fs *c)
 static void __bch2_fs_free(struct bch_fs *c)
 {
        unsigned i;
-       int cpu;
 
        for (i = 0; i < BCH_TIME_STAT_NR; i++)
                bch2_time_stats_exit(&c->times[i]);
@@ -502,12 +501,7 @@ static void __bch2_fs_free(struct bch_fs *c)
        percpu_free_rwsem(&c->mark_lock);
        free_percpu(c->online_reserved);
 
-       if (c->btree_paths_bufs)
-               for_each_possible_cpu(cpu)
-                       kfree(per_cpu_ptr(c->btree_paths_bufs, cpu)->path);
-
        darray_exit(&c->btree_roots_extra);
-       free_percpu(c->btree_paths_bufs);
        free_percpu(c->pcpu);
        mempool_exit(&c->large_bkey_pool);
        mempool_exit(&c->btree_bounce_pool);
@@ -829,7 +823,6 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
                        BIOSET_NEED_BVECS) ||
            !(c->pcpu = alloc_percpu(struct bch_fs_pcpu)) ||
            !(c->online_reserved = alloc_percpu(u64)) ||
-           !(c->btree_paths_bufs = alloc_percpu(struct btree_path_buf)) ||
            mempool_init_kvpmalloc_pool(&c->btree_bounce_pool, 1,
                                        btree_bytes(c)) ||
            mempool_init_kmalloc_pool(&c->large_bkey_pool, 1, 2048) ||
index 1e26c26..03dbea4 100644 (file)
@@ -252,7 +252,7 @@ static size_t bch2_btree_cache_size(struct bch_fs *c)
 
 static int bch2_compression_stats_to_text(struct printbuf *out, struct bch_fs *c)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter iter;
        struct bkey_s_c k;
        enum btree_id id;
@@ -268,13 +268,13 @@ static int bch2_compression_stats_to_text(struct printbuf *out, struct bch_fs *c
        if (!test_bit(BCH_FS_STARTED, &c->flags))
                return -EPERM;
 
-       bch2_trans_init(&trans, c, 0, 0);
+       trans = bch2_trans_get(c);
 
        for (id = 0; id < BTREE_ID_NR; id++) {
                if (!btree_type_has_ptrs(id))
                        continue;
 
-               for_each_btree_key(&trans, iter, id, POS_MIN,
+               for_each_btree_key(trans, iter, id, POS_MIN,
                                   BTREE_ITER_ALL_SNAPSHOTS, k, ret) {
                        struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
                        const union bch_extent_entry *entry;
@@ -308,10 +308,10 @@ static int bch2_compression_stats_to_text(struct printbuf *out, struct bch_fs *c
                        else if (compressed)
                                nr_compressed_extents++;
                }
-               bch2_trans_iter_exit(&trans, &iter);
+               bch2_trans_iter_exit(trans, &iter);
        }
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        if (ret)
                return ret;
index 18ccb37..c907b3e 100644 (file)
@@ -31,7 +31,7 @@ static void delete_test_keys(struct bch_fs *c)
 
 static int test_delete(struct bch_fs *c, u64 nr)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_i_cookie k;
        int ret;
@@ -39,44 +39,43 @@ static int test_delete(struct bch_fs *c, u64 nr)
        bkey_cookie_init(&k.k_i);
        k.k.p.snapshot = U32_MAX;
 
-       bch2_trans_init(&trans, c, 0, 0);
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_xattrs, k.k.p,
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_xattrs, k.k.p,
                             BTREE_ITER_INTENT);
 
-       ret = commit_do(&trans, NULL, NULL, 0,
+       ret = commit_do(trans, NULL, NULL, 0,
                bch2_btree_iter_traverse(&iter) ?:
-               bch2_trans_update(&trans, &iter, &k.k_i, 0));
+               bch2_trans_update(trans, &iter, &k.k_i, 0));
        if (ret) {
                bch_err_msg(c, ret, "update error");
                goto err;
        }
 
        pr_info("deleting once");
-       ret = commit_do(&trans, NULL, NULL, 0,
+       ret = commit_do(trans, NULL, NULL, 0,
                bch2_btree_iter_traverse(&iter) ?:
-               bch2_btree_delete_at(&trans, &iter, 0));
+               bch2_btree_delete_at(trans, &iter, 0));
        if (ret) {
                bch_err_msg(c, ret, "delete error (first)");
                goto err;
        }
 
        pr_info("deleting twice");
-       ret = commit_do(&trans, NULL, NULL, 0,
+       ret = commit_do(trans, NULL, NULL, 0,
                bch2_btree_iter_traverse(&iter) ?:
-               bch2_btree_delete_at(&trans, &iter, 0));
+               bch2_btree_delete_at(trans, &iter, 0));
        if (ret) {
                bch_err_msg(c, ret, "delete error (second)");
                goto err;
        }
 err:
-       bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_exit(trans, &iter);
+       bch2_trans_put(trans);
        return ret;
 }
 
 static int test_delete_written(struct bch_fs *c, u64 nr)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_i_cookie k;
        int ret;
@@ -84,45 +83,41 @@ static int test_delete_written(struct bch_fs *c, u64 nr)
        bkey_cookie_init(&k.k_i);
        k.k.p.snapshot = U32_MAX;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_xattrs, k.k.p,
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_xattrs, k.k.p,
                             BTREE_ITER_INTENT);
 
-       ret = commit_do(&trans, NULL, NULL, 0,
+       ret = commit_do(trans, NULL, NULL, 0,
                bch2_btree_iter_traverse(&iter) ?:
-               bch2_trans_update(&trans, &iter, &k.k_i, 0));
+               bch2_trans_update(trans, &iter, &k.k_i, 0));
        if (ret) {
                bch_err_msg(c, ret, "update error");
                goto err;
        }
 
-       bch2_trans_unlock(&trans);
+       bch2_trans_unlock(trans);
        bch2_journal_flush_all_pins(&c->journal);
 
-       ret = commit_do(&trans, NULL, NULL, 0,
+       ret = commit_do(trans, NULL, NULL, 0,
                bch2_btree_iter_traverse(&iter) ?:
-               bch2_btree_delete_at(&trans, &iter, 0));
+               bch2_btree_delete_at(trans, &iter, 0));
        if (ret) {
                bch_err_msg(c, ret, "delete error");
                goto err;
        }
 err:
-       bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_exit(trans, &iter);
+       bch2_trans_put(trans);
        return ret;
 }
 
 static int test_iterate(struct bch_fs *c, u64 nr)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter = { NULL };
        struct bkey_s_c k;
        u64 i;
        int ret = 0;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
        delete_test_keys(c);
 
        pr_info("inserting test keys");
@@ -145,7 +140,7 @@ static int test_iterate(struct bch_fs *c, u64 nr)
 
        i = 0;
 
-       ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_xattrs,
+       ret = for_each_btree_key2_upto(trans, iter, BTREE_ID_xattrs,
                                  SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
                                  0, k, ({
                BUG_ON(k.k->p.offset != i++);
@@ -160,7 +155,7 @@ static int test_iterate(struct bch_fs *c, u64 nr)
 
        pr_info("iterating backwards");
 
-       ret = for_each_btree_key_reverse(&trans, iter, BTREE_ID_xattrs,
+       ret = for_each_btree_key_reverse(trans, iter, BTREE_ID_xattrs,
                                         SPOS(0, U64_MAX, U32_MAX), 0, k,
                ({
                        BUG_ON(k.k->p.offset != --i);
@@ -173,21 +168,19 @@ static int test_iterate(struct bch_fs *c, u64 nr)
 
        BUG_ON(i);
 err:
-       bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_exit(trans, &iter);
+       bch2_trans_put(trans);
        return ret;
 }
 
 static int test_iterate_extents(struct bch_fs *c, u64 nr)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter = { NULL };
        struct bkey_s_c k;
        u64 i;
        int ret = 0;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
        delete_test_keys(c);
 
        pr_info("inserting test extents");
@@ -211,7 +204,7 @@ static int test_iterate_extents(struct bch_fs *c, u64 nr)
 
        i = 0;
 
-       ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_extents,
+       ret = for_each_btree_key2_upto(trans, iter, BTREE_ID_extents,
                                  SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
                                  0, k, ({
                BUG_ON(bkey_start_offset(k.k) != i);
@@ -227,7 +220,7 @@ static int test_iterate_extents(struct bch_fs *c, u64 nr)
 
        pr_info("iterating backwards");
 
-       ret = for_each_btree_key_reverse(&trans, iter, BTREE_ID_extents,
+       ret = for_each_btree_key_reverse(trans, iter, BTREE_ID_extents,
                                         SPOS(0, U64_MAX, U32_MAX), 0, k,
                ({
                        BUG_ON(k.k->p.offset != i);
@@ -241,21 +234,19 @@ static int test_iterate_extents(struct bch_fs *c, u64 nr)
 
        BUG_ON(i);
 err:
-       bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_exit(trans, &iter);
+       bch2_trans_put(trans);
        return ret;
 }
 
 static int test_iterate_slots(struct bch_fs *c, u64 nr)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter = { NULL };
        struct bkey_s_c k;
        u64 i;
        int ret = 0;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
        delete_test_keys(c);
 
        pr_info("inserting test keys");
@@ -278,7 +269,7 @@ static int test_iterate_slots(struct bch_fs *c, u64 nr)
 
        i = 0;
 
-       ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_xattrs,
+       ret = for_each_btree_key2_upto(trans, iter, BTREE_ID_xattrs,
                                  SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
                                  0, k, ({
                BUG_ON(k.k->p.offset != i);
@@ -296,7 +287,7 @@ static int test_iterate_slots(struct bch_fs *c, u64 nr)
 
        i = 0;
 
-       ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_xattrs,
+       ret = for_each_btree_key2_upto(trans, iter, BTREE_ID_xattrs,
                                  SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
                                  BTREE_ITER_SLOTS, k, ({
                if (i >= nr * 2)
@@ -314,20 +305,18 @@ static int test_iterate_slots(struct bch_fs *c, u64 nr)
        }
        ret = 0;
 err:
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        return ret;
 }
 
 static int test_iterate_slots_extents(struct bch_fs *c, u64 nr)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter = { NULL };
        struct bkey_s_c k;
        u64 i;
        int ret = 0;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
        delete_test_keys(c);
 
        pr_info("inserting test keys");
@@ -351,7 +340,7 @@ static int test_iterate_slots_extents(struct bch_fs *c, u64 nr)
 
        i = 0;
 
-       ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_extents,
+       ret = for_each_btree_key2_upto(trans, iter, BTREE_ID_extents,
                                  SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
                                  0, k, ({
                BUG_ON(bkey_start_offset(k.k) != i + 8);
@@ -370,7 +359,7 @@ static int test_iterate_slots_extents(struct bch_fs *c, u64 nr)
 
        i = 0;
 
-       ret = for_each_btree_key2_upto(&trans, iter, BTREE_ID_extents,
+       ret = for_each_btree_key2_upto(trans, iter, BTREE_ID_extents,
                                 SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
                                 BTREE_ITER_SLOTS, k, ({
                if (i == nr)
@@ -388,7 +377,7 @@ static int test_iterate_slots_extents(struct bch_fs *c, u64 nr)
        }
        ret = 0;
 err:
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        return 0;
 }
 
@@ -398,43 +387,41 @@ err:
  */
 static int test_peek_end(struct bch_fs *c, u64 nr)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
 
-       bch2_trans_init(&trans, c, 0, 0);
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_xattrs,
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_xattrs,
                             SPOS(0, 0, U32_MAX), 0);
 
-       lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
+       lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
        BUG_ON(k.k);
 
-       lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
+       lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
        BUG_ON(k.k);
 
-       bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_exit(trans, &iter);
+       bch2_trans_put(trans);
        return 0;
 }
 
 static int test_peek_end_extents(struct bch_fs *c, u64 nr)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
 
-       bch2_trans_init(&trans, c, 0, 0);
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_extents,
                             SPOS(0, 0, U32_MAX), 0);
 
-       lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
+       lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
        BUG_ON(k.k);
 
-       lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
+       lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
        BUG_ON(k.k);
 
-       bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_exit(trans, &iter);
+       bch2_trans_put(trans);
        return 0;
 }
 
@@ -510,7 +497,7 @@ static int insert_test_overlapping_extent(struct bch_fs *c, u64 inum, u64 start,
        k.k_i.k.size = len;
 
        ret = bch2_trans_do(c, NULL, NULL, 0,
-               bch2_btree_insert_nonextent(&trans, BTREE_ID_extents, &k.k_i,
+               bch2_btree_insert_nonextent(trans, BTREE_ID_extents, &k.k_i,
                                            BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE));
        if (ret)
                bch_err_fn(c, ret);
@@ -533,7 +520,7 @@ static int test_extent_create_overlapping(struct bch_fs *c, u64 inum)
 /* Test skipping over keys in unrelated snapshots: */
 static int test_snapshot_filter(struct bch_fs *c, u32 snapid_lo, u32 snapid_hi)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans;
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bkey_i_cookie cookie;
@@ -545,15 +532,15 @@ static int test_snapshot_filter(struct bch_fs *c, u32 snapid_lo, u32 snapid_hi)
        if (ret)
                return ret;
 
-       bch2_trans_init(&trans, c, 0, 0);
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_xattrs,
+       trans = bch2_trans_get(c);
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_xattrs,
                             SPOS(0, 0, snapid_lo), 0);
-       lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
+       lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_upto(&iter, POS(0, U64_MAX))));
 
        BUG_ON(k.k->p.snapshot != U32_MAX);
 
-       bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_exit(trans, &iter);
+       bch2_trans_put(trans);
        return ret;
 }
 
@@ -571,7 +558,7 @@ static int test_snapshots(struct bch_fs *c, u64 nr)
                return ret;
 
        ret = bch2_trans_do(c, NULL, NULL, 0,
-                     bch2_snapshot_node_create(&trans, U32_MAX,
+                     bch2_snapshot_node_create(trans, U32_MAX,
                                                snapids,
                                                snapid_subvols,
                                                2));
@@ -602,38 +589,34 @@ static u64 test_rand(void)
 
 static int rand_insert(struct bch_fs *c, u64 nr)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct bkey_i_cookie k;
        int ret = 0;
        u64 i;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
        for (i = 0; i < nr; i++) {
                bkey_cookie_init(&k.k_i);
                k.k.p.offset = test_rand();
                k.k.p.snapshot = U32_MAX;
 
-               ret = commit_do(&trans, NULL, NULL, 0,
-                       bch2_btree_insert_trans(&trans, BTREE_ID_xattrs, &k.k_i, 0));
+               ret = commit_do(trans, NULL, NULL, 0,
+                       bch2_btree_insert_trans(trans, BTREE_ID_xattrs, &k.k_i, 0));
                if (ret)
                        break;
        }
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        return ret;
 }
 
 static int rand_insert_multi(struct bch_fs *c, u64 nr)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct bkey_i_cookie k[8];
        int ret = 0;
        unsigned j;
        u64 i;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
        for (i = 0; i < nr; i += ARRAY_SIZE(k)) {
                for (j = 0; j < ARRAY_SIZE(k); j++) {
                        bkey_cookie_init(&k[j].k_i);
@@ -641,46 +624,45 @@ static int rand_insert_multi(struct bch_fs *c, u64 nr)
                        k[j].k.p.snapshot = U32_MAX;
                }
 
-               ret = commit_do(&trans, NULL, NULL, 0,
-                       bch2_btree_insert_trans(&trans, BTREE_ID_xattrs, &k[0].k_i, 0) ?:
-                       bch2_btree_insert_trans(&trans, BTREE_ID_xattrs, &k[1].k_i, 0) ?:
-                       bch2_btree_insert_trans(&trans, BTREE_ID_xattrs, &k[2].k_i, 0) ?:
-                       bch2_btree_insert_trans(&trans, BTREE_ID_xattrs, &k[3].k_i, 0) ?:
-                       bch2_btree_insert_trans(&trans, BTREE_ID_xattrs, &k[4].k_i, 0) ?:
-                       bch2_btree_insert_trans(&trans, BTREE_ID_xattrs, &k[5].k_i, 0) ?:
-                       bch2_btree_insert_trans(&trans, BTREE_ID_xattrs, &k[6].k_i, 0) ?:
-                       bch2_btree_insert_trans(&trans, BTREE_ID_xattrs, &k[7].k_i, 0));
+               ret = commit_do(trans, NULL, NULL, 0,
+                       bch2_btree_insert_trans(trans, BTREE_ID_xattrs, &k[0].k_i, 0) ?:
+                       bch2_btree_insert_trans(trans, BTREE_ID_xattrs, &k[1].k_i, 0) ?:
+                       bch2_btree_insert_trans(trans, BTREE_ID_xattrs, &k[2].k_i, 0) ?:
+                       bch2_btree_insert_trans(trans, BTREE_ID_xattrs, &k[3].k_i, 0) ?:
+                       bch2_btree_insert_trans(trans, BTREE_ID_xattrs, &k[4].k_i, 0) ?:
+                       bch2_btree_insert_trans(trans, BTREE_ID_xattrs, &k[5].k_i, 0) ?:
+                       bch2_btree_insert_trans(trans, BTREE_ID_xattrs, &k[6].k_i, 0) ?:
+                       bch2_btree_insert_trans(trans, BTREE_ID_xattrs, &k[7].k_i, 0));
                if (ret)
                        break;
        }
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        return ret;
 }
 
 static int rand_lookup(struct bch_fs *c, u64 nr)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        int ret = 0;
        u64 i;
 
-       bch2_trans_init(&trans, c, 0, 0);
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_xattrs,
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_xattrs,
                             SPOS(0, 0, U32_MAX), 0);
 
        for (i = 0; i < nr; i++) {
                bch2_btree_iter_set_pos(&iter, SPOS(0, test_rand(), U32_MAX));
 
-               lockrestart_do(&trans, bkey_err(k = bch2_btree_iter_peek(&iter)));
+               lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek(&iter)));
                ret = bkey_err(k);
                if (ret)
                        break;
        }
 
-       bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_exit(trans, &iter);
+       bch2_trans_put(trans);
        return ret;
 }
 
@@ -712,26 +694,25 @@ static int rand_mixed_trans(struct btree_trans *trans,
 
 static int rand_mixed(struct bch_fs *c, u64 nr)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_i_cookie cookie;
        int ret = 0;
        u64 i, rand;
 
-       bch2_trans_init(&trans, c, 0, 0);
-       bch2_trans_iter_init(&trans, &iter, BTREE_ID_xattrs,
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_xattrs,
                             SPOS(0, 0, U32_MAX), 0);
 
        for (i = 0; i < nr; i++) {
                rand = test_rand();
-               ret = commit_do(&trans, NULL, NULL, 0,
-                       rand_mixed_trans(&trans, &iter, &cookie, i, rand));
+               ret = commit_do(trans, NULL, NULL, 0,
+                       rand_mixed_trans(trans, &iter, &cookie, i, rand));
                if (ret)
                        break;
        }
 
-       bch2_trans_iter_exit(&trans, &iter);
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_exit(trans, &iter);
+       bch2_trans_put(trans);
        return ret;
 }
 
@@ -759,22 +740,20 @@ err:
 
 static int rand_delete(struct bch_fs *c, u64 nr)
 {
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        int ret = 0;
        u64 i;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
        for (i = 0; i < nr; i++) {
                struct bpos pos = SPOS(0, test_rand(), U32_MAX);
 
-               ret = commit_do(&trans, NULL, NULL, 0,
-                       __do_delete(&trans, pos));
+               ret = commit_do(trans, NULL, NULL, 0,
+                       __do_delete(trans, pos));
                if (ret)
                        break;
        }
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        return ret;
 }
 
@@ -787,14 +766,14 @@ static int seq_insert(struct bch_fs *c, u64 nr)
        bkey_cookie_init(&insert.k_i);
 
        return bch2_trans_run(c,
-               for_each_btree_key_commit(&trans, iter, BTREE_ID_xattrs,
+               for_each_btree_key_commit(trans, iter, BTREE_ID_xattrs,
                                        SPOS(0, 0, U32_MAX),
                                        BTREE_ITER_SLOTS|BTREE_ITER_INTENT, k,
                                        NULL, NULL, 0, ({
                        if (iter.pos.offset >= nr)
                                break;
                        insert.k.p = iter.pos;
-                       bch2_trans_update(&trans, &iter, &insert.k_i, 0);
+                       bch2_trans_update(trans, &iter, &insert.k_i, 0);
                })));
 }
 
@@ -804,7 +783,7 @@ static int seq_lookup(struct bch_fs *c, u64 nr)
        struct bkey_s_c k;
 
        return bch2_trans_run(c,
-               for_each_btree_key2_upto(&trans, iter, BTREE_ID_xattrs,
+               for_each_btree_key2_upto(trans, iter, BTREE_ID_xattrs,
                                  SPOS(0, 0, U32_MAX), POS(0, U64_MAX),
                                  0, k,
                0));
@@ -816,14 +795,14 @@ static int seq_overwrite(struct bch_fs *c, u64 nr)
        struct bkey_s_c k;
 
        return bch2_trans_run(c,
-               for_each_btree_key_commit(&trans, iter, BTREE_ID_xattrs,
+               for_each_btree_key_commit(trans, iter, BTREE_ID_xattrs,
                                        SPOS(0, 0, U32_MAX),
                                        BTREE_ITER_INTENT, k,
                                        NULL, NULL, 0, ({
                        struct bkey_i_cookie u;
 
                        bkey_reassemble(&u.k_i, k);
-                       bch2_trans_update(&trans, &iter, &u.k_i, 0);
+                       bch2_trans_update(trans, &iter, &u.k_i, 0);
                })));
 }
 
index 637174b..b069b1a 100644 (file)
@@ -307,24 +307,22 @@ ssize_t bch2_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
 {
        struct bch_fs *c = dentry->d_sb->s_fs_info;
        struct bch_inode_info *inode = to_bch_ei(dentry->d_inode);
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        struct btree_iter iter;
        struct bkey_s_c k;
        struct xattr_buf buf = { .buf = buffer, .len = buffer_size };
        u64 offset = 0, inum = inode->ei_inode.bi_inum;
        u32 snapshot;
        int ret;
-
-       bch2_trans_init(&trans, c, 0, 0);
 retry:
-       bch2_trans_begin(&trans);
+       bch2_trans_begin(trans);
        iter = (struct btree_iter) { NULL };
 
-       ret = bch2_subvolume_get_snapshot(&trans, inode->ei_subvol, &snapshot);
+       ret = bch2_subvolume_get_snapshot(trans, inode->ei_subvol, &snapshot);
        if (ret)
                goto err;
 
-       for_each_btree_key_upto_norestart(&trans, iter, BTREE_ID_xattrs,
+       for_each_btree_key_upto_norestart(trans, iter, BTREE_ID_xattrs,
                           SPOS(inum, offset, snapshot),
                           POS(inum, U64_MAX), 0, k, ret) {
                if (k.k->type != KEY_TYPE_xattr)
@@ -336,12 +334,12 @@ retry:
        }
 
        offset = iter.pos.offset;
-       bch2_trans_iter_exit(&trans, &iter);
+       bch2_trans_iter_exit(trans, &iter);
 err:
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
 
        if (ret)
                goto out;
@@ -366,7 +364,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,
-               bch2_xattr_get_trans(&trans, inode, name, buffer, size, handler->flags));
+               bch2_xattr_get_trans(trans, inode, name, buffer, size, handler->flags));
 
        return bch2_err_class(ret);
 }
@@ -381,18 +379,14 @@ static int bch2_xattr_set_handler(const struct xattr_handler *handler,
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
        struct bch_hash_info hash = bch2_hash_info_init(c, &inode->ei_inode);
        struct bch_inode_unpacked inode_u;
-       struct btree_trans trans;
        int ret;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
-       ret = commit_do(&trans, NULL, NULL, 0,
-                       bch2_xattr_set(&trans, inode_inum(inode), &inode_u,
+       ret = bch2_trans_run(c,
+               commit_do(trans, NULL, NULL, 0,
+                       bch2_xattr_set(trans, inode_inum(inode), &inode_u,
                                       &hash, name, value, size,
-                                      handler->flags, flags));
-       if (!ret)
-               bch2_inode_update_after_write(&trans, inode, &inode_u, ATTR_CTIME);
-       bch2_trans_exit(&trans);
+                                      handler->flags, flags)) ?:
+               (bch2_inode_update_after_write(trans, inode, &inode_u, ATTR_CTIME), 0));
 
        return bch2_err_class(ret);
 }