]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
Update bcachefs sources to 0a9f0fc68a bcachefs: Don't unconditially version_upgrade...
authorKent Overstreet <kent.overstreet@gmail.com>
Sun, 21 Mar 2021 20:40:41 +0000 (16:40 -0400)
committerKent Overstreet <kent.overstreet@gmail.com>
Sun, 21 Mar 2021 20:44:44 +0000 (16:44 -0400)
33 files changed:
.bcachefs_revision
libbcachefs/acl.c
libbcachefs/alloc_background.c
libbcachefs/bcachefs.h
libbcachefs/bcachefs_format.h
libbcachefs/bkey_methods.c
libbcachefs/bkey_methods.h
libbcachefs/btree_gc.c
libbcachefs/btree_io.c
libbcachefs/btree_iter.c
libbcachefs/btree_iter.h
libbcachefs/btree_key_cache.c
libbcachefs/btree_types.h
libbcachefs/btree_update_interior.c
libbcachefs/btree_update_leaf.c
libbcachefs/buckets.c
libbcachefs/debug.c
libbcachefs/dirent.c
libbcachefs/ec.c
libbcachefs/extents.c
libbcachefs/extents.h
libbcachefs/fs-io.c
libbcachefs/fs.c
libbcachefs/fsck.c
libbcachefs/inode.c
libbcachefs/io.c
libbcachefs/journal.c
libbcachefs/move.c
libbcachefs/recovery.c
libbcachefs/reflink.c
libbcachefs/super-io.c
libbcachefs/super.c
libbcachefs/xattr.c

index 77e97af759facc3dabfb4f5ddc07b2fd731bea7e..e52e11e881ebbbfbaf56ea1461fae9e68aec7afe 100644 (file)
@@ -1 +1 @@
-242d37cbd0abfa575ebf816c715e5bb9513c90a0
+0a9f0fc68a3cfaaee05a0848673fdb3de3108982
index 276ab56ce5944b5362cfcf4c543877d68f86116a..0f2d7437c740344e3191ee83041e3bc62d6c2be1 100644 (file)
@@ -240,12 +240,12 @@ retry:
        }
 
        xattr = bkey_s_c_to_xattr(bch2_btree_iter_peek_slot(iter));
-
        acl = bch2_acl_from_disk(xattr_val(xattr.v),
                        le16_to_cpu(xattr.v->x_val_len));
 
        if (!IS_ERR(acl))
                set_cached_acl(&inode->v, type, acl);
+       bch2_trans_iter_put(&trans, iter);
 out:
        bch2_trans_exit(&trans);
        return acl;
@@ -310,7 +310,7 @@ retry:
        if (type == ACL_TYPE_ACCESS) {
                ret = posix_acl_update_mode(&inode->v, &mode, &acl);
                if (ret)
-                       goto err;
+                       goto btree_err;
        }
 
        hash_info = bch2_hash_info_init(c, &inode_u);
@@ -327,6 +327,8 @@ retry:
                                  &inode->ei_journal_seq,
                                  BTREE_INSERT_NOUNLOCK);
 btree_err:
+       bch2_trans_iter_put(&trans, inode_iter);
+
        if (ret == -EINTR)
                goto retry;
        if (unlikely(ret))
@@ -353,21 +355,22 @@ int bch2_acl_chmod(struct btree_trans *trans,
        struct bkey_s_c_xattr xattr;
        struct bkey_i_xattr *new;
        struct posix_acl *acl;
-       int ret = 0;
+       int ret;
 
        iter = bch2_hash_lookup(trans, bch2_xattr_hash_desc,
                        &hash_info, inode->bi_inum,
                        &X_SEARCH(KEY_TYPE_XATTR_INDEX_POSIX_ACL_ACCESS, "", 0),
                        BTREE_ITER_INTENT);
-       if (IS_ERR(iter))
-               return PTR_ERR(iter) != -ENOENT ? PTR_ERR(iter) : 0;
+       ret = PTR_ERR_OR_ZERO(iter);
+       if (ret)
+               return ret == -ENOENT ? 0 : ret;
 
        xattr = bkey_s_c_to_xattr(bch2_btree_iter_peek_slot(iter));
-
        acl = bch2_acl_from_disk(xattr_val(xattr.v),
                        le16_to_cpu(xattr.v->x_val_len));
-       if (IS_ERR_OR_NULL(acl))
-               return PTR_ERR(acl);
+       ret = PTR_ERR_OR_ZERO(acl);
+       if (ret || !acl)
+               goto err;
 
        ret = __posix_acl_chmod(&acl, GFP_KERNEL, mode);
        if (ret)
@@ -384,6 +387,7 @@ int bch2_acl_chmod(struct btree_trans *trans,
        *new_acl = acl;
        acl = NULL;
 err:
+       bch2_trans_iter_put(trans, iter);
        kfree(acl);
        return ret;
 }
index 796a061d99946e75b8275203f33e0b4ee3f84620..48971fcf2d5bb393c818732e3b0f1be50c179ebc 100644 (file)
@@ -139,25 +139,6 @@ static void bch2_alloc_unpack_v1(struct bkey_alloc_unpacked *out,
 #undef  x
 }
 
-static void bch2_alloc_pack_v1(struct bkey_alloc_buf *dst,
-                              const struct bkey_alloc_unpacked src)
-{
-       struct bkey_i_alloc *a = bkey_alloc_init(&dst->k);
-       void *d = a->v.data;
-       unsigned bytes, idx = 0;
-
-       a->k.p          = POS(src.dev, src.bucket);
-       a->v.fields     = 0;
-       a->v.gen        = src.gen;
-
-#define x(_name, _bits)        alloc_field_v1_put(a, &d, idx++, src._name);
-       BCH_ALLOC_FIELDS_V1()
-#undef  x
-       bytes = (void *) d - (void *) &a->v;
-       set_bkey_val_bytes(&a->k, bytes);
-       memset_u64s_tail(&a->v, 0, bytes);
-}
-
 static int bch2_alloc_unpack_v2(struct bkey_alloc_unpacked *out,
                                struct bkey_s_c k)
 {
@@ -250,10 +231,7 @@ void bch2_alloc_pack(struct bch_fs *c,
                     struct bkey_alloc_buf *dst,
                     const struct bkey_alloc_unpacked src)
 {
-       if (c->sb.features & (1ULL << BCH_FEATURE_alloc_v2))
-               bch2_alloc_pack_v2(dst, src);
-       else
-               bch2_alloc_pack_v1(dst, src);
+       bch2_alloc_pack_v2(dst, src);
 }
 
 static unsigned bch_alloc_val_u64s(const struct bch_alloc *a)
@@ -410,7 +388,6 @@ int bch2_alloc_write(struct bch_fs *c, unsigned flags)
        int ret = 0;
 
        bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
-
        iter = bch2_trans_get_iter(&trans, BTREE_ID_alloc, POS_MIN,
                                   BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
 
@@ -430,6 +407,7 @@ int bch2_alloc_write(struct bch_fs *c, unsigned flags)
                }
        }
 err:
+       bch2_trans_iter_put(&trans, iter);
        bch2_trans_exit(&trans);
        return ret;
 }
@@ -959,7 +937,6 @@ static int bch2_invalidate_buckets(struct bch_fs *c, struct bch_dev *ca)
        int ret = 0;
 
        bch2_trans_init(&trans, c, 0, 0);
-
        iter = bch2_trans_get_iter(&trans, BTREE_ID_alloc,
                                   POS(ca->dev_idx, 0),
                                   BTREE_ITER_CACHED|
@@ -975,6 +952,7 @@ static int bch2_invalidate_buckets(struct bch_fs *c, struct bch_dev *ca)
                                (!fifo_empty(&ca->free_inc)
                                 ? BTREE_INSERT_NOWAIT : 0));
 
+       bch2_trans_iter_put(&trans, iter);
        bch2_trans_exit(&trans);
 
        /* If we used NOWAIT, don't return the error: */
index 5f0e45f79611cc8a7c6c10430dd8913fb982f669..4133651d5b688abc168cede3cb1b3ca52f577946 100644 (file)
@@ -597,6 +597,7 @@ struct bch_fs {
                uuid_le         user_uuid;
 
                u16             version;
+               u16             version_min;
                u16             encoded_extent_max;
 
                u8              nr_devices;
index 573e1fe5f410942e98f908db4e77776aa89d00ae..c4aa4deacdfcd0a6f2f1e4dc6b9480301800f22a 100644 (file)
@@ -1376,6 +1376,7 @@ LE64_BITMASK(BCH_SB_METADATA_TARGET,      struct bch_sb, flags[3], 16, 28);
        ((1ULL << BCH_FEATURE_new_extent_overwrite)|    \
         (1ULL << BCH_FEATURE_extents_above_btree_updates)|\
         (1ULL << BCH_FEATURE_btree_updates_journalled)|\
+        (1ULL << BCH_FEATURE_alloc_v2)|\
         (1ULL << BCH_FEATURE_extents_across_btree_nodes))
 
 #define BCH_SB_FEATURES_ALL                            \
@@ -1383,8 +1384,7 @@ LE64_BITMASK(BCH_SB_METADATA_TARGET,      struct bch_sb, flags[3], 16, 28);
         (1ULL << BCH_FEATURE_new_siphash)|             \
         (1ULL << BCH_FEATURE_btree_ptr_v2)|            \
         (1ULL << BCH_FEATURE_new_varint)|              \
-        (1ULL << BCH_FEATURE_journal_no_flush)|        \
-        (1ULL << BCH_FEATURE_alloc_v2))
+        (1ULL << BCH_FEATURE_journal_no_flush))
 
 enum bch_sb_feature {
 #define x(f, n) BCH_FEATURE_##f,
index 79e249f49971bd163294ba60dfb2ce9b249e451f..878befb5b9efe6254500565477199616c524cfdc 100644 (file)
@@ -149,7 +149,6 @@ const char *bch2_bkey_in_btree_node(struct btree *b, struct bkey_s_c k)
 
 void bch2_bkey_debugcheck(struct bch_fs *c, struct btree *b, struct bkey_s_c k)
 {
-       const struct bkey_ops *ops = &bch2_bkey_ops[k.k->type];
        const char *invalid;
 
        BUG_ON(!k.k->u64s);
@@ -161,11 +160,7 @@ void bch2_bkey_debugcheck(struct bch_fs *c, struct btree *b, struct bkey_s_c k)
 
                bch2_bkey_val_to_text(&PBUF(buf), c, k);
                bch2_fs_inconsistent(c, "invalid bkey %s: %s", buf, invalid);
-               return;
        }
-
-       if (ops->key_debugcheck)
-               ops->key_debugcheck(c, k);
 }
 
 void bch2_bpos_to_text(struct printbuf *out, struct bpos pos)
index 0bca725ae3b8c5d3d719cc878c07bb1812cc6802..bfa6f112aeed17519677d96bc41ca9177f91abe4 100644 (file)
@@ -26,7 +26,6 @@ struct bkey_ops {
        /* Returns reason for being invalid if invalid, else NULL: */
        const char *    (*key_invalid)(const struct bch_fs *,
                                       struct bkey_s_c);
-       void            (*key_debugcheck)(struct bch_fs *, struct bkey_s_c);
        void            (*val_to_text)(struct printbuf *, struct bch_fs *,
                                       struct bkey_s_c);
        void            (*swab)(struct bkey_s);
index 1c8244d4cb8dbbb9b14551c27c6e2fc67f44ccd2..8c9172a8a1123dcdd7cdf2b734cd6920e6c8117a 100644 (file)
@@ -373,8 +373,6 @@ static int btree_gc_mark_node(struct bch_fs *c, struct btree *b, u8 *max_stale,
        bkey_init(&prev.k->k);
 
        while ((k = bch2_btree_node_iter_peek_unpack(&iter, b, &unpacked)).k) {
-               bch2_bkey_debugcheck(c, b, k);
-
                ret = bch2_gc_mark_key(c, b->c.btree_id, b->c.level, false,
                                       k, max_stale, initial);
                if (ret)
@@ -439,6 +437,8 @@ static int bch2_gc_btree(struct bch_fs *c, enum btree_id btree_id,
 
                bch2_trans_cond_resched(&trans);
        }
+       bch2_trans_iter_put(&trans, iter);
+
        ret = bch2_trans_exit(&trans) ?: ret;
        if (ret)
                return ret;
@@ -470,8 +470,6 @@ static int bch2_gc_btree_init_recurse(struct bch_fs *c, struct btree *b,
        bkey_init(&prev.k->k);
 
        while ((k = bch2_btree_and_journal_iter_peek(&iter)).k) {
-               bch2_bkey_debugcheck(c, b, k);
-
                BUG_ON(bkey_cmp(k.k->p, b->data->min_key) < 0);
                BUG_ON(bkey_cmp(k.k->p, b->data->max_key) > 0);
 
@@ -1470,6 +1468,7 @@ static int bch2_coalesce_btree(struct bch_fs *c, enum btree_id btree_id)
        struct btree *b;
        bool kthread = (current->flags & PF_KTHREAD) != 0;
        unsigned i;
+       int ret = 0;
 
        /* Sliding window of adjacent btree nodes */
        struct btree *merge[GC_MERGE_NODES];
@@ -1518,8 +1517,8 @@ static int bch2_coalesce_btree(struct bch_fs *c, enum btree_id btree_id)
                lock_seq[0] = merge[0]->c.lock.state.seq;
 
                if (kthread && kthread_should_stop()) {
-                       bch2_trans_exit(&trans);
-                       return -ESHUTDOWN;
+                       ret = -ESHUTDOWN;
+                       break;
                }
 
                bch2_trans_cond_resched(&trans);
@@ -1534,7 +1533,9 @@ static int bch2_coalesce_btree(struct bch_fs *c, enum btree_id btree_id)
                        memset(merge + 1, 0,
                               (GC_MERGE_NODES - 1) * sizeof(merge[0]));
        }
-       return bch2_trans_exit(&trans);
+       bch2_trans_iter_put(&trans, iter);
+
+       return bch2_trans_exit(&trans) ?: ret;
 }
 
 /**
index dab3a7133ddf10d90251d95dc10687c2e31f8e76..9b74e7997f7bfbddff6b3bcbb4fad64ca9735e1a 100644 (file)
@@ -560,6 +560,26 @@ static int validate_bset(struct bch_fs *c, struct bch_dev *ca,
                     BTREE_ERR_FATAL, c, ca, b, i,
                     "unsupported bset version");
 
+       if (btree_err_on(version < c->sb.version_min,
+                        BTREE_ERR_FIXABLE, c, NULL, b, i,
+                        "bset version %u older than superblock version_min %u",
+                        version, c->sb.version_min)) {
+               mutex_lock(&c->sb_lock);
+               c->disk_sb.sb->version_min = cpu_to_le16(version);
+               bch2_write_super(c);
+               mutex_unlock(&c->sb_lock);
+       }
+
+       if (btree_err_on(version > c->sb.version,
+                        BTREE_ERR_FIXABLE, c, NULL, b, i,
+                        "bset version %u newer than superblock version %u",
+                        version, c->sb.version)) {
+               mutex_lock(&c->sb_lock);
+               c->disk_sb.sb->version = cpu_to_le16(version);
+               bch2_write_super(c);
+               mutex_unlock(&c->sb_lock);
+       }
+
        if (btree_err_on(b->written + sectors > c->opts.btree_node_size,
                         BTREE_ERR_FIXABLE, c, ca, b, i,
                         "bset past end of btree node")) {
@@ -753,6 +773,8 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
        unsigned u64s;
        int ret, retry_read = 0, write = READ;
 
+       b->version_ondisk = U16_MAX;
+
        iter = mempool_alloc(&c->fill_iter, GFP_NOIO);
        sort_iter_init(iter, b);
        iter->size = (btree_blocks(c) + 1) * 2;
@@ -832,6 +854,9 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
                        sectors = vstruct_sectors(bne, c->block_bits);
                }
 
+               b->version_ondisk = min(b->version_ondisk,
+                                       le16_to_cpu(i->version));
+
                ret = validate_bset(c, ca, b, i, sectors,
                                    READ, have_retry);
                if (ret)
@@ -1200,6 +1225,7 @@ retry:
        if (ret)
                goto err;
 out:
+       bch2_trans_iter_put(&trans, iter);
        bch2_trans_exit(&trans);
        bch2_bkey_buf_exit(&k, c);
        bio_put(&wbio->wbio.bio);
index 086d5c1bb66619b90197b8093668bdf081803ff4..ddd3bf5f38453b502862bd3f203cdf2592d4399b 100644 (file)
@@ -9,6 +9,7 @@
 #include "btree_locking.h"
 #include "btree_update.h"
 #include "debug.h"
+#include "error.h"
 #include "extents.h"
 #include "journal.h"
 
@@ -1424,7 +1425,7 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter)
                if (btree_node_read_locked(iter, iter->level))
                        btree_node_unlock(iter, iter->level);
 
-               iter->pos       = bkey_successor(iter->pos);
+               iter->pos = iter->real_pos = bkey_successor(iter->pos);
                iter->level     = iter->min_depth;
 
                btree_iter_set_dirty(iter, BTREE_ITER_NEED_TRAVERSE);
@@ -1496,7 +1497,7 @@ void bch2_btree_iter_set_pos(struct btree_iter *iter, struct bpos new_pos)
        btree_iter_set_search_pos(iter, btree_iter_search_key(iter));
 }
 
-static inline bool bch2_btree_iter_advance_pos(struct btree_iter *iter)
+inline bool bch2_btree_iter_advance_pos(struct btree_iter *iter)
 {
        struct bpos pos = iter->k.p;
        bool ret = bkey_cmp(pos, POS_MAX) != 0;
@@ -1507,7 +1508,7 @@ static inline bool bch2_btree_iter_advance_pos(struct btree_iter *iter)
        return ret;
 }
 
-static inline bool bch2_btree_iter_rewind_pos(struct btree_iter *iter)
+inline bool bch2_btree_iter_rewind_pos(struct btree_iter *iter)
 {
        struct bpos pos = bkey_start_pos(&iter->k);
        bool ret = bkey_cmp(pos, POS_MIN) != 0;
@@ -1955,6 +1956,7 @@ int bch2_trans_iter_put(struct btree_trans *trans,
                return 0;
 
        BUG_ON(trans->iters + iter->idx != iter);
+       BUG_ON(!btree_iter_live(trans, iter));
 
        ret = btree_iter_err(iter);
 
@@ -1972,7 +1974,7 @@ int bch2_trans_iter_free(struct btree_trans *trans,
        if (IS_ERR_OR_NULL(iter))
                return 0;
 
-       trans->iters_touched &= ~(1ULL << iter->idx);
+       set_btree_iter_dontneed(trans, iter);
 
        return bch2_trans_iter_put(trans, iter);
 }
@@ -2116,6 +2118,7 @@ struct btree_iter *bch2_trans_get_node_iter(struct btree_trans *trans,
        for (i = 0; i < ARRAY_SIZE(iter->l); i++)
                iter->l[i].b            = NULL;
        iter->l[iter->level].b          = BTREE_ITER_NO_NODE_INIT;
+       iter->ip_allocated = _RET_IP_;
 
        return iter;
 }
@@ -2133,7 +2136,7 @@ struct btree_iter *__bch2_trans_copy_iter(struct btree_trans *trans,
         * We don't need to preserve this iter since it's cheap to copy it
         * again - this will cause trans_iter_put() to free it right away:
         */
-       trans->iters_touched &= ~(1ULL << iter->idx);
+       set_btree_iter_dontneed(trans, iter);
 
        return iter;
 }
@@ -2214,6 +2217,8 @@ void bch2_trans_reset(struct btree_trans *trans, unsigned flags)
                       (void *) &trans->fs_usage_deltas->memset_start);
        }
 
+       bch2_trans_cond_resched(trans);
+
        if (!(flags & TRANS_RESET_NOTRAVERSE))
                bch2_btree_iter_traverse_all(trans);
 }
@@ -2273,6 +2278,19 @@ int bch2_trans_exit(struct btree_trans *trans)
        bch2_trans_unlock(trans);
 
 #ifdef CONFIG_BCACHEFS_DEBUG
+       if (trans->iters_live) {
+               struct btree_iter *iter;
+
+               bch_err(c, "btree iterators leaked!");
+               trans_for_each_iter(trans, iter)
+                       if (btree_iter_live(trans, iter))
+                               printk(KERN_ERR "  btree %s allocated at %pS\n",
+                                      bch2_btree_ids[iter->btree_id],
+                                      (void *) iter->ip_allocated);
+               /* Be noisy about this: */
+               bch2_fatal_error(c);
+       }
+
        mutex_lock(&trans->c->btree_trans_lock);
        list_del(&trans->list);
        mutex_unlock(&trans->c->btree_trans_lock);
index bd0c429bd91a5962ada19a3806a18d131fb3fc72..c839bfe6ffa48d77a0652f80bb5cd6b0e1f5ce66 100644 (file)
@@ -175,6 +175,8 @@ struct bkey_s_c bch2_btree_iter_prev_slot(struct btree_iter *);
 
 struct bkey_s_c bch2_btree_iter_peek_cached(struct btree_iter *);
 
+bool bch2_btree_iter_advance_pos(struct btree_iter *);
+bool bch2_btree_iter_rewind_pos(struct btree_iter *);
 void bch2_btree_iter_set_pos(struct btree_iter *, struct bpos);
 
 /* Sort order for locking btree iterators: */
@@ -298,6 +300,11 @@ static inline bool btree_iter_keep(struct btree_trans *trans, struct btree_iter
                (iter->flags & BTREE_ITER_KEEP_UNTIL_COMMIT);
 }
 
+static inline void set_btree_iter_dontneed(struct btree_trans *trans, struct btree_iter *iter)
+{
+       trans->iters_touched &= ~(1ULL << iter->idx);
+}
+
 #define TRANS_RESET_NOTRAVERSE         (1 << 0)
 
 void bch2_trans_reset(struct btree_trans *, unsigned);
index 2230da8b3acdefe87f9a22d42184df80bdaa9faa..0b3545637bb39819690c20ee4e13480f09bbe31c 100644 (file)
@@ -171,23 +171,21 @@ static int btree_key_cache_fill(struct btree_trans *trans,
                                   ck->key.pos, BTREE_ITER_SLOTS);
        k = bch2_btree_iter_peek_slot(iter);
        ret = bkey_err(k);
-       if (ret) {
-               bch2_trans_iter_put(trans, iter);
-               return ret;
-       }
+       if (ret)
+               goto err;
 
        if (!bch2_btree_node_relock(ck_iter, 0)) {
-               bch2_trans_iter_put(trans, iter);
                trace_transaction_restart_ip(trans->ip, _THIS_IP_);
-               return -EINTR;
+               ret = -EINTR;
+               goto err;
        }
 
        if (k.k->u64s > ck->u64s) {
                new_u64s = roundup_pow_of_two(k.k->u64s);
                new_k = kmalloc(new_u64s * sizeof(u64), GFP_NOFS);
                if (!new_k) {
-                       bch2_trans_iter_put(trans, iter);
-                       return -ENOMEM;
+                       ret = -ENOMEM;
+                       goto err;
                }
        }
 
@@ -203,9 +201,10 @@ static int btree_key_cache_fill(struct btree_trans *trans,
        bch2_btree_node_unlock_write(ck_iter->l[0].b, ck_iter);
 
        /* We're not likely to need this iterator again: */
-       bch2_trans_iter_free(trans, iter);
-
-       return 0;
+       set_btree_iter_dontneed(trans, iter);
+err:
+       bch2_trans_iter_put(trans, iter);
+       return ret;
 }
 
 static int bkey_cached_check_fn(struct six_lock *lock, void *p)
index c3148079a822e18cc2613fdbc0f5358f500b8fac..5999044ab023357b1fbcb8e451655c6b907cc906 100644 (file)
@@ -76,6 +76,7 @@ struct btree {
        u16                     written;
        u8                      nsets;
        u8                      nr_key_bits;
+       u16                     version_ondisk;
 
        struct bkey_format      format;
 
index df06c4a8625df1c8727cf3bc34a59cf50b4e62bd..4c0e3d7c8ddff3a30ea9eb235e637291e098e0b4 100644 (file)
@@ -282,6 +282,7 @@ static struct btree *bch2_btree_node_alloc(struct btree_update *as, unsigned lev
        bch2_bset_init_first(b, &b->data->keys);
        b->c.level      = level;
        b->c.btree_id   = as->btree_id;
+       b->version_ondisk = c->sb.version;
 
        memset(&b->nr, 0, sizeof(b->nr));
        b->data->magic = cpu_to_le64(bset_magic(c));
index d7937bdf804bbed0200f4926e856f0fe8af75313..ed3009b8b157007b48dddb502df61d3180a99165 100644 (file)
@@ -754,7 +754,7 @@ static int extent_handle_overwrites(struct btree_trans *trans,
                                    enum btree_id btree_id,
                                    struct bpos start, struct bpos end)
 {
-       struct btree_iter *iter = NULL, *update_iter;
+       struct btree_iter *iter, *update_iter;
        struct bkey_i *update;
        struct bkey_s_c k;
        int ret = 0;
@@ -767,8 +767,6 @@ static int extent_handle_overwrites(struct btree_trans *trans,
                        break;
 
                if (bkey_cmp(bkey_start_pos(k.k), start) < 0) {
-                       update_iter = bch2_trans_copy_iter(trans, iter);
-
                        update = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
                        if ((ret = PTR_ERR_OR_ZERO(update)))
                                goto err;
@@ -776,6 +774,7 @@ static int extent_handle_overwrites(struct btree_trans *trans,
                        bkey_reassemble(update, k);
                        bch2_cut_back(start, update);
 
+                       update_iter = bch2_trans_copy_iter(trans, iter);
                        update_iter->flags &= ~BTREE_ITER_IS_EXTENTS;
                        bch2_btree_iter_set_pos(update_iter, update->k.p);
                        ret = bch2_trans_update2(trans, update_iter, update);
@@ -785,8 +784,6 @@ static int extent_handle_overwrites(struct btree_trans *trans,
                }
 
                if (bkey_cmp(k.k->p, end) > 0) {
-                       update_iter = bch2_trans_copy_iter(trans, iter);
-
                        update = bch2_trans_kmalloc(trans, bkey_bytes(k.k));
                        if ((ret = PTR_ERR_OR_ZERO(update)))
                                goto err;
@@ -794,6 +791,7 @@ static int extent_handle_overwrites(struct btree_trans *trans,
                        bkey_reassemble(update, k);
                        bch2_cut_front(end, update);
 
+                       update_iter = bch2_trans_copy_iter(trans, iter);
                        update_iter->flags &= ~BTREE_ITER_IS_EXTENTS;
                        bch2_btree_iter_set_pos(update_iter, update->k.p);
                        ret = bch2_trans_update2(trans, update_iter, update);
@@ -801,8 +799,6 @@ static int extent_handle_overwrites(struct btree_trans *trans,
                        if (ret)
                                goto err;
                } else {
-                       update_iter = bch2_trans_copy_iter(trans, iter);
-
                        update = bch2_trans_kmalloc(trans, sizeof(struct bkey));
                        if ((ret = PTR_ERR_OR_ZERO(update)))
                                goto err;
@@ -812,6 +808,7 @@ static int extent_handle_overwrites(struct btree_trans *trans,
                        update->k.type = KEY_TYPE_deleted;
                        update->k.size = 0;
 
+                       update_iter = bch2_trans_copy_iter(trans, iter);
                        update_iter->flags &= ~BTREE_ITER_IS_EXTENTS;
                        bch2_btree_iter_set_pos(update_iter, update->k.p);
                        ret = bch2_trans_update2(trans, update_iter, update);
@@ -823,8 +820,7 @@ static int extent_handle_overwrites(struct btree_trans *trans,
                k = bch2_btree_iter_next_with_updates(iter);
        }
 err:
-       if (!IS_ERR_OR_NULL(iter))
-               bch2_trans_iter_put(trans, iter);
+       bch2_trans_iter_put(trans, iter);
        return ret;
 }
 
index be59e37e0a2f447d1b2b84b40a4dcbdf18cc56fd..e6e752353f523833fc735961db991974478f5290 100644 (file)
@@ -1481,6 +1481,10 @@ static struct btree_iter *trans_get_update(struct btree_trans *trans,
                       bkey_cmp(pos, i->k->k.p) < 0
                     : !bkey_cmp(pos, i->iter->pos))) {
                        *k = bkey_i_to_s_c(i->k);
+
+                       /* ugly hack.. */
+                       BUG_ON(btree_iter_live(trans, i->iter));
+                       trans->iters_live |= 1ULL << i->iter->idx;
                        return i->iter;
                }
 
index 06dbca32e1893e749b64077882d43a8e1bd7b323..cce747da8b9e42f7c9fa926c7f085d75009b1a78 100644 (file)
@@ -242,6 +242,8 @@ static ssize_t bch2_read_btree(struct file *file, char __user *buf,
                if (!i->size)
                        break;
        }
+       bch2_trans_iter_put(&trans, iter);
+
        bch2_trans_exit(&trans);
 
        return err < 0 ? err : i->ret;
@@ -294,6 +296,8 @@ static ssize_t bch2_read_btree_formats(struct file *file, char __user *buf,
                if (!i->size)
                        break;
        }
+       bch2_trans_iter_put(&trans, iter);
+
        bch2_trans_exit(&trans);
 
        return err < 0 ? err : i->ret;
index b0625176ab35bf8732fbc0b63325254cefa99630..592dd80cf963959f4b23f1ae4f463227bfa655e6 100644 (file)
@@ -321,6 +321,7 @@ u64 bch2_dirent_lookup(struct bch_fs *c, u64 dir_inum,
 
        k = bch2_btree_iter_peek_slot(iter);
        inum = le64_to_cpu(bkey_s_c_to_dirent(k).v->d_inum);
+       bch2_trans_iter_put(&trans, iter);
 out:
        bch2_trans_exit(&trans);
        return inum;
@@ -379,6 +380,8 @@ int bch2_readdir(struct bch_fs *c, u64 inum, struct dir_context *ctx)
                        break;
                ctx->pos = dirent.k->p.offset + 1;
        }
+       bch2_trans_iter_put(&trans, iter);
+
        ret = bch2_trans_exit(&trans) ?: ret;
 
        return ret;
index e36ef0956f8f6da8e2956a201f7b43f951b6d048..8d94ee70b80a57f4ace601e49b125a4dd14ddf01 100644 (file)
@@ -1663,12 +1663,13 @@ int bch2_ec_mem_alloc(struct bch_fs *c, bool gc)
        int ret = 0;
 
        bch2_trans_init(&trans, c, 0, 0);
-
        iter = bch2_trans_get_iter(&trans, BTREE_ID_stripes, POS(0, U64_MAX), 0);
 
        k = bch2_btree_iter_prev(iter);
        if (!IS_ERR_OR_NULL(k.k))
                idx = k.k->p.offset + 1;
+
+       bch2_trans_iter_put(&trans, iter);
        ret = bch2_trans_exit(&trans);
        if (ret)
                return ret;
index 34f0e469598d4a8cb6e76ff86ef44e18d71971c7..8ed3f73b3044e0cdd8c007e87d3f096f5cd10860 100644 (file)
@@ -164,46 +164,6 @@ const char *bch2_btree_ptr_invalid(const struct bch_fs *c, struct bkey_s_c k)
        return bch2_bkey_ptrs_invalid(c, k);
 }
 
-void bch2_btree_ptr_debugcheck(struct bch_fs *c, struct bkey_s_c k)
-{
-       struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
-       const struct bch_extent_ptr *ptr;
-       const char *err;
-       char buf[160];
-       struct bucket_mark mark;
-       struct bch_dev *ca;
-
-       if (!test_bit(BCH_FS_INITIAL_GC_DONE, &c->flags))
-               return;
-
-       if (!percpu_down_read_trylock(&c->mark_lock))
-               return;
-
-       bkey_for_each_ptr(ptrs, ptr) {
-               ca = bch_dev_bkey_exists(c, ptr->dev);
-
-               mark = ptr_bucket_mark(ca, ptr);
-
-               err = "stale";
-               if (gen_after(mark.gen, ptr->gen))
-                       goto err;
-
-               err = "inconsistent";
-               if (mark.data_type != BCH_DATA_btree ||
-                   mark.dirty_sectors < c->opts.btree_node_size)
-                       goto err;
-       }
-out:
-       percpu_up_read(&c->mark_lock);
-       return;
-err:
-       bch2_fs_inconsistent(c, "%s btree pointer %s: bucket %zi gen %i mark %08x",
-               err, (bch2_bkey_val_to_text(&PBUF(buf), c, k), buf),
-               PTR_BUCKET_NR(ca, ptr),
-               mark.gen, (unsigned) mark.v.counter);
-       goto out;
-}
-
 void bch2_btree_ptr_to_text(struct printbuf *out, struct bch_fs *c,
                            struct bkey_s_c k)
 {
@@ -247,49 +207,6 @@ const char *bch2_extent_invalid(const struct bch_fs *c, struct bkey_s_c k)
        return bch2_bkey_ptrs_invalid(c, k);
 }
 
-void bch2_extent_debugcheck(struct bch_fs *c, struct bkey_s_c k)
-{
-       struct bkey_s_c_extent e = bkey_s_c_to_extent(k);
-       const union bch_extent_entry *entry;
-       struct extent_ptr_decoded p;
-       char buf[160];
-
-       if (!test_bit(JOURNAL_REPLAY_DONE, &c->journal.flags) ||
-           !test_bit(BCH_FS_INITIAL_GC_DONE, &c->flags))
-               return;
-
-       if (!percpu_down_read_trylock(&c->mark_lock))
-               return;
-
-       extent_for_each_ptr_decode(e, p, entry) {
-               struct bch_dev *ca      = bch_dev_bkey_exists(c, p.ptr.dev);
-               struct bucket_mark mark = ptr_bucket_mark(ca, &p.ptr);
-               unsigned stale          = gen_after(mark.gen, p.ptr.gen);
-               unsigned disk_sectors   = ptr_disk_sectors(p);
-               unsigned mark_sectors   = p.ptr.cached
-                       ? mark.cached_sectors
-                       : mark.dirty_sectors;
-
-               bch2_fs_inconsistent_on(stale && !p.ptr.cached, c,
-                       "stale dirty pointer (ptr gen %u bucket %u",
-                       p.ptr.gen, mark.gen);
-
-               bch2_fs_inconsistent_on(stale > 96, c,
-                       "key too stale: %i", stale);
-
-               bch2_fs_inconsistent_on(!stale &&
-                       (mark.data_type != BCH_DATA_user ||
-                        mark_sectors < disk_sectors), c,
-                       "extent pointer not marked: %s:\n"
-                       "type %u sectors %u < %u",
-                       (bch2_bkey_val_to_text(&PBUF(buf), c, e.s_c), buf),
-                       mark.data_type,
-                       mark_sectors, disk_sectors);
-       }
-
-       percpu_up_read(&c->mark_lock);
-}
-
 void bch2_extent_to_text(struct printbuf *out, struct bch_fs *c,
                         struct bkey_s_c k)
 {
@@ -688,6 +605,8 @@ bool bch2_check_range_allocated(struct bch_fs *c, struct bpos pos, u64 size,
                        break;
                }
        }
+       bch2_trans_iter_put(&trans, iter);
+
        bch2_trans_exit(&trans);
 
        return ret;
@@ -1265,7 +1184,7 @@ int bch2_cut_back_s(struct bpos where, struct bkey_s k)
 
        len = where.offset - bkey_start_offset(k.k);
 
-       k.k->p = where;
+       k.k->p.offset = where.offset;
        k.k->size = len;
 
        if (!len) {
index 3988315fc4043a336233194cd3af8a46e1425ff7..2ee50a24501e8b0437dd2c943791802f5f7ebdab 100644 (file)
@@ -368,7 +368,6 @@ int bch2_bkey_pick_read_device(struct bch_fs *, struct bkey_s_c,
 /* KEY_TYPE_btree_ptr: */
 
 const char *bch2_btree_ptr_invalid(const struct bch_fs *, struct bkey_s_c);
-void bch2_btree_ptr_debugcheck(struct bch_fs *, struct bkey_s_c);
 void bch2_btree_ptr_to_text(struct printbuf *, struct bch_fs *,
                            struct bkey_s_c);
 
@@ -379,14 +378,12 @@ void bch2_btree_ptr_v2_compat(enum btree_id, unsigned, unsigned,
 
 #define bch2_bkey_ops_btree_ptr (struct bkey_ops) {            \
        .key_invalid    = bch2_btree_ptr_invalid,               \
-       .key_debugcheck = bch2_btree_ptr_debugcheck,            \
        .val_to_text    = bch2_btree_ptr_to_text,               \
        .swab           = bch2_ptr_swab,                        \
 }
 
 #define bch2_bkey_ops_btree_ptr_v2 (struct bkey_ops) {         \
        .key_invalid    = bch2_btree_ptr_invalid,               \
-       .key_debugcheck = bch2_btree_ptr_debugcheck,            \
        .val_to_text    = bch2_btree_ptr_v2_to_text,            \
        .swab           = bch2_ptr_swab,                        \
        .compat         = bch2_btree_ptr_v2_compat,             \
@@ -395,14 +392,12 @@ void bch2_btree_ptr_v2_compat(enum btree_id, unsigned, unsigned,
 /* KEY_TYPE_extent: */
 
 const char *bch2_extent_invalid(const struct bch_fs *, struct bkey_s_c);
-void bch2_extent_debugcheck(struct bch_fs *, struct bkey_s_c);
 void bch2_extent_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 enum merge_result bch2_extent_merge(struct bch_fs *,
                                    struct bkey_s, struct bkey_s);
 
 #define bch2_bkey_ops_extent (struct bkey_ops) {               \
        .key_invalid    = bch2_extent_invalid,                  \
-       .key_debugcheck = bch2_extent_debugcheck,               \
        .val_to_text    = bch2_extent_to_text,                  \
        .swab           = bch2_ptr_swab,                        \
        .key_normalize  = bch2_extent_normalize,                \
index 0322960d3114205c29df1fc8227d560bba7a0161..1a94e7f7cd9615c8eb246c18748808ce2606eee8 100644 (file)
@@ -883,7 +883,6 @@ void bch2_readahead(struct readahead_control *ractl)
        BUG_ON(ret);
 
        bch2_trans_init(&trans, c, 0, 0);
-
        iter = bch2_trans_get_iter(&trans, BTREE_ID_extents, POS_MIN,
                                   BTREE_ITER_SLOTS);
 
@@ -912,6 +911,7 @@ void bch2_readahead(struct readahead_control *ractl)
 
        bch2_pagecache_add_put(&inode->ei_pagecache_lock);
 
+       bch2_trans_iter_put(&trans, iter);
        bch2_trans_exit(&trans);
        kfree(readpages_iter.pages);
 }
@@ -935,6 +935,7 @@ static void __bchfs_readpage(struct bch_fs *c, struct bch_read_bio *rbio,
 
        bchfs_read(&trans, iter, rbio, inum, NULL);
 
+       bch2_trans_iter_put(&trans, iter);
        bch2_trans_exit(&trans);
 }
 
@@ -2143,6 +2144,7 @@ static inline int range_has_data(struct bch_fs *c,
                        break;
                }
        }
+       bch2_trans_iter_put(&trans, iter);
 
        return bch2_trans_exit(&trans) ?: ret;
 }
@@ -2312,6 +2314,7 @@ int bch2_truncate(struct bch_inode_info *inode, struct iattr *iattr)
        bch2_trans_init(&trans, c, 0, 0);
        iter = bch2_inode_peek(&trans, &inode_u, inode->v.i_ino, 0);
        ret = PTR_ERR_OR_ZERO(iter);
+       bch2_trans_iter_put(&trans, iter);
        bch2_trans_exit(&trans);
 
        if (ret)
@@ -2445,14 +2448,11 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
        struct btree_iter *src, *dst, *del;
        loff_t shift, new_size;
        u64 src_start;
-       int ret;
+       int ret = 0;
 
        if ((offset | len) & (block_bytes(c) - 1))
                return -EINVAL;
 
-       bch2_bkey_buf_init(&copy);
-       bch2_trans_init(&trans, c, BTREE_ITER_MAX, 256);
-
        /*
         * We need i_mutex to keep the page cache consistent with the extents
         * btree, and the btree consistent with i_size - we don't need outside
@@ -2508,13 +2508,15 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
                        goto err;
        }
 
+       bch2_bkey_buf_init(&copy);
+       bch2_trans_init(&trans, c, BTREE_ITER_MAX, 256);
        src = bch2_trans_get_iter(&trans, BTREE_ID_extents,
                        POS(inode->v.i_ino, src_start >> 9),
                        BTREE_ITER_INTENT);
        dst = bch2_trans_copy_iter(&trans, src);
        del = bch2_trans_copy_iter(&trans, src);
 
-       while (1) {
+       while (ret == 0 || ret == -EINTR) {
                struct disk_reservation disk_res =
                        bch2_disk_reservation_init(c, 0);
                struct bkey_i delete;
@@ -2528,7 +2530,7 @@ static long bchfs_fcollapse_finsert(struct bch_inode_info *inode,
                        ? bch2_btree_iter_peek_prev(src)
                        : bch2_btree_iter_peek(src);
                if ((ret = bkey_err(k)))
-                       goto bkey_err;
+                       continue;
 
                if (!k.k || k.k->p.inode != inode->v.i_ino)
                        break;
@@ -2548,7 +2550,7 @@ reassemble:
 
                ret = bch2_extent_atomic_end(dst, copy.k, &atomic_end);
                if (ret)
-                       goto bkey_err;
+                       continue;
 
                if (bkey_cmp(atomic_end, copy.k->k.p)) {
                        if (insert) {
@@ -2591,18 +2593,18 @@ reassemble:
                                          &inode->ei_journal_seq,
                                          BTREE_INSERT_NOFAIL);
                bch2_disk_reservation_put(c, &disk_res);
-bkey_err:
+
                if (!ret)
                        bch2_btree_iter_set_pos(src, next_pos);
-
-               if (ret == -EINTR)
-                       ret = 0;
-               if (ret)
-                       goto err;
-
-               bch2_trans_cond_resched(&trans);
        }
-       bch2_trans_unlock(&trans);
+       bch2_trans_iter_put(&trans, del);
+       bch2_trans_iter_put(&trans, dst);
+       bch2_trans_iter_put(&trans, src);
+       bch2_trans_exit(&trans);
+       bch2_bkey_buf_exit(&copy, c);
+
+       if (ret)
+               goto err;
 
        if (!insert) {
                i_size_write(&inode->v, new_size);
@@ -2612,8 +2614,6 @@ bkey_err:
                mutex_unlock(&inode->ei_update_lock);
        }
 err:
-       bch2_trans_exit(&trans);
-       bch2_bkey_buf_exit(&copy, c);
        bch2_pagecache_block_put(&inode->ei_pagecache_lock);
        inode_unlock(&inode->v);
        return ret;
@@ -2668,7 +2668,7 @@ static long bchfs_fallocate(struct bch_inode_info *inode, int mode,
                        BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
        end_pos = POS(inode->v.i_ino, block_end >> 9);
 
-       while (bkey_cmp(iter->pos, end_pos) < 0) {
+       while (!ret && bkey_cmp(iter->pos, end_pos) < 0) {
                s64 i_sectors_delta = 0;
                struct disk_reservation disk_res = { 0 };
                struct quota_res quota_res = { 0 };
@@ -2732,9 +2732,11 @@ bkey_err:
                bch2_disk_reservation_put(c, &disk_res);
                if (ret == -EINTR)
                        ret = 0;
-               if (ret)
-                       goto err;
        }
+       bch2_trans_iter_put(&trans, iter);
+
+       if (ret)
+               goto err;
 
        /*
         * Do we need to extend the file?
@@ -2756,6 +2758,7 @@ bkey_err:
                        ret = PTR_ERR_OR_ZERO(inode_iter);
                } while (ret == -EINTR);
 
+               bch2_trans_iter_put(&trans, inode_iter);
                bch2_trans_unlock(&trans);
 
                if (ret)
@@ -3003,6 +3006,7 @@ static loff_t bch2_seek_data(struct file *file, u64 offset)
                } else if (k.k->p.offset >> 9 > isize)
                        break;
        }
+       bch2_trans_iter_put(&trans, iter);
 
        ret = bch2_trans_exit(&trans) ?: ret;
        if (ret)
@@ -3106,6 +3110,7 @@ static loff_t bch2_seek_hole(struct file *file, u64 offset)
                        offset = max(offset, bkey_start_offset(k.k) << 9);
                }
        }
+       bch2_trans_iter_put(&trans, iter);
 
        ret = bch2_trans_exit(&trans) ?: ret;
        if (ret)
index 0301ab19fd60c4802cee01bc677739a01028dc05..1cca02f0aa3de2cf3ddb0e714e79e4b685cda278 100644 (file)
@@ -725,6 +725,8 @@ retry:
                                  BTREE_INSERT_NOUNLOCK|
                                  BTREE_INSERT_NOFAIL);
 btree_err:
+       bch2_trans_iter_put(&trans, inode_iter);
+
        if (ret == -EINTR)
                goto retry;
        if (unlikely(ret))
@@ -948,6 +950,7 @@ retry:
                ret = bch2_fill_extent(c, info, bkey_i_to_s_c(prev.k),
                                       FIEMAP_EXTENT_LAST);
 
+       bch2_trans_iter_put(&trans, iter);
        ret = bch2_trans_exit(&trans) ?: ret;
        bch2_bkey_buf_exit(&cur, c);
        bch2_bkey_buf_exit(&prev, c);
index 7f6b4ac48f3d895c00676ba072907a8f4a9a5cd3..c902abc10221a34f4ca226b5bb8b07387625e62e 100644 (file)
@@ -319,7 +319,7 @@ static int hash_check_key(struct btree_trans *trans,
                        bch_err(c, "hash_redo_key err %i", ret);
                        return ret;
                }
-               return 1;
+               return -EINTR;
        }
 
        ret = hash_check_duplicates(trans, desc, h, k_iter, k);
@@ -413,18 +413,10 @@ err_redo:
        goto err;
 }
 
-static int bch2_inode_truncate(struct bch_fs *c, u64 inode_nr, u64 new_size)
-{
-       return bch2_btree_delete_range(c, BTREE_ID_extents,
-                       POS(inode_nr, round_up(new_size, block_bytes(c)) >> 9),
-                       POS(inode_nr + 1, 0), NULL);
-}
-
-static int bch2_fix_overlapping_extent(struct btree_trans *trans,
-                                      struct btree_iter *iter,
+static int fix_overlapping_extent(struct btree_trans *trans,
                                       struct bkey_s_c k, struct bpos cut_at)
 {
-       struct btree_iter *u_iter;
+       struct btree_iter *iter;
        struct bkey_i *u;
        int ret;
 
@@ -436,22 +428,24 @@ static int bch2_fix_overlapping_extent(struct btree_trans *trans,
        bkey_reassemble(u, k);
        bch2_cut_front(cut_at, u);
 
-       u_iter = bch2_trans_copy_iter(trans, iter);
 
        /*
-        * We don't want to go through the
-        * extent_handle_overwrites path:
+        * We don't want to go through the extent_handle_overwrites path:
+        *
+        * XXX: this is going to screw up disk accounting, extent triggers
+        * assume things about extent overwrites - we should be running the
+        * triggers manually here
         */
-       u_iter->flags &= ~BTREE_ITER_IS_EXTENTS;
-       bch2_btree_iter_set_pos(u_iter, u->k.p);
+       iter = bch2_trans_get_iter(trans, BTREE_ID_extents, u->k.p,
+                                  BTREE_ITER_INTENT|BTREE_ITER_NOT_EXTENTS);
 
-       /*
-        * XXX: this is going to leave disk space
-        * accounting slightly wrong
-        */
-       ret = bch2_trans_update(trans, u_iter, u, 0);
-       bch2_trans_iter_put(trans, u_iter);
-       return ret;
+       BUG_ON(iter->flags & BTREE_ITER_IS_EXTENTS);
+       bch2_trans_update(trans, iter, u, BTREE_TRIGGER_NORUN);
+       bch2_trans_iter_put(trans, iter);
+
+       return bch2_trans_commit(trans, NULL, NULL,
+                                BTREE_INSERT_NOFAIL|
+                                BTREE_INSERT_LAZY_RW);
 }
 
 /*
@@ -466,7 +460,7 @@ static int check_extents(struct bch_fs *c)
        struct btree_iter *iter;
        struct bkey_s_c k;
        struct bkey_buf prev;
-       u64 i_sectors;
+       u64 i_sectors = 0;
        int ret = 0;
 
        bch2_bkey_buf_init(&prev);
@@ -479,97 +473,86 @@ static int check_extents(struct bch_fs *c)
                                   POS(BCACHEFS_ROOT_INO, 0),
                                   BTREE_ITER_INTENT);
 retry:
-       for_each_btree_key_continue(iter, 0, k, ret) {
-               /*
-                * due to retry errors we might see the same extent twice:
-                */
-               if (bkey_cmp(prev.k->k.p, k.k->p) &&
-                   bkey_cmp(prev.k->k.p, bkey_start_pos(k.k)) > 0) {
+       while ((k = bch2_btree_iter_peek(iter)).k &&
+              !(ret = bkey_err(k))) {
+               if (w.have_inode &&
+                   w.cur_inum != k.k->p.inode &&
+                   !(w.inode.bi_flags & BCH_INODE_I_SECTORS_DIRTY) &&
+                   fsck_err_on(w.inode.bi_sectors != i_sectors, c,
+                               "inode %llu has incorrect i_sectors: got %llu, should be %llu",
+                               w.inode.bi_inum,
+                               w.inode.bi_sectors, i_sectors)) {
+                       struct btree_iter *inode_iter =
+                               bch2_trans_get_iter(&trans, BTREE_ID_inodes,
+                                                   POS(0, w.cur_inum),
+                                                   BTREE_ITER_INTENT);
+
+                       w.inode.bi_sectors = i_sectors;
+
+                       ret = __bch2_trans_do(&trans, NULL, NULL,
+                                             BTREE_INSERT_NOFAIL|
+                                             BTREE_INSERT_LAZY_RW,
+                                             bch2_inode_write(&trans, inode_iter, &w.inode));
+                       bch2_trans_iter_put(&trans, inode_iter);
+                       if (ret)
+                               break;
+               }
+
+               if (bkey_cmp(prev.k->k.p, bkey_start_pos(k.k)) > 0) {
                        char buf1[200];
                        char buf2[200];
 
                        bch2_bkey_val_to_text(&PBUF(buf1), c, bkey_i_to_s_c(prev.k));
                        bch2_bkey_val_to_text(&PBUF(buf2), c, k);
 
-                       if (fsck_err(c, "overlapping extents:\n%s\n%s", buf1, buf2)) {
-                               ret = __bch2_trans_do(&trans, NULL, NULL,
-                                                     BTREE_INSERT_NOFAIL|
-                                                     BTREE_INSERT_LAZY_RW,
-                                               bch2_fix_overlapping_extent(&trans,
-                                                               iter, k, prev.k->k.p));
-                               if (ret)
-                                       goto err;
-                       }
+                       if (fsck_err(c, "overlapping extents:\n%s\n%s", buf1, buf2))
+                               return fix_overlapping_extent(&trans, k, prev.k->k.p) ?: -EINTR;
                }
-               bch2_bkey_buf_reassemble(&prev, c, k);
 
                ret = walk_inode(&trans, &w, k.k->p.inode);
                if (ret)
                        break;
 
+               if (w.first_this_inode)
+                       i_sectors = 0;
+
                if (fsck_err_on(!w.have_inode, c,
-                       "extent type %u for missing inode %llu",
-                       k.k->type, k.k->p.inode) ||
+                               "extent type %u for missing inode %llu",
+                               k.k->type, k.k->p.inode) ||
                    fsck_err_on(w.have_inode &&
-                       !S_ISREG(w.inode.bi_mode) && !S_ISLNK(w.inode.bi_mode), c,
-                       "extent type %u for non regular file, inode %llu mode %o",
-                       k.k->type, k.k->p.inode, w.inode.bi_mode)) {
-                       bch2_trans_unlock(&trans);
-
-                       ret = bch2_inode_truncate(c, k.k->p.inode, 0);
-                       if (ret)
-                               goto err;
-                       continue;
+                               !S_ISREG(w.inode.bi_mode) && !S_ISLNK(w.inode.bi_mode), c,
+                               "extent type %u for non regular file, inode %llu mode %o",
+                               k.k->type, k.k->p.inode, w.inode.bi_mode)) {
+                       bch2_fs_lazy_rw(c);
+                       return bch2_btree_delete_range_trans(&trans, BTREE_ID_extents,
+                                                      POS(k.k->p.inode, 0),
+                                                      POS(k.k->p.inode, U64_MAX),
+                                                      NULL) ?: -EINTR;
                }
 
-               if (fsck_err_on(w.first_this_inode &&
-                       w.have_inode &&
-                       !(w.inode.bi_flags & BCH_INODE_I_SECTORS_DIRTY) &&
-                       w.inode.bi_sectors !=
-                       (i_sectors = bch2_count_inode_sectors(&trans, w.cur_inum)),
-                       c, "inode %llu has incorrect i_sectors: got %llu, should be %llu",
-                       w.inode.bi_inum,
-                       w.inode.bi_sectors, i_sectors)) {
-                       struct bkey_inode_buf p;
-
-                       w.inode.bi_sectors = i_sectors;
-
-                       bch2_trans_unlock(&trans);
-
-                       bch2_inode_pack(c, &p, &w.inode);
-
-                       ret = bch2_btree_insert(c, BTREE_ID_inodes,
-                                               &p.inode.k_i, NULL, NULL,
-                                               BTREE_INSERT_NOFAIL|
-                                               BTREE_INSERT_LAZY_RW);
-                       if (ret) {
-                               bch_err(c, "error in fsck: error %i updating inode", ret);
-                               goto err;
-                       }
-
-                       /* revalidate iterator: */
-                       k = bch2_btree_iter_peek(iter);
+               if (fsck_err_on(w.have_inode &&
+                               !(w.inode.bi_flags & BCH_INODE_I_SIZE_DIRTY) &&
+                               k.k->type != KEY_TYPE_reservation &&
+                               k.k->p.offset > round_up(w.inode.bi_size, block_bytes(c)) >> 9, c,
+                               "extent type %u offset %llu past end of inode %llu, i_size %llu",
+                               k.k->type, k.k->p.offset, k.k->p.inode, w.inode.bi_size)) {
+                       bch2_fs_lazy_rw(c);
+                       return bch2_btree_delete_range_trans(&trans, BTREE_ID_extents,
+                                       POS(k.k->p.inode, round_up(w.inode.bi_size, block_bytes(c))),
+                                       POS(k.k->p.inode, U64_MAX),
+                                       NULL) ?: -EINTR;
                }
 
-               if (fsck_err_on(w.have_inode &&
-                       !(w.inode.bi_flags & BCH_INODE_I_SIZE_DIRTY) &&
-                       k.k->type != KEY_TYPE_reservation &&
-                       k.k->p.offset > round_up(w.inode.bi_size, block_bytes(c)) >> 9, c,
-                       "extent type %u offset %llu past end of inode %llu, i_size %llu",
-                       k.k->type, k.k->p.offset, k.k->p.inode, w.inode.bi_size)) {
-                       bch2_trans_unlock(&trans);
+               if (bkey_extent_is_allocation(k.k))
+                       i_sectors += k.k->size;
+               bch2_bkey_buf_reassemble(&prev, c, k);
 
-                       ret = bch2_inode_truncate(c, k.k->p.inode,
-                                                 w.inode.bi_size);
-                       if (ret)
-                               goto err;
-                       continue;
-               }
+               bch2_btree_iter_advance_pos(iter);
        }
-err:
 fsck_err:
        if (ret == -EINTR)
                goto retry;
+       bch2_trans_iter_put(&trans, iter);
        bch2_bkey_buf_exit(&prev, c);
        return bch2_trans_exit(&trans) ?: ret;
 }
@@ -599,7 +582,8 @@ static int check_dirents(struct bch_fs *c)
        iter = bch2_trans_get_iter(&trans, BTREE_ID_dirents,
                                   POS(BCACHEFS_ROOT_INO, 0), 0);
 retry:
-       for_each_btree_key_continue(iter, 0, k, ret) {
+       while ((k = bch2_btree_iter_peek(iter)).k &&
+              !(ret = bkey_err(k))) {
                struct bkey_s_c_dirent d;
                struct bch_inode_unpacked target;
                bool have_target;
@@ -718,6 +702,8 @@ retry:
                                goto err;
 
                }
+
+               bch2_btree_iter_advance_pos(iter);
        }
 
        hash_stop_chain(&trans, &h);
@@ -726,6 +712,8 @@ fsck_err:
        if (ret == -EINTR)
                goto retry;
 
+       bch2_trans_iter_put(&trans, h.chain);
+       bch2_trans_iter_put(&trans, iter);
        return bch2_trans_exit(&trans) ?: ret;
 }
 
@@ -751,7 +739,8 @@ static int check_xattrs(struct bch_fs *c)
        iter = bch2_trans_get_iter(&trans, BTREE_ID_xattrs,
                                   POS(BCACHEFS_ROOT_INO, 0), 0);
 retry:
-       for_each_btree_key_continue(iter, 0, k, ret) {
+       while ((k = bch2_btree_iter_peek(iter)).k &&
+              !(ret = bkey_err(k))) {
                ret = walk_inode(&trans, &w, k.k->p.inode);
                if (ret)
                        break;
@@ -761,7 +750,7 @@ retry:
                                k.k->p.inode)) {
                        ret = bch2_btree_delete_at(&trans, iter, 0);
                        if (ret)
-                               goto err;
+                               break;
                        continue;
                }
 
@@ -771,12 +760,16 @@ retry:
                ret = hash_check_key(&trans, bch2_xattr_hash_desc,
                                     &h, iter, k);
                if (ret)
-                       goto fsck_err;
+                       break;
+
+               bch2_btree_iter_advance_pos(iter);
        }
-err:
 fsck_err:
        if (ret == -EINTR)
                goto retry;
+
+       bch2_trans_iter_put(&trans, h.chain);
+       bch2_trans_iter_put(&trans, iter);
        return bch2_trans_exit(&trans) ?: ret;
 }
 
@@ -1127,6 +1120,8 @@ static int bch2_gc_walk_dirents(struct bch_fs *c, nlink_table *links,
 
                bch2_trans_cond_resched(&trans);
        }
+       bch2_trans_iter_put(&trans, iter);
+
        ret = bch2_trans_exit(&trans) ?: ret;
        if (ret)
                bch_err(c, "error in fsck: btree error %i while walking dirents", ret);
@@ -1279,8 +1274,10 @@ static int check_inode(struct btree_trans *trans,
                 * XXX: need to truncate partial blocks too here - or ideally
                 * just switch units to bytes and that issue goes away
                 */
-
-               ret = bch2_inode_truncate(c, u.bi_inum, u.bi_size);
+               ret = bch2_btree_delete_range_trans(trans, BTREE_ID_extents,
+                               POS(u.bi_inum, round_up(u.bi_size, block_bytes(c))),
+                               POS(u.bi_inum, U64_MAX),
+                               NULL);
                if (ret) {
                        bch_err(c, "error in fsck: error %i truncating inode", ret);
                        return ret;
@@ -1392,10 +1389,11 @@ peek_nlinks:    link = genradix_iter_peek(&nlinks_iter, links);
                if (nlinks_pos == iter->pos.offset)
                        genradix_iter_advance(&nlinks_iter, links);
 
-               bch2_btree_iter_next(iter);
+               bch2_btree_iter_advance_pos(iter);
                bch2_trans_cond_resched(&trans);
        }
 fsck_err:
+       bch2_trans_iter_put(&trans, iter);
        bch2_trans_exit(&trans);
 
        if (ret2)
@@ -1487,11 +1485,12 @@ int bch2_fsck_walk_inodes_only(struct bch_fs *c)
                     BCH_INODE_I_SECTORS_DIRTY|
                     BCH_INODE_UNLINKED)) {
                        ret = check_inode(&trans, NULL, iter, inode, NULL);
-                       BUG_ON(ret == -EINTR);
                        if (ret)
                                break;
                }
        }
+       bch2_trans_iter_put(&trans, iter);
+
        BUG_ON(ret == -EINTR);
 
        return bch2_trans_exit(&trans) ?: ret;
index e72c49e18f13afc749279941f8a75616857f5c66..c9b31afc7c97d71e3c0daec218a337b9d7346a71 100644 (file)
@@ -620,6 +620,7 @@ retry:
 
        ret = bch2_trans_commit(&trans, NULL, NULL,
                                BTREE_INSERT_NOFAIL);
+       bch2_trans_iter_put(&trans, iter);
 err:
        if (ret == -EINTR)
                goto retry;
index 4fcc2c71377b469a3967288629bc21c55b9d1c7e..2a660574d47f231898174afd9476466dae98f701 100644 (file)
@@ -404,6 +404,8 @@ int bch2_fpunch(struct bch_fs *c, u64 inum, u64 start, u64 end,
 
        ret = bch2_fpunch_at(&trans, iter, POS(inum, end),
                             journal_seq, i_sectors_delta);
+
+       bch2_trans_iter_put(&trans, iter);
        bch2_trans_exit(&trans);
 
        if (ret == -EINTR)
@@ -450,6 +452,7 @@ int bch2_write_index_default(struct bch_write_op *op)
                        bch2_keylist_pop_front(keys);
        } while (!bch2_keylist_empty(keys));
 
+       bch2_trans_iter_put(&trans, iter);
        bch2_trans_exit(&trans);
        bch2_bkey_buf_exit(&sk, c);
 
@@ -1667,6 +1670,7 @@ retry:
                goto err;
 out:
        bch2_rbio_done(rbio);
+       bch2_trans_iter_put(&trans, iter);
        bch2_trans_exit(&trans);
        bch2_bkey_buf_exit(&sk, c);
        return;
@@ -2260,7 +2264,7 @@ retry:
                k = bch2_btree_iter_peek_slot(iter);
                ret = bkey_err(k);
                if (ret)
-                       goto err;
+                       break;
 
                offset_into_extent = iter->pos.offset -
                        bkey_start_offset(k.k);
@@ -2271,7 +2275,7 @@ retry:
                ret = bch2_read_indirect_extent(&trans, &data_btree,
                                        &offset_into_extent, &sk);
                if (ret)
-                       goto err;
+                       break;
 
                k = bkey_i_to_s_c(sk.k);
 
@@ -2296,12 +2300,8 @@ retry:
                ret = __bch2_read_extent(&trans, rbio, bvec_iter, iter->pos,
                                         data_btree, k,
                                         offset_into_extent, failed, flags);
-               switch (ret) {
-               case READ_RETRY:
-                       goto retry;
-               case READ_ERR:
-                       goto err;
-               };
+               if (ret)
+                       break;
 
                if (flags & BCH_READ_LAST_FRAGMENT)
                        break;
@@ -2309,19 +2309,19 @@ retry:
                swap(bvec_iter.bi_size, bytes);
                bio_advance_iter(&rbio->bio, &bvec_iter, bytes);
        }
-out:
-       bch2_trans_exit(&trans);
-       bch2_bkey_buf_exit(&sk, c);
-       return;
-err:
-       if (ret == -EINTR)
+       bch2_trans_iter_put(&trans, iter);
+
+       if (ret == -EINTR || ret == READ_RETRY || ret == READ_RETRY_AVOID)
                goto retry;
 
-       bch_err_inum_ratelimited(c, inode,
-                                "read error %i from btree lookup", ret);
-       rbio->bio.bi_status = BLK_STS_IOERR;
-       bch2_rbio_done(rbio);
-       goto out;
+       if (ret) {
+               bch_err_inum_ratelimited(c, inode,
+                                        "read error %i from btree lookup", ret);
+               rbio->bio.bi_status = BLK_STS_IOERR;
+               bch2_rbio_done(rbio);
+       }
+       bch2_trans_exit(&trans);
+       bch2_bkey_buf_exit(&sk, c);
 }
 
 void bch2_fs_io_exit(struct bch_fs *c)
index 395021b5ac8e9e4c0e103415c1e858c1a4769931..1f26139d9a1b8d463115027e7f5972e8a09f174a 100644 (file)
@@ -1234,6 +1234,9 @@ void __bch2_journal_debug_to_text(struct printbuf *out, struct journal *j)
                                   &c->rw_devs[BCH_DATA_journal]) {
                struct journal_device *ja = &ca->journal;
 
+               if (!test_bit(ca->dev_idx, c->rw_devs[BCH_DATA_journal].d))
+                       continue;
+
                if (!ja->nr)
                        continue;
 
index 253a27c52724589f2a7c5315e9ed8895347dc18c..5389745000da0db6830aa7fb4e0389510f032249 100644 (file)
@@ -196,6 +196,7 @@ nomatch:
                goto next;
        }
 out:
+       bch2_trans_iter_put(&trans, iter);
        bch2_trans_exit(&trans);
        bch2_bkey_buf_exit(&_insert, c);
        bch2_bkey_buf_exit(&_new, c);
@@ -642,6 +643,8 @@ next_nondata:
                bch2_trans_cond_resched(&trans);
        }
 out:
+
+       bch2_trans_iter_put(&trans, iter);
        ret = bch2_trans_exit(&trans) ?: ret;
        bch2_bkey_buf_exit(&sk, c);
 
@@ -728,7 +731,7 @@ static int bch2_move_btree(struct bch_fs *c,
                for_each_btree_node(&trans, iter, id,
                                    id == start_btree_id ? start_pos : POS_MIN,
                                    BTREE_ITER_PREFETCH, b) {
-                       if (kthread && (ret = kthread_should_stop()))
+                       if (kthread && kthread_should_stop())
                                goto out;
 
                        if ((cmp_int(id, end_btree_id) ?:
@@ -837,13 +840,15 @@ static enum data_cmd rewrite_old_nodes_pred(struct bch_fs *c, void *arg,
                                            struct bch_io_opts *io_opts,
                                            struct data_opts *data_opts)
 {
-       if (!btree_node_need_rewrite(b))
-               return DATA_SKIP;
+       if (b->version_ondisk != c->sb.version ||
+           btree_node_need_rewrite(b)) {
+               data_opts->target               = 0;
+               data_opts->nr_replicas          = 1;
+               data_opts->btree_insert_flags   = 0;
+               return DATA_REWRITE;
+       }
 
-       data_opts->target               = 0;
-       data_opts->nr_replicas          = 1;
-       data_opts->btree_insert_flags   = 0;
-       return DATA_REWRITE;
+       return DATA_SKIP;
 }
 
 int bch2_data_job(struct bch_fs *c,
@@ -895,11 +900,17 @@ int bch2_data_job(struct bch_fs *c,
                ret = bch2_replicas_gc2(c) ?: ret;
                break;
        case BCH_DATA_OP_REWRITE_OLD_NODES:
-
                ret = bch2_move_btree(c,
                                      op.start_btree,   op.start_pos,
                                      op.end_btree,     op.end_pos,
                                      rewrite_old_nodes_pred, &op, stats) ?: ret;
+
+               if (!ret) {
+                       mutex_lock(&c->sb_lock);
+                       c->disk_sb.sb->version_min = c->disk_sb.sb->version;
+                       bch2_write_super(c);
+                       mutex_unlock(&c->sb_lock);
+               }
                break;
        default:
                ret = -EINVAL;
index 0975cf3338af100afc9dfe0143cb2a4a0a0981b4..f8efeb36420618ed8c5ac8f101416fbca09db9c3 100644 (file)
@@ -990,11 +990,17 @@ int bch2_fs_recovery(struct bch_fs *c)
                goto err;
        }
 
+       if (!c->sb.clean &&
+           !(c->sb.features & (1ULL << BCH_FEATURE_extents_above_btree_updates))) {
+               bch_err(c, "filesystem needs recovery from older version; run fsck from older bcachefs-tools to fix");
+               ret = -EINVAL;
+               goto err;
+       }
+
        if (!(c->sb.features & (1ULL << BCH_FEATURE_alloc_v2))) {
                bch_info(c, "alloc_v2 feature bit not set, fsck required");
                c->opts.fsck = true;
                c->opts.fix_errors = FSCK_OPT_YES;
-               c->disk_sb.sb->features[0] |= 1ULL << BCH_FEATURE_alloc_v2;
        }
 
        if (!c->replicas.entries ||
@@ -1060,13 +1066,6 @@ use_clean:
                blacklist_seq = journal_seq = le64_to_cpu(clean->journal_seq) + 1;
        }
 
-       if (!c->sb.clean &&
-           !(c->sb.features & (1ULL << BCH_FEATURE_extents_above_btree_updates))) {
-               bch_err(c, "filesystem needs recovery from older version; run fsck from older bcachefs-tools to fix");
-               ret = -EINVAL;
-               goto err;
-       }
-
        if (c->opts.reconstruct_alloc) {
                c->sb.compat &= ~(1ULL << BCH_COMPAT_FEAT_ALLOC_INFO);
                drop_alloc_keys(&c->journal_keys);
@@ -1209,15 +1208,6 @@ use_clean:
        }
 
        mutex_lock(&c->sb_lock);
-       if (c->opts.version_upgrade) {
-               if (c->sb.version < bcachefs_metadata_version_new_versioning)
-                       c->disk_sb.sb->version_min =
-                               le16_to_cpu(bcachefs_metadata_version_min);
-               c->disk_sb.sb->version = le16_to_cpu(bcachefs_metadata_version_current);
-               c->disk_sb.sb->features[0] |= BCH_SB_FEATURES_ALL;
-               write_sb = true;
-       }
-
        if (!test_bit(BCH_FS_ERROR, &c->flags)) {
                c->disk_sb.sb->compat[0] |= 1ULL << BCH_COMPAT_FEAT_ALLOC_INFO;
                write_sb = true;
@@ -1274,15 +1264,6 @@ int bch2_fs_initialize(struct bch_fs *c)
                bch2_mark_dev_superblock(c, ca, 0);
        mutex_unlock(&c->sb_lock);
 
-       mutex_lock(&c->sb_lock);
-       c->disk_sb.sb->version = c->disk_sb.sb->version_min =
-               le16_to_cpu(bcachefs_metadata_version_current);
-       c->disk_sb.sb->features[0] |= 1ULL << BCH_FEATURE_atomic_nlink;
-       c->disk_sb.sb->features[0] |= BCH_SB_FEATURES_ALL;
-
-       bch2_write_super(c);
-       mutex_unlock(&c->sb_lock);
-
        set_bit(BCH_FS_ALLOC_READ_DONE, &c->flags);
        set_bit(BCH_FS_INITIAL_GC_DONE, &c->flags);
 
index e9a6a5f639b4a8d0dd47d8ca59c691a2298e3b4f..0978ad92614c649d61b3ed40cf0f89cb772f740c 100644 (file)
@@ -223,20 +223,18 @@ s64 bch2_remap_range(struct bch_fs *c,
        dst_iter = bch2_trans_get_iter(&trans, BTREE_ID_extents, dst_start,
                                       BTREE_ITER_INTENT);
 
-       while (1) {
+       while (ret == 0 || ret == -EINTR) {
                bch2_trans_begin(&trans);
 
-               trans.mem_top = 0;
-
                if (fatal_signal_pending(current)) {
                        ret = -EINTR;
-                       goto err;
+                       break;
                }
 
                src_k = get_next_src(src_iter, src_end);
                ret = bkey_err(src_k);
                if (ret)
-                       goto btree_err;
+                       continue;
 
                src_done = bpos_min(src_iter->pos, src_end).offset -
                        src_start.offset;
@@ -245,8 +243,6 @@ s64 bch2_remap_range(struct bch_fs *c,
                if (bkey_cmp(dst_iter->pos, dst_want) < 0) {
                        ret = bch2_fpunch_at(&trans, dst_iter, dst_want,
                                             journal_seq, i_sectors_delta);
-                       if (ret)
-                               goto btree_err;
                        continue;
                }
 
@@ -265,7 +261,7 @@ s64 bch2_remap_range(struct bch_fs *c,
                        ret = bch2_make_extent_indirect(&trans, src_iter,
                                                new_src.k);
                        if (ret)
-                               goto btree_err;
+                               continue;
 
                        BUG_ON(src_k.k->type != KEY_TYPE_reflink_p);
                }
@@ -294,20 +290,16 @@ s64 bch2_remap_range(struct bch_fs *c,
                                         NULL, journal_seq,
                                         new_i_size, i_sectors_delta);
                if (ret)
-                       goto btree_err;
+                       continue;
 
                dst_done = dst_iter->pos.offset - dst_start.offset;
                src_want = POS(src_start.inode, src_start.offset + dst_done);
                bch2_btree_iter_set_pos(src_iter, src_want);
-btree_err:
-               if (ret == -EINTR)
-                       ret = 0;
-               if (ret)
-                       goto err;
        }
+       bch2_trans_iter_put(&trans, dst_iter);
+       bch2_trans_iter_put(&trans, src_iter);
 
-       BUG_ON(bkey_cmp(dst_iter->pos, dst_end));
-err:
+       BUG_ON(!ret && bkey_cmp(dst_iter->pos, dst_end));
        BUG_ON(bkey_cmp(dst_iter->pos, dst_end) > 0);
 
        dst_done = dst_iter->pos.offset - dst_start.offset;
@@ -329,6 +321,8 @@ err:
                        ret2  = bch2_inode_write(&trans, inode_iter, &inode_u) ?:
                                bch2_trans_commit(&trans, NULL, journal_seq, 0);
                }
+
+               bch2_trans_iter_put(&trans, inode_iter);
        } while (ret2 == -EINTR);
 
        ret = bch2_trans_exit(&trans) ?: ret;
index b9ad9c4dc77e156776757d32c44e623fd6ffff5b..b4eb51af08d8c459c43c0ca5117027f195809c85 100644 (file)
@@ -362,6 +362,7 @@ static void bch2_sb_update(struct bch_fs *c)
        c->sb.uuid              = src->uuid;
        c->sb.user_uuid         = src->user_uuid;
        c->sb.version           = le16_to_cpu(src->version);
+       c->sb.version_min       = le16_to_cpu(src->version_min);
        c->sb.nr_devices        = src->nr_devices;
        c->sb.clean             = BCH_SB_CLEAN(src);
        c->sb.encryption_type   = BCH_SB_ENCRYPTION_TYPE(src);
@@ -964,6 +965,11 @@ int bch2_fs_mark_dirty(struct bch_fs *c)
         */
 
        mutex_lock(&c->sb_lock);
+       if (c->opts.version_upgrade) {
+               c->disk_sb.sb->version = le16_to_cpu(bcachefs_metadata_version_current);
+               c->disk_sb.sb->features[0] |= BCH_SB_FEATURES_ALL;
+       }
+
        SET_BCH_SB_CLEAN(c->disk_sb.sb, false);
        c->disk_sb.sb->features[0] |= BCH_SB_FEATURES_ALWAYS;
        ret = bch2_write_super(c);
index 2096c76ed81d39de8f8e1461dfbe891d6bd1834a..4eaa4cee82c5601329230764d950855d7443f576 100644 (file)
@@ -396,6 +396,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;
index 6bb5565cca478ef8cd47f0b71a73c6417e5fa3fb..858aa87660533ef1498e73b3ff27b290c3e21646 100644 (file)
@@ -133,12 +133,9 @@ int bch2_xattr_get(struct bch_fs *c, struct bch_inode_info *inode,
                                inode->v.i_ino,
                                &X_SEARCH(type, name, strlen(name)),
                                0);
-       if (IS_ERR(iter)) {
-               bch2_trans_exit(&trans);
-               BUG_ON(PTR_ERR(iter) == -EINTR);
-
-               return PTR_ERR(iter) == -ENOENT ? -ENODATA : PTR_ERR(iter);
-       }
+       ret = PTR_ERR_OR_ZERO(iter);
+       if (ret)
+               goto err;
 
        xattr = bkey_s_c_to_xattr(bch2_btree_iter_peek_slot(iter));
        ret = le16_to_cpu(xattr.v->x_val_len);
@@ -148,9 +145,12 @@ int bch2_xattr_get(struct bch_fs *c, struct bch_inode_info *inode,
                else
                        memcpy(buffer, xattr_val(xattr.v), ret);
        }
-
+       bch2_trans_iter_put(&trans, iter);
+err:
        bch2_trans_exit(&trans);
-       return ret;
+
+       BUG_ON(ret == -EINTR);
+       return ret == -ENOENT ? -ENODATA : ret;
 }
 
 int bch2_xattr_set(struct btree_trans *trans, u64 inum,
@@ -294,6 +294,8 @@ ssize_t bch2_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
                if (ret)
                        break;
        }
+       bch2_trans_iter_put(&trans, iter);
+
        ret = bch2_trans_exit(&trans) ?: ret;
 
        if (ret)