bcachefs: bch_fs.writes -> enumerated_refs
authorKent Overstreet <kent.overstreet@linux.dev>
Fri, 18 Apr 2025 18:56:09 +0000 (14:56 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Thu, 22 May 2025 00:14:27 +0000 (20:14 -0400)
Drop the single-purpose write ref code in bcachefs.h, and convert to
enumarated refs.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
18 files changed:
fs/bcachefs/alloc_background.c
fs/bcachefs/bcachefs.h
fs/bcachefs/btree_gc.c
fs/bcachefs/btree_io.c
fs/bcachefs/btree_trans_commit.c
fs/bcachefs/btree_update_interior.c
fs/bcachefs/btree_write_buffer.c
fs/bcachefs/ec.c
fs/bcachefs/fs-io-direct.c
fs/bcachefs/fs-io.c
fs/bcachefs/io_read.c
fs/bcachefs/io_write.c
fs/bcachefs/journal.c
fs/bcachefs/reflink.c
fs/bcachefs/snapshot.c
fs/bcachefs/subvolume.c
fs/bcachefs/super.c
fs/bcachefs/sysfs.c

index 195d20220b7dd790038bcdb98af7c1072ed65a2a..ced31309c54190fc5f233b8a83550876c93f3373 100644 (file)
@@ -17,6 +17,7 @@
 #include "debug.h"
 #include "disk_accounting.h"
 #include "ec.h"
+#include "enumerated_ref.h"
 #include "error.h"
 #include "lru.h"
 #include "recovery.h"
@@ -1381,7 +1382,7 @@ static void check_discard_freespace_key_work(struct work_struct *work)
                container_of(work, struct check_discard_freespace_key_async, work);
 
        bch2_trans_do(w->c, bch2_recheck_discard_freespace_key(trans, w->pos));
-       bch2_write_ref_put(w->c, BCH_WRITE_REF_check_discard_freespace_key);
+       enumerated_ref_put(&w->c->writes, BCH_WRITE_REF_check_discard_freespace_key);
        kfree(w);
 }
 
@@ -1458,7 +1459,7 @@ delete:
                if (!w)
                        goto out;
 
-               if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_check_discard_freespace_key)) {
+               if (!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_check_discard_freespace_key)) {
                        kfree(w);
                        goto out;
                }
@@ -1953,14 +1954,14 @@ static void bch2_do_discards_work(struct work_struct *work)
                              bch2_err_str(ret));
 
        percpu_ref_put(&ca->io_ref[WRITE]);
-       bch2_write_ref_put(c, BCH_WRITE_REF_discard);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_discard);
 }
 
 void bch2_dev_do_discards(struct bch_dev *ca)
 {
        struct bch_fs *c = ca->fs;
 
-       if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_discard))
+       if (!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_discard))
                return;
 
        if (!bch2_dev_get_ioref(c, ca->dev_idx, WRITE))
@@ -1971,7 +1972,7 @@ void bch2_dev_do_discards(struct bch_dev *ca)
 
        percpu_ref_put(&ca->io_ref[WRITE]);
 put_write_ref:
-       bch2_write_ref_put(c, BCH_WRITE_REF_discard);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_discard);
 }
 
 void bch2_do_discards(struct bch_fs *c)
@@ -2048,7 +2049,7 @@ static void bch2_do_discards_fast_work(struct work_struct *work)
 
        bch2_trans_put(trans);
        percpu_ref_put(&ca->io_ref[WRITE]);
-       bch2_write_ref_put(c, BCH_WRITE_REF_discard_fast);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_discard_fast);
 }
 
 static void bch2_discard_one_bucket_fast(struct bch_dev *ca, u64 bucket)
@@ -2058,7 +2059,7 @@ static void bch2_discard_one_bucket_fast(struct bch_dev *ca, u64 bucket)
        if (discard_in_flight_add(ca, bucket, false))
                return;
 
-       if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_discard_fast))
+       if (!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_discard_fast))
                return;
 
        if (!bch2_dev_get_ioref(c, ca->dev_idx, WRITE))
@@ -2069,7 +2070,7 @@ static void bch2_discard_one_bucket_fast(struct bch_dev *ca, u64 bucket)
 
        percpu_ref_put(&ca->io_ref[WRITE]);
 put_ref:
-       bch2_write_ref_put(c, BCH_WRITE_REF_discard_fast);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_discard_fast);
 }
 
 static int invalidate_one_bp(struct btree_trans *trans,
@@ -2263,14 +2264,14 @@ err:
        bch2_trans_put(trans);
        percpu_ref_put(&ca->io_ref[WRITE]);
        bch2_bkey_buf_exit(&last_flushed, c);
-       bch2_write_ref_put(c, BCH_WRITE_REF_invalidate);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_invalidate);
 }
 
 void bch2_dev_do_invalidates(struct bch_dev *ca)
 {
        struct bch_fs *c = ca->fs;
 
-       if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_invalidate))
+       if (!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_invalidate))
                return;
 
        if (!bch2_dev_get_ioref(c, ca->dev_idx, WRITE))
@@ -2281,7 +2282,7 @@ void bch2_dev_do_invalidates(struct bch_dev *ca)
 
        percpu_ref_put(&ca->io_ref[WRITE]);
 put_ref:
-       bch2_write_ref_put(c, BCH_WRITE_REF_invalidate);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_invalidate);
 }
 
 void bch2_do_invalidates(struct bch_fs *c)
index 1597259b708c0a6cc44fb106faf45d0971e1bbd2..ced80d4b606a3b7c00590d22e67265a9314be3b8 100644 (file)
 #include "util.h"
 
 #ifdef CONFIG_BCACHEFS_DEBUG
-#define BCH_WRITE_REF_DEBUG
+#define ENUMERATED_REF_DEBUG
 #endif
 
 #ifndef dynamic_fault
@@ -483,6 +483,7 @@ enum bch_time_stats {
 #include "clock_types.h"
 #include "disk_groups_types.h"
 #include "ec_types.h"
+#include "enumerated_ref_types.h"
 #include "journal_types.h"
 #include "keylist_types.h"
 #include "quota_types.h"
@@ -733,11 +734,7 @@ struct bch_fs {
        struct rw_semaphore     state_lock;
 
        /* Counts outstanding writes, for clean transition to read-only */
-#ifdef BCH_WRITE_REF_DEBUG
-       atomic_long_t           writes[BCH_WRITE_REF_NR];
-#else
-       struct percpu_ref       writes;
-#endif
+       struct enumerated_ref   writes;
        /*
         * Certain operations are only allowed in single threaded mode, during
         * recovery, and we want to assert that this is the case:
@@ -1115,54 +1112,6 @@ struct bch_fs {
 
 extern struct wait_queue_head bch2_read_only_wait;
 
-static inline void bch2_write_ref_get(struct bch_fs *c, enum bch_write_ref ref)
-{
-#ifdef BCH_WRITE_REF_DEBUG
-       atomic_long_inc(&c->writes[ref]);
-#else
-       percpu_ref_get(&c->writes);
-#endif
-}
-
-static inline bool __bch2_write_ref_tryget(struct bch_fs *c, enum bch_write_ref ref)
-{
-#ifdef BCH_WRITE_REF_DEBUG
-       return !test_bit(BCH_FS_going_ro, &c->flags) &&
-               atomic_long_inc_not_zero(&c->writes[ref]);
-#else
-       return percpu_ref_tryget(&c->writes);
-#endif
-}
-
-static inline bool bch2_write_ref_tryget(struct bch_fs *c, enum bch_write_ref ref)
-{
-#ifdef BCH_WRITE_REF_DEBUG
-       return !test_bit(BCH_FS_going_ro, &c->flags) &&
-               atomic_long_inc_not_zero(&c->writes[ref]);
-#else
-       return percpu_ref_tryget_live(&c->writes);
-#endif
-}
-
-static inline void bch2_write_ref_put(struct bch_fs *c, enum bch_write_ref ref)
-{
-#ifdef BCH_WRITE_REF_DEBUG
-       long v = atomic_long_dec_return(&c->writes[ref]);
-
-       BUG_ON(v < 0);
-       if (v)
-               return;
-       for (unsigned i = 0; i < BCH_WRITE_REF_NR; i++)
-               if (atomic_long_read(&c->writes[i]))
-                       return;
-
-       set_bit(BCH_FS_write_disable_complete, &c->flags);
-       wake_up(&bch2_read_only_wait);
-#else
-       percpu_ref_put(&c->writes);
-#endif
-}
-
 static inline bool bch2_ro_ref_tryget(struct bch_fs *c)
 {
        if (test_bit(BCH_FS_stopping, &c->flags))
index 1f02d28c175c3b1e95b4d6f62ded6a251ce04dd5..2e72784332ff631cad3a1aa2626b419ce89f7786 100644 (file)
@@ -22,6 +22,7 @@
 #include "debug.h"
 #include "disk_accounting.h"
 #include "ec.h"
+#include "enumerated_ref.h"
 #include "error.h"
 #include "extents.h"
 #include "journal.h"
@@ -1256,14 +1257,14 @@ static void bch2_gc_gens_work(struct work_struct *work)
 {
        struct bch_fs *c = container_of(work, struct bch_fs, gc_gens_work);
        bch2_gc_gens(c);
-       bch2_write_ref_put(c, BCH_WRITE_REF_gc_gens);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_gc_gens);
 }
 
 void bch2_gc_gens_async(struct bch_fs *c)
 {
-       if (bch2_write_ref_tryget(c, BCH_WRITE_REF_gc_gens) &&
+       if (enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_gc_gens) &&
            !queue_work(c->write_ref_wq, &c->gc_gens_work))
-               bch2_write_ref_put(c, BCH_WRITE_REF_gc_gens);
+               enumerated_ref_put(&c->writes, BCH_WRITE_REF_gc_gens);
 }
 
 void bch2_fs_btree_gc_init_early(struct bch_fs *c)
index c1c671e340c7518816879a66494fadad872aa59d..9e759d9e29b1f9faccbeae3cba94b46b0de7651b 100644 (file)
@@ -13,6 +13,7 @@
 #include "buckets.h"
 #include "checksum.h"
 #include "debug.h"
+#include "enumerated_ref.h"
 #include "error.h"
 #include "extents.h"
 #include "io_write.h"
@@ -1931,7 +1932,7 @@ err:
        btree_bounce_free(c, c->opts.btree_node_size, scrub->used_mempool, scrub->buf);
        percpu_ref_put(&scrub->ca->io_ref[READ]);
        kfree(scrub);
-       bch2_write_ref_put(c, BCH_WRITE_REF_btree_node_scrub);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_btree_node_scrub);
 }
 
 static void btree_node_scrub_endio(struct bio *bio)
@@ -1950,7 +1951,7 @@ int bch2_btree_node_scrub(struct btree_trans *trans,
 
        struct bch_fs *c = trans->c;
 
-       if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_btree_node_scrub))
+       if (!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_btree_node_scrub))
                return -BCH_ERR_erofs_no_writes;
 
        struct extent_ptr_decoded pick;
@@ -2000,7 +2001,7 @@ err_free:
        btree_bounce_free(c, c->opts.btree_node_size, used_mempool, buf);
        percpu_ref_put(&ca->io_ref[READ]);
 err:
-       bch2_write_ref_put(c, BCH_WRITE_REF_btree_node_scrub);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_btree_node_scrub);
        return ret;
 }
 
index 4297d8b5edddf7b4af3f5b389268dc6da2e51a79..cdde769e7da32ff58aa353a709ffcc90d7d2c49b 100644 (file)
@@ -11,6 +11,7 @@
 #include "btree_write_buffer.h"
 #include "buckets.h"
 #include "disk_accounting.h"
+#include "enumerated_ref.h"
 #include "errcode.h"
 #include "error.h"
 #include "journal.h"
@@ -994,7 +995,7 @@ int __bch2_trans_commit(struct btree_trans *trans, unsigned flags)
                goto out_reset;
 
        if (!(flags & BCH_TRANS_COMMIT_no_check_rw) &&
-           unlikely(!bch2_write_ref_tryget(c, BCH_WRITE_REF_trans))) {
+           unlikely(!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_trans))) {
                if (unlikely(!test_bit(BCH_FS_may_go_rw, &c->flags)))
                        ret = do_bch2_trans_commit_to_journal_replay(trans);
                else
@@ -1060,7 +1061,7 @@ retry:
        trace_and_count(c, transaction_commit, trans, _RET_IP_);
 out:
        if (likely(!(flags & BCH_TRANS_COMMIT_no_check_rw)))
-               bch2_write_ref_put(c, BCH_WRITE_REF_trans);
+               enumerated_ref_put(&c->writes, BCH_WRITE_REF_trans);
 out_reset:
        if (!ret)
                bch2_trans_downgrade(trans);
index 3155b4360fbc686b08aa9875b0e06071e1087738..3d25c2be035ed9e77a8c435231d70de23fd1e4f9 100644 (file)
@@ -14,6 +14,7 @@
 #include "btree_locking.h"
 #include "buckets.h"
 #include "clock.h"
+#include "enumerated_ref.h"
 #include "error.h"
 #include "extents.h"
 #include "io_write.h"
@@ -2341,7 +2342,7 @@ static void async_btree_node_rewrite_work(struct work_struct *work)
        closure_wake_up(&c->btree_node_rewrites_wait);
 
        bch2_bkey_buf_exit(&a->key, c);
-       bch2_write_ref_put(c, BCH_WRITE_REF_node_rewrite);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_node_rewrite);
        kfree(a);
 }
 
@@ -2363,7 +2364,7 @@ void bch2_btree_node_rewrite_async(struct bch_fs *c, struct btree *b)
 
        spin_lock(&c->btree_node_rewrites_lock);
        if (c->curr_recovery_pass > BCH_RECOVERY_PASS_journal_replay &&
-           bch2_write_ref_tryget(c, BCH_WRITE_REF_node_rewrite)) {
+           enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_node_rewrite)) {
                list_add(&a->list, &c->btree_node_rewrites);
                now = true;
        } else if (!test_bit(BCH_FS_may_go_rw, &c->flags)) {
@@ -2402,7 +2403,7 @@ void bch2_do_pending_node_rewrites(struct bch_fs *c)
                if (!a)
                        break;
 
-               bch2_write_ref_get(c, BCH_WRITE_REF_node_rewrite);
+               enumerated_ref_get(&c->writes, BCH_WRITE_REF_node_rewrite);
                queue_work(c->btree_node_rewrite_worker, &a->work);
        }
 }
index 68ab48af40f0abf948563896974b93fb757577fd..0094e4342b6945fb18a08e9647070f7d4d91bbfe 100644 (file)
@@ -7,6 +7,7 @@
 #include "btree_update_interior.h"
 #include "btree_write_buffer.h"
 #include "disk_accounting.h"
+#include "enumerated_ref.h"
 #include "error.h"
 #include "extents.h"
 #include "journal.h"
@@ -629,11 +630,11 @@ int bch2_btree_write_buffer_tryflush(struct btree_trans *trans)
 {
        struct bch_fs *c = trans->c;
 
-       if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_btree_write_buffer))
+       if (!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_btree_write_buffer))
                return -BCH_ERR_erofs_no_writes;
 
        int ret = bch2_btree_write_buffer_flush_nocheck_rw(trans);
-       bch2_write_ref_put(c, BCH_WRITE_REF_btree_write_buffer);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_btree_write_buffer);
        return ret;
 }
 
@@ -692,7 +693,7 @@ static void bch2_btree_write_buffer_flush_work(struct work_struct *work)
        } while (!ret && bch2_btree_write_buffer_should_flush(c));
        mutex_unlock(&wb->flushing.lock);
 
-       bch2_write_ref_put(c, BCH_WRITE_REF_btree_write_buffer);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_btree_write_buffer);
 }
 
 static void wb_accounting_sort(struct btree_write_buffer *wb)
@@ -821,9 +822,9 @@ int bch2_journal_keys_to_write_buffer_end(struct bch_fs *c, struct journal_keys_
                bch2_journal_pin_drop(&c->journal, &dst->wb->pin);
 
        if (bch2_btree_write_buffer_should_flush(c) &&
-           __bch2_write_ref_tryget(c, BCH_WRITE_REF_btree_write_buffer) &&
+           __enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_btree_write_buffer) &&
            !queue_work(system_unbound_wq, &c->btree_write_buffer.flush_work))
-               bch2_write_ref_put(c, BCH_WRITE_REF_btree_write_buffer);
+               enumerated_ref_put(&c->writes, BCH_WRITE_REF_btree_write_buffer);
 
        if (dst->wb == &wb->flushing)
                mutex_unlock(&wb->flushing.lock);
index 37e63137041c9491e20f02fd4f4220ccc333500f..94c24f4582bd5b0b72a2cf247f8509e2e359481b 100644 (file)
@@ -16,6 +16,7 @@
 #include "disk_accounting.h"
 #include "disk_groups.h"
 #include "ec.h"
+#include "enumerated_ref.h"
 #include "error.h"
 #include "io_read.h"
 #include "io_write.h"
@@ -1011,14 +1012,14 @@ static void ec_stripe_delete_work(struct work_struct *work)
                                BCH_TRANS_COMMIT_no_enospc, ({
                        ec_stripe_delete(trans, lru_k.k->p.offset);
                })));
-       bch2_write_ref_put(c, BCH_WRITE_REF_stripe_delete);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_stripe_delete);
 }
 
 void bch2_do_stripe_deletes(struct bch_fs *c)
 {
-       if (bch2_write_ref_tryget(c, BCH_WRITE_REF_stripe_delete) &&
+       if (enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_stripe_delete) &&
            !queue_work(c->write_ref_wq, &c->ec_stripe_delete_work))
-               bch2_write_ref_put(c, BCH_WRITE_REF_stripe_delete);
+               enumerated_ref_put(&c->writes, BCH_WRITE_REF_stripe_delete);
 }
 
 /* stripe creation: */
@@ -1412,15 +1413,15 @@ static void ec_stripe_create_work(struct work_struct *work)
        while ((s = get_pending_stripe(c)))
                ec_stripe_create(s);
 
-       bch2_write_ref_put(c, BCH_WRITE_REF_stripe_create);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_stripe_create);
 }
 
 void bch2_ec_do_stripe_creates(struct bch_fs *c)
 {
-       bch2_write_ref_get(c, BCH_WRITE_REF_stripe_create);
+       enumerated_ref_get(&c->writes, BCH_WRITE_REF_stripe_create);
 
        if (!queue_work(system_long_wq, &c->ec_stripe_create_work))
-               bch2_write_ref_put(c, BCH_WRITE_REF_stripe_create);
+               enumerated_ref_put(&c->writes, BCH_WRITE_REF_stripe_create);
 }
 
 static void ec_stripe_new_set_pending(struct bch_fs *c, struct ec_stripe_head *h)
index 535bc5fcbcc09c3b01596bd73aae46ca32ed25fd..1f5154d9676bda2591b4242238c06c7dc2bc3ee7 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "bcachefs.h"
 #include "alloc_foreground.h"
+#include "enumerated_ref.h"
 #include "fs.h"
 #include "fs-io.h"
 #include "fs-io-direct.h"
@@ -401,7 +402,7 @@ static __always_inline long bch2_dio_write_done(struct dio_write *dio)
        ret = dio->op.error ?: ((long) dio->written << 9);
        bio_put(&dio->op.wbio.bio);
 
-       bch2_write_ref_put(c, BCH_WRITE_REF_dio_write);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_dio_write);
 
        /* inode->i_dio_count is our ref on inode and thus bch_fs */
        inode_dio_end(&inode->v);
@@ -606,7 +607,7 @@ ssize_t bch2_direct_write(struct kiocb *req, struct iov_iter *iter)
        prefetch(&inode->ei_inode);
        prefetch((void *) &inode->ei_inode + 64);
 
-       if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_dio_write))
+       if (!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_dio_write))
                return -EROFS;
 
        inode_lock(&inode->v);
@@ -675,7 +676,7 @@ err_put_bio:
        bio_put(bio);
        inode_dio_end(&inode->v);
 err_put_write_ref:
-       bch2_write_ref_put(c, BCH_WRITE_REF_dio_write);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_dio_write);
        goto out;
 }
 
index 7200ec00128d28195386f4c8e9cc94f55f7d225c..6ea2762e651769e3a5c32a8c4be59acdb3053056 100644 (file)
@@ -7,6 +7,7 @@
 #include "btree_update.h"
 #include "buckets.h"
 #include "clock.h"
+#include "enumerated_ref.h"
 #include "error.h"
 #include "extents.h"
 #include "extent_update.h"
@@ -219,7 +220,7 @@ static int bch2_flush_inode(struct bch_fs *c,
        if (c->opts.journal_flush_disabled)
                return 0;
 
-       if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_fsync))
+       if (!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_fsync))
                return -EROFS;
 
        u64 seq;
@@ -227,7 +228,7 @@ static int bch2_flush_inode(struct bch_fs *c,
                        bch2_get_inode_journal_seq_trans(trans, inode_inum(inode), &seq)) ?:
                  bch2_journal_flush_seq(&c->journal, seq, TASK_INTERRUPTIBLE) ?:
                  bch2_inode_flush_nocow_writes(c, inode);
-       bch2_write_ref_put(c, BCH_WRITE_REF_fsync);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_fsync);
        return ret;
 }
 
@@ -818,7 +819,7 @@ long bch2_fallocate_dispatch(struct file *file, int mode,
        struct bch_fs *c = inode->v.i_sb->s_fs_info;
        long ret;
 
-       if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_fallocate))
+       if (!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_fallocate))
                return -EROFS;
 
        inode_lock(&inode->v);
@@ -842,7 +843,7 @@ long bch2_fallocate_dispatch(struct file *file, int mode,
 err:
        bch2_pagecache_block_put(inode);
        inode_unlock(&inode->v);
-       bch2_write_ref_put(c, BCH_WRITE_REF_fallocate);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_fallocate);
 
        return bch2_err_class(ret);
 }
index e490f136d63d4c98d52d2a7a303b2045144264af..baedfee673999418477f8691d9303146b66f3ea8 100644 (file)
@@ -17,6 +17,7 @@
 #include "data_update.h"
 #include "disk_groups.h"
 #include "ec.h"
+#include "enumerated_ref.h"
 #include "error.h"
 #include "io_read.h"
 #include "io_misc.h"
@@ -178,7 +179,7 @@ static noinline void promote_free(struct bch_read_bio *rbio)
 
        bch2_data_update_exit(&op->write);
 
-       bch2_write_ref_put(c, BCH_WRITE_REF_promote);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_promote);
        kfree_rcu(op, rcu);
 }
 
@@ -243,7 +244,7 @@ static struct bch_read_bio *__promote_alloc(struct btree_trans *trans,
                        return NULL;
        }
 
-       if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_promote))
+       if (!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_promote))
                return ERR_PTR(-BCH_ERR_nopromote_no_writes);
 
        struct promote_op *op = kzalloc(sizeof(*op), GFP_KERNEL);
@@ -288,7 +289,7 @@ err:
        /* We may have added to the rhashtable and thus need rcu freeing: */
        kfree_rcu(op, rcu);
 err_put:
-       bch2_write_ref_put(c, BCH_WRITE_REF_promote);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_promote);
        return ERR_PTR(ret);
 }
 
index 38086c1a8e2815fd7f1b0625b2096577c736f60f..e95a535ad44aaa4d8376e367be7400c0cd55d274 100644 (file)
@@ -15,6 +15,7 @@
 #include "compress.h"
 #include "debug.h"
 #include "ec.h"
+#include "enumerated_ref.h"
 #include "error.h"
 #include "extent_update.h"
 #include "inode.h"
@@ -531,7 +532,7 @@ static void bch2_write_done(struct closure *cl)
        bch2_disk_reservation_put(c, &op->res);
 
        if (!(op->flags & BCH_WRITE_move))
-               bch2_write_ref_put(c, BCH_WRITE_REF_write);
+               enumerated_ref_put(&c->writes, BCH_WRITE_REF_write);
        bch2_keylist_free(&op->insert_keys, op->inline_keys);
 
        EBUG_ON(cl->parent);
@@ -1679,7 +1680,7 @@ CLOSURE_CALLBACK(bch2_write)
        }
 
        if (!(op->flags & BCH_WRITE_move) &&
-           !bch2_write_ref_tryget(c, BCH_WRITE_REF_write)) {
+           !enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_write)) {
                op->error = -BCH_ERR_erofs_no_writes;
                goto err;
        }
index e1cd6e8e37cf08b1fc88fe63a8927fc88482a990..e2c95192a5779c1832627e53e2cadbb69e50901c 100644 (file)
@@ -12,6 +12,7 @@
 #include "btree_update.h"
 #include "btree_write_buffer.h"
 #include "buckets.h"
+#include "enumerated_ref.h"
 #include "error.h"
 #include "journal.h"
 #include "journal_io.h"
@@ -989,11 +990,11 @@ int bch2_journal_meta(struct journal *j)
 {
        struct bch_fs *c = container_of(j, struct bch_fs, journal);
 
-       if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_journal))
+       if (!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_journal))
                return -BCH_ERR_erofs_no_writes;
 
        int ret = __bch2_journal_meta(j);
-       bch2_write_ref_put(c, BCH_WRITE_REF_journal);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_journal);
        return ret;
 }
 
index 710178e3da4c2a944bd9329fefcde8cc298e94e4..3a13dbcab6bab057cbe3b8197dd34c195657565e 100644 (file)
@@ -3,6 +3,7 @@
 #include "bkey_buf.h"
 #include "btree_update.h"
 #include "buckets.h"
+#include "enumerated_ref.h"
 #include "error.h"
 #include "extents.h"
 #include "inode.h"
@@ -610,7 +611,7 @@ s64 bch2_remap_range(struct bch_fs *c,
                !bch2_request_incompat_feature(c, bcachefs_metadata_version_reflink_p_may_update_opts);
        int ret = 0, ret2 = 0;
 
-       if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_reflink))
+       if (!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_reflink))
                return -BCH_ERR_erofs_no_writes;
 
        bch2_check_set_feature(c, BCH_FEATURE_reflink);
@@ -761,7 +762,7 @@ err:
        bch2_bkey_buf_exit(&new_src, c);
        bch2_bkey_buf_exit(&new_dst, c);
 
-       bch2_write_ref_put(c, BCH_WRITE_REF_reflink);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_reflink);
 
        return dst_done ?: ret ?: ret2;
 }
index 2eede851572c1a3bec94535bbcb9b72dce04edb2..14ea09ccee37b1cb9070fbf2859c7561334aa0f4 100644 (file)
@@ -6,6 +6,7 @@
 #include "btree_key_cache.h"
 #include "btree_update.h"
 #include "buckets.h"
+#include "enumerated_ref.h"
 #include "errcode.h"
 #include "error.h"
 #include "fs.h"
@@ -1661,18 +1662,18 @@ void bch2_delete_dead_snapshots_work(struct work_struct *work)
        set_worker_desc("bcachefs-delete-dead-snapshots/%s", c->name);
 
        bch2_delete_dead_snapshots(c);
-       bch2_write_ref_put(c, BCH_WRITE_REF_delete_dead_snapshots);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_delete_dead_snapshots);
 }
 
 void bch2_delete_dead_snapshots_async(struct bch_fs *c)
 {
-       if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_delete_dead_snapshots))
+       if (!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_delete_dead_snapshots))
                return;
 
        BUG_ON(!test_bit(BCH_FS_may_go_rw, &c->flags));
 
        if (!queue_work(c->write_ref_wq, &c->snapshot_delete_work))
-               bch2_write_ref_put(c, BCH_WRITE_REF_delete_dead_snapshots);
+               enumerated_ref_put(&c->writes, BCH_WRITE_REF_delete_dead_snapshots);
 }
 
 int __bch2_key_has_snapshot_overwrites(struct btree_trans *trans,
index c9d7209f0cb175de82ef0de137299f1949d28aa6..ff20ce98a476f72a74cb7d63c61b6d4e4ddeecb9 100644 (file)
@@ -3,6 +3,7 @@
 #include "bcachefs.h"
 #include "btree_key_cache.h"
 #include "btree_update.h"
+#include "enumerated_ref.h"
 #include "errcode.h"
 #include "error.h"
 #include "fs.h"
@@ -517,7 +518,7 @@ static void bch2_subvolume_wait_for_pagecache_and_delete(struct work_struct *wor
                darray_exit(&s);
        }
 
-       bch2_write_ref_put(c, BCH_WRITE_REF_snapshot_delete_pagecache);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_snapshot_delete_pagecache);
 }
 
 struct subvolume_unlink_hook {
@@ -540,11 +541,11 @@ static int bch2_subvolume_wait_for_pagecache_and_delete_hook(struct btree_trans
        if (ret)
                return ret;
 
-       if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_snapshot_delete_pagecache))
+       if (!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_snapshot_delete_pagecache))
                return -EROFS;
 
        if (!queue_work(c->write_ref_wq, &c->snapshot_wait_for_pagecache_and_delete_work))
-               bch2_write_ref_put(c, BCH_WRITE_REF_snapshot_delete_pagecache);
+               enumerated_ref_put(&c->writes, BCH_WRITE_REF_snapshot_delete_pagecache);
        return 0;
 }
 
index cdcfed4dd283e695d6d7a65dd2cbf5ac9e6dfd57..6fa427d5cbd69eb81357a922998cb8fb8bf732e2 100644 (file)
@@ -28,6 +28,7 @@
 #include "disk_accounting.h"
 #include "disk_groups.h"
 #include "ec.h"
+#include "enumerated_ref.h"
 #include "errcode.h"
 #include "error.h"
 #include "fs.h"
@@ -311,15 +312,13 @@ static void __bch2_fs_read_only(struct bch_fs *c)
        }
 }
 
-#ifndef BCH_WRITE_REF_DEBUG
-static void bch2_writes_disabled(struct percpu_ref *writes)
+static void bch2_writes_disabled(struct enumerated_ref *writes)
 {
        struct bch_fs *c = container_of(writes, struct bch_fs, writes);
 
        set_bit(BCH_FS_write_disable_complete, &c->flags);
        wake_up(&bch2_read_only_wait);
 }
-#endif
 
 void bch2_fs_read_only(struct bch_fs *c)
 {
@@ -337,12 +336,7 @@ void bch2_fs_read_only(struct bch_fs *c)
         * writes will return -EROFS:
         */
        set_bit(BCH_FS_going_ro, &c->flags);
-#ifndef BCH_WRITE_REF_DEBUG
-       percpu_ref_kill(&c->writes);
-#else
-       for (unsigned i = 0; i < BCH_WRITE_REF_NR; i++)
-               bch2_write_ref_put(c, i);
-#endif
+       enumerated_ref_stop_async(&c->writes);
 
        /*
         * If we're not doing an emergency shutdown, we want to wait on
@@ -504,14 +498,7 @@ static int __bch2_fs_read_write(struct bch_fs *c, bool early)
        set_bit(BCH_FS_rw, &c->flags);
        set_bit(BCH_FS_was_rw, &c->flags);
 
-#ifndef BCH_WRITE_REF_DEBUG
-       percpu_ref_reinit(&c->writes);
-#else
-       for (unsigned i = 0; i < BCH_WRITE_REF_NR; i++) {
-               BUG_ON(atomic_long_read(&c->writes[i]));
-               atomic_long_inc(&c->writes[i]);
-       }
-#endif
+       enumerated_ref_start(&c->writes);
 
        ret = bch2_copygc_start(c);
        if (ret) {
@@ -619,9 +606,7 @@ static void __bch2_fs_free(struct bch_fs *c)
        mempool_exit(&c->btree_bounce_pool);
        bioset_exit(&c->btree_bio);
        mempool_exit(&c->fill_iter);
-#ifndef BCH_WRITE_REF_DEBUG
-       percpu_ref_exit(&c->writes);
-#endif
+       enumerated_ref_exit(&c->writes);
        kfree(rcu_dereference_protected(c->disk_groups, 1));
        kfree(c->journal_seq_blacklist_table);
 
@@ -949,10 +934,8 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts,
 
        if (!(c->btree_read_complete_wq = alloc_workqueue("bcachefs_btree_read_complete",
                                WQ_HIGHPRI|WQ_FREEZABLE|WQ_MEM_RECLAIM, 512)) ||
-#ifndef BCH_WRITE_REF_DEBUG
-           percpu_ref_init(&c->writes, bch2_writes_disabled,
-                           PERCPU_REF_INIT_DEAD, GFP_KERNEL) ||
-#endif
+           enumerated_ref_init(&c->writes, BCH_WRITE_REF_NR,
+                               bch2_writes_disabled) ||
            mempool_init_kmalloc_pool(&c->fill_iter, 1, iter_size) ||
            bioset_init(&c->btree_bio, 1,
                        max(offsetof(struct btree_read_bio, bio),
index bfdadeae970e31d23bf189369d2a8791a26f291d..b80c46af13d441ec03d37f700083d4ce27de4c1c 100644 (file)
@@ -25,6 +25,7 @@
 #include "disk_accounting.h"
 #include "disk_groups.h"
 #include "ec.h"
+#include "enumerated_ref.h"
 #include "inode.h"
 #include "journal.h"
 #include "journal_reclaim.h"
@@ -175,8 +176,6 @@ read_attribute(btree_reserve_cache);
 read_attribute(open_buckets);
 read_attribute(open_buckets_partial);
 read_attribute(nocow_lock_table);
-
-#ifdef BCH_WRITE_REF_DEBUG
 read_attribute(write_refs);
 
 static const char * const bch2_write_refs[] = {
@@ -186,15 +185,6 @@ static const char * const bch2_write_refs[] = {
        NULL
 };
 
-static void bch2_write_refs_to_text(struct printbuf *out, struct bch_fs *c)
-{
-       bch2_printbuf_tabstop_push(out, 24);
-
-       for (unsigned i = 0; i < ARRAY_SIZE(c->writes); i++)
-               prt_printf(out, "%s\t%li\n", bch2_write_refs[i], atomic_long_read(&c->writes[i]));
-}
-#endif
-
 read_attribute(internal_uuid);
 read_attribute(disk_groups);
 
@@ -369,10 +359,8 @@ SHOW(bch2_fs)
        if (attr == &sysfs_moving_ctxts)
                bch2_fs_moving_ctxts_to_text(out, c);
 
-#ifdef BCH_WRITE_REF_DEBUG
        if (attr == &sysfs_write_refs)
-               bch2_write_refs_to_text(out, c);
-#endif
+               enumerated_ref_to_text(out, &c->writes, bch2_write_refs);
 
        if (attr == &sysfs_nocow_lock_table)
                bch2_nocow_locks_to_text(out, &c->nocow_locks);
@@ -405,7 +393,7 @@ STORE(bch2_fs)
        if (attr == &sysfs_trigger_btree_updates)
                queue_work(c->btree_interior_update_worker, &c->btree_interior_update_work);
 
-       if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_sysfs))
+       if (!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_sysfs))
                return -EROFS;
 
        if (attr == &sysfs_trigger_btree_cache_shrink) {
@@ -465,7 +453,7 @@ STORE(bch2_fs)
                        size = ret;
        }
 #endif
-       bch2_write_ref_put(c, BCH_WRITE_REF_sysfs);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_sysfs);
        return size;
 }
 SYSFS_OPS(bch2_fs);
@@ -558,9 +546,7 @@ struct attribute *bch2_fs_internal_files[] = {
        &sysfs_new_stripes,
        &sysfs_open_buckets,
        &sysfs_open_buckets_partial,
-#ifdef BCH_WRITE_REF_DEBUG
        &sysfs_write_refs,
-#endif
        &sysfs_nocow_lock_table,
        &sysfs_io_timers_read,
        &sysfs_io_timers_write,
@@ -626,7 +612,7 @@ static ssize_t sysfs_opt_store(struct bch_fs *c,
         * We don't need to take c->writes for correctness, but it eliminates an
         * unsightly error message in the dmesg log when we're RO:
         */
-       if (unlikely(!bch2_write_ref_tryget(c, BCH_WRITE_REF_sysfs)))
+       if (unlikely(!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_sysfs)))
                return -EROFS;
 
        char *tmp = kstrdup(buf, GFP_KERNEL);
@@ -653,7 +639,7 @@ static ssize_t sysfs_opt_store(struct bch_fs *c,
 
        ret = size;
 err:
-       bch2_write_ref_put(c, BCH_WRITE_REF_sysfs);
+       enumerated_ref_put(&c->writes, BCH_WRITE_REF_sysfs);
        return ret;
 }