diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2024-04-21 04:26:47 +0200 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2024-04-21 05:00:59 +0200 |
commit | 0e42f381193d7f9b47922f1c4308e7729a45ba13 (patch) | |
tree | b070eef0152f4d1eb60ab184900e5f4f4ebfd634 /fs | |
parent | bcachefs: Fix deadlock in journal write path (diff) | |
download | linux-0e42f381193d7f9b47922f1c4308e7729a45ba13.tar.xz linux-0e42f381193d7f9b47922f1c4308e7729a45ba13.zip |
bcachefs: Fix inode early destruction path
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/bcachefs/fs.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c index b5ea9fa1259d..fce690007edf 100644 --- a/fs/bcachefs/fs.c +++ b/fs/bcachefs/fs.c @@ -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); } |