]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bcachefs: Fix inode early destruction path
authorKent Overstreet <kent.overstreet@linux.dev>
Sun, 21 Apr 2024 02:26:47 +0000 (22:26 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 21 Apr 2024 03:00:59 +0000 (23:00 -0400)
discard_new_inode() is the wrong interface to use when we need to free
an inode that was never inserted into the inode hash table; we can
bypass the whole iput() -> evict() path and replace it with
__destroy_inode(); kmem_cache_free() - this fixes a WARN_ON() about
I_NEW.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/fs.c

index b5ea9fa1259d1462e9033318466fc914911672ce..fce690007edfce089f054d81cc862c04c132c2b3 100644 (file)
@@ -188,7 +188,8 @@ static struct bch_inode_info *bch2_inode_insert(struct bch_fs *c, struct bch_ino
        BUG_ON(!old);
 
        if (unlikely(old != inode)) {
-               discard_new_inode(&inode->v);
+               __destroy_inode(&inode->v);
+               kmem_cache_free(bch2_inode_cache, inode);
                inode = old;
        } else {
                mutex_lock(&c->vfs_inodes_lock);
@@ -225,8 +226,10 @@ static struct bch_inode_info *bch2_new_inode(struct btree_trans *trans)
 
        if (unlikely(!inode)) {
                int ret = drop_locks_do(trans, (inode = to_bch_ei(new_inode(c->vfs_sb))) ? 0 : -ENOMEM);
-               if (ret && inode)
-                       discard_new_inode(&inode->v);
+               if (ret && inode) {
+                       __destroy_inode(&inode->v);
+                       kmem_cache_free(bch2_inode_cache, inode);
+               }
                if (ret)
                        return ERR_PTR(ret);
        }