bcachefs: Simplify hash table checks
[linux-block.git] / fs / bcachefs / super.c
index 224c21c3f9f74b3ee2af4a8bc4a8027448b4519e..385b41f167549e68811e3b7b943ae995ff460163 100644 (file)
@@ -276,7 +276,7 @@ static void bch2_writes_disabled(struct percpu_ref *writes)
 void bch2_fs_read_only(struct bch_fs *c)
 {
        if (!test_bit(BCH_FS_RW, &c->flags)) {
-               BUG_ON(c->journal.reclaim_thread);
+               bch2_journal_reclaim_stop(&c->journal);
                return;
        }
 
@@ -293,7 +293,6 @@ void bch2_fs_read_only(struct bch_fs *c)
        percpu_ref_kill(&c->writes);
 
        cancel_work_sync(&c->ec_stripe_delete_work);
-       cancel_delayed_work(&c->pd_controllers_update);
 
        /*
         * If we're not doing an emergency shutdown, we want to wait on
@@ -378,8 +377,6 @@ static int bch2_fs_read_write_late(struct bch_fs *c)
                return ret;
        }
 
-       schedule_delayed_work(&c->pd_controllers_update, 5 * HZ);
-
        schedule_work(&c->ec_stripe_delete_work);
 
        return 0;
@@ -403,6 +400,8 @@ static int __bch2_fs_read_write(struct bch_fs *c, bool early)
             (!early || c->opts.read_only)))
                return -EROFS;
 
+       bch_info(c, "going read-write");
+
        ret = bch2_fs_mark_dirty(c);
        if (ret)
                goto err;
@@ -434,12 +433,6 @@ static int __bch2_fs_read_write(struct bch_fs *c, bool early)
        for_each_rw_member(ca, c, i)
                bch2_wake_allocator(ca);
 
-       ret = bch2_journal_reclaim_start(&c->journal);
-       if (ret) {
-               bch_err(c, "error starting journal reclaim: %i", ret);
-               return ret;
-       }
-
        if (!early) {
                ret = bch2_fs_read_write_late(c);
                if (ret)
@@ -485,6 +478,7 @@ static void __bch2_fs_free(struct bch_fs *c)
        bch2_fs_btree_iter_exit(c);
        bch2_fs_btree_key_cache_exit(&c->btree_key_cache);
        bch2_fs_btree_cache_exit(c);
+       bch2_fs_replicas_exit(c);
        bch2_fs_journal_exit(&c->journal);
        bch2_io_clock_exit(&c->io_clock[WRITE]);
        bch2_io_clock_exit(&c->io_clock[READ]);
@@ -493,10 +487,6 @@ static void __bch2_fs_free(struct bch_fs *c)
        bch2_journal_entries_free(&c->journal_entries);
        percpu_free_rwsem(&c->mark_lock);
        free_percpu(c->online_reserved);
-       kfree(c->usage_scratch);
-       for (i = 0; i < ARRAY_SIZE(c->usage); i++)
-               free_percpu(c->usage[i]);
-       kfree(c->usage_base);
 
        if (c->btree_iters_bufs)
                for_each_possible_cpu(cpu)
@@ -509,8 +499,6 @@ static void __bch2_fs_free(struct bch_fs *c)
        bioset_exit(&c->btree_bio);
        mempool_exit(&c->fill_iter);
        percpu_ref_exit(&c->writes);
-       kfree(c->replicas.entries);
-       kfree(c->replicas_gc.entries);
        kfree(rcu_dereference_protected(c->disk_groups, 1));
        kfree(c->journal_seq_blacklist_table);
        kfree(c->unused_inode_hints);
@@ -521,8 +509,7 @@ static void __bch2_fs_free(struct bch_fs *c)
        if (c->wq)
                destroy_workqueue(c->wq);
 
-       free_pages((unsigned long) c->disk_sb.sb,
-                  c->disk_sb.page_order);
+       bch2_free_super(&c->disk_sb);
        kvpfree(c, sizeof(*c));
        module_put(THIS_MODULE);
 }
@@ -571,7 +558,6 @@ void __bch2_fs_stop(struct bch_fs *c)
                cancel_work_sync(&ca->io_error_work);
 
        cancel_work_sync(&c->btree_write_error_work);
-       cancel_delayed_work_sync(&c->pd_controllers_update);
        cancel_work_sync(&c->read_only_work);
 }
 
@@ -912,9 +898,16 @@ int bch2_fs_start(struct bch_fs *c)
        /*
         * Allocator threads don't start filling copygc reserve until after we
         * set BCH_FS_STARTED - wake them now:
+        *
+        * XXX ugly hack:
+        * Need to set ca->allocator_state here instead of relying on the
+        * allocator threads to do it to avoid racing with the copygc threads
+        * checking it and thinking they have no alloc reserve:
         */
-       for_each_online_member(ca, c, i)
+       for_each_online_member(ca, c, i) {
+               ca->allocator_state = ALLOCATOR_running;
                bch2_wake_allocator(ca);
+       }
 
        if (c->opts.read_only || c->opts.nochanges) {
                bch2_fs_read_only(c);
@@ -1177,7 +1170,9 @@ static int bch2_dev_alloc(struct bch_fs *c, unsigned dev_idx)
        if (!ca)
                goto err;
 
-       if (ca->mi.state == BCH_MEMBER_STATE_RW &&
+       ca->fs = c;
+
+       if (ca->mi.state == BCH_MEMBER_STATE_rw &&
            bch2_dev_allocator_start(ca)) {
                bch2_dev_free(ca);
                goto err;
@@ -1282,16 +1277,16 @@ bool bch2_dev_state_allowed(struct bch_fs *c, struct bch_dev *ca,
        lockdep_assert_held(&c->state_lock);
 
        switch (new_state) {
-       case BCH_MEMBER_STATE_RW:
+       case BCH_MEMBER_STATE_rw:
                return true;
-       case BCH_MEMBER_STATE_RO:
-               if (ca->mi.state != BCH_MEMBER_STATE_RW)
+       case BCH_MEMBER_STATE_ro:
+               if (ca->mi.state != BCH_MEMBER_STATE_rw)
                        return true;
 
                /* do we have enough devices to write to?  */
                for_each_member_device(ca2, c, i)
                        if (ca2 != ca)
-                               nr_rw += ca2->mi.state == BCH_MEMBER_STATE_RW;
+                               nr_rw += ca2->mi.state == BCH_MEMBER_STATE_rw;
 
                required = max(!(flags & BCH_FORCE_IF_METADATA_DEGRADED)
                               ? c->opts.metadata_replicas
@@ -1301,10 +1296,10 @@ bool bch2_dev_state_allowed(struct bch_fs *c, struct bch_dev *ca,
                               : c->opts.data_replicas_required);
 
                return nr_rw >= required;
-       case BCH_MEMBER_STATE_FAILED:
-       case BCH_MEMBER_STATE_SPARE:
-               if (ca->mi.state != BCH_MEMBER_STATE_RW &&
-                   ca->mi.state != BCH_MEMBER_STATE_RO)
+       case BCH_MEMBER_STATE_failed:
+       case BCH_MEMBER_STATE_spare:
+               if (ca->mi.state != BCH_MEMBER_STATE_rw &&
+                   ca->mi.state != BCH_MEMBER_STATE_ro)
                        return true;
 
                /* do we have enough devices to read from?  */
@@ -1341,8 +1336,8 @@ static bool bch2_fs_may_start(struct bch_fs *c)
                        ca = bch_dev_locked(c, i);
 
                        if (!bch2_dev_is_online(ca) &&
-                           (ca->mi.state == BCH_MEMBER_STATE_RW ||
-                            ca->mi.state == BCH_MEMBER_STATE_RO)) {
+                           (ca->mi.state == BCH_MEMBER_STATE_rw ||
+                            ca->mi.state == BCH_MEMBER_STATE_ro)) {
                                mutex_unlock(&c->sb_lock);
                                return false;
                        }
@@ -1375,7 +1370,7 @@ static const char *__bch2_dev_read_write(struct bch_fs *c, struct bch_dev *ca)
 {
        lockdep_assert_held(&c->state_lock);
 
-       BUG_ON(ca->mi.state != BCH_MEMBER_STATE_RW);
+       BUG_ON(ca->mi.state != BCH_MEMBER_STATE_rw);
 
        bch2_dev_allocator_add(c, ca);
        bch2_recalc_capacity(c);
@@ -1398,10 +1393,10 @@ int __bch2_dev_set_state(struct bch_fs *c, struct bch_dev *ca,
        if (!bch2_dev_state_allowed(c, ca, new_state, flags))
                return -EINVAL;
 
-       if (new_state != BCH_MEMBER_STATE_RW)
+       if (new_state != BCH_MEMBER_STATE_rw)
                __bch2_dev_read_only(c, ca);
 
-       bch_notice(ca, "%s", bch2_dev_state[new_state]);
+       bch_notice(ca, "%s", bch2_member_states[new_state]);
 
        mutex_lock(&c->sb_lock);
        mi = bch2_sb_get_members(c->disk_sb.sb);
@@ -1409,7 +1404,7 @@ int __bch2_dev_set_state(struct bch_fs *c, struct bch_dev *ca,
        bch2_write_super(c);
        mutex_unlock(&c->sb_lock);
 
-       if (new_state == BCH_MEMBER_STATE_RW &&
+       if (new_state == BCH_MEMBER_STATE_rw &&
            __bch2_dev_read_write(c, ca))
                ret = -ENOMEM;
 
@@ -1442,7 +1437,7 @@ int bch2_dev_remove_alloc(struct bch_fs *c, struct bch_dev *ca)
 
        for (i = 0; i < ca->mi.nbuckets; i++) {
                ret = bch2_btree_key_cache_flush(&trans,
-                               BTREE_ID_ALLOC, POS(ca->dev_idx, i));
+                               BTREE_ID_alloc, POS(ca->dev_idx, i));
                if (ret)
                        break;
        }
@@ -1451,7 +1446,7 @@ int bch2_dev_remove_alloc(struct bch_fs *c, struct bch_dev *ca)
        if (ret)
                return ret;
 
-       return bch2_btree_delete_range(c, BTREE_ID_ALLOC,
+       return bch2_btree_delete_range(c, BTREE_ID_alloc,
                                       POS(ca->dev_idx, 0),
                                       POS(ca->dev_idx + 1, 0),
                                       NULL);
@@ -1471,7 +1466,7 @@ int bch2_dev_remove(struct bch_fs *c, struct bch_dev *ca, int flags)
         */
        percpu_ref_put(&ca->ref);
 
-       if (!bch2_dev_state_allowed(c, ca, BCH_MEMBER_STATE_FAILED, flags)) {
+       if (!bch2_dev_state_allowed(c, ca, BCH_MEMBER_STATE_failed, flags)) {
                bch_err(ca, "Cannot remove without losing data");
                goto err;
        }
@@ -1555,7 +1550,7 @@ int bch2_dev_remove(struct bch_fs *c, struct bch_dev *ca, int flags)
        bch2_dev_usage_journal_reserve(c);
        return 0;
 err:
-       if (ca->mi.state == BCH_MEMBER_STATE_RW &&
+       if (ca->mi.state == BCH_MEMBER_STATE_rw &&
            !percpu_ref_is_zero(&ca->io_ref))
                __bch2_dev_read_write(c, ca);
        up_write(&c->state_lock);
@@ -1679,7 +1674,7 @@ have_slot:
        if (ret)
                goto err_late;
 
-       if (ca->mi.state == BCH_MEMBER_STATE_RW) {
+       if (ca->mi.state == BCH_MEMBER_STATE_rw) {
                err = __bch2_dev_read_write(c, ca);
                if (err)
                        goto err_late;
@@ -1740,7 +1735,7 @@ int bch2_dev_online(struct bch_fs *c, const char *path)
                goto err;
        }
 
-       if (ca->mi.state == BCH_MEMBER_STATE_RW) {
+       if (ca->mi.state == BCH_MEMBER_STATE_rw) {
                err = __bch2_dev_read_write(c, ca);
                if (err)
                        goto err;
@@ -1774,7 +1769,7 @@ int bch2_dev_offline(struct bch_fs *c, struct bch_dev *ca, int flags)
                return 0;
        }
 
-       if (!bch2_dev_state_allowed(c, ca, BCH_MEMBER_STATE_FAILED, flags)) {
+       if (!bch2_dev_state_allowed(c, ca, BCH_MEMBER_STATE_failed, flags)) {
                bch_err(ca, "Cannot offline required disk");
                up_write(&c->state_lock);
                return -EINVAL;