From: Omar Sandoval <osandov@osandov.com> To: linux-fsdevel@vger.kernel.org, Al Viro <viro@zeniv.linux.org.uk> Cc: kernel-team@fb.com Subject: [RFC PATCH v4 3/4] Btrfs: fix inode reference count leak in btrfs_link() error path Date: Tue, 28 Jan 2020 15:19:02 -0800 [thread overview] Message-ID: <885829e37b0cdf75e26f4605e34110a7b23fe162.1580251857.git.osandov@fb.com> (raw) In-Reply-To: <cover.1580251857.git.osandov@fb.com> From: Omar Sandoval <osandov@fb.com> If btrfs_update_inode() or btrfs_orphan_del() fails in btrfs_link(), then we don't drop the reference we got with ihold(). This results in the "VFS: Busy inodes after unmount" crash. The reference is needed for the new dentry, so get it right before we instantiate the dentry. Fixes: 79787eaab461 ("btrfs: replace many BUG_ONs with proper error handling") [Although d_instantiate() was moved further from ihold() before that, in commit 08c422c27f85 ("Btrfs: call d_instantiate after all ops are setup")] Signed-off-by: Omar Sandoval <osandov@fb.com> --- fs/btrfs/inode.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index bc7709c4f6eb..8c9a114f48f6 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6801,7 +6801,6 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, inc_nlink(inode); inode_inc_iversion(inode); inode->i_ctime = current_time(inode); - ihold(inode); set_bit(BTRFS_INODE_COPY_EVERYTHING, &BTRFS_I(inode)->runtime_flags); err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode), @@ -6825,6 +6824,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, if (err) goto fail; } + ihold(inode); d_instantiate(dentry, inode); ret = btrfs_log_new_name(trans, BTRFS_I(inode), NULL, parent, true, NULL); @@ -6837,10 +6837,8 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, fail: if (trans) btrfs_end_transaction(trans); - if (drop_inode) { + if (drop_inode) inode_dec_link_count(inode); - iput(inode); - } btrfs_btree_balance_dirty(fs_info); return err; } -- 2.25.0
WARNING: multiple messages have this Message-ID (diff)
From: Omar Sandoval <osandov@osandov.com> To: linux-fsdevel@vger.kernel.org, Al Viro <viro@zeniv.linux.org.uk> Cc: kernel-team@fb.com, linux-api@vger.kernel.org, David Howells <dhowells@redhat.com>, Amir Goldstein <amir73il@gmail.com>, Xi Wang <xi@cs.washington.edu> Subject: [RFC PATCH v4 3/4] Btrfs: fix inode reference count leak in btrfs_link() error path Date: Wed, 29 Jan 2020 00:58:33 -0800 [thread overview] Message-ID: <885829e37b0cdf75e26f4605e34110a7b23fe162.1580251857.git.osandov@fb.com> (raw) Message-ID: <20200129085833.S2QQvJ-b5mRjBwIoL7FF7WG1gPztAMIk3BTKADrg9fA@z> (raw) In-Reply-To: <cover.1580251857.git.osandov@fb.com> From: Omar Sandoval <osandov@fb.com> If btrfs_update_inode() or btrfs_orphan_del() fails in btrfs_link(), then we don't drop the reference we got with ihold(). This results in the "VFS: Busy inodes after unmount" crash. The reference is needed for the new dentry, so get it right before we instantiate the dentry. Fixes: 79787eaab461 ("btrfs: replace many BUG_ONs with proper error handling") [Although d_instantiate() was moved further from ihold() before that, in commit 08c422c27f85 ("Btrfs: call d_instantiate after all ops are setup")] Signed-off-by: Omar Sandoval <osandov@fb.com> --- fs/btrfs/inode.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index bc7709c4f6eb..8c9a114f48f6 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6801,7 +6801,6 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, inc_nlink(inode); inode_inc_iversion(inode); inode->i_ctime = current_time(inode); - ihold(inode); set_bit(BTRFS_INODE_COPY_EVERYTHING, &BTRFS_I(inode)->runtime_flags); err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode), @@ -6825,6 +6824,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, if (err) goto fail; } + ihold(inode); d_instantiate(dentry, inode); ret = btrfs_log_new_name(trans, BTRFS_I(inode), NULL, parent, true, NULL); @@ -6837,10 +6837,8 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, fail: if (trans) btrfs_end_transaction(trans); - if (drop_inode) { + if (drop_inode) inode_dec_link_count(inode); - iput(inode); - } btrfs_btree_balance_dirty(fs_info); return err; } -- 2.25.0
next prev parent reply other threads:[~2020-01-28 23:19 UTC|newest] Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-01-28 23:18 [RFC PATCH v4 0/4] fs: add flag to linkat() for replacing destination Omar Sandoval 2020-01-29 8:58 ` Omar Sandoval 2020-01-28 23:18 ` [RFC PATCH xfstests] generic: add smoke test for AT_LINK_REPLACE Omar Sandoval 2020-01-29 8:58 ` Omar Sandoval 2020-01-29 7:02 ` Zorro Lang 2020-02-23 14:46 ` Eryu Guan 2020-01-28 23:18 ` [RFC PATCH man-pages] link.2: Document new AT_LINK_REPLACE flag Omar Sandoval 2020-01-29 8:58 ` Omar Sandoval 2020-01-28 23:18 ` [RFC PATCH xfsprogs] xfs_io: add support for linkat() AT_LINK_REPLACE Omar Sandoval 2020-01-29 8:58 ` Omar Sandoval 2020-01-30 4:42 ` Zorro Lang 2020-01-28 23:19 ` [RFC PATCH v4 1/4] fs: add flags argument to i_op->link() Omar Sandoval 2020-01-29 8:58 ` Omar Sandoval 2020-01-28 23:19 ` [RFC PATCH v4 2/4] fs: add AT_LINK_REPLACE flag for linkat() which replaces the target Omar Sandoval 2020-01-29 8:58 ` Omar Sandoval 2020-01-28 23:19 ` Omar Sandoval [this message] 2020-01-29 8:58 ` [RFC PATCH v4 3/4] Btrfs: fix inode reference count leak in btrfs_link() error path Omar Sandoval 2020-01-28 23:19 ` [RFC PATCH v4 4/4] Btrfs: add support for linkat() AT_REPLACE Omar Sandoval 2020-01-29 8:58 ` Omar Sandoval 2020-01-29 8:58 ` [RFC PATCH xfstests] generic: add smoke test for AT_LINK_REPLACE Omar Sandoval [not found] ` <cover.1580251857.git.osandov-b10kYP2dOMg@public.gmane.org> 2020-01-29 8:58 ` Omar Sandoval 2020-01-29 8:58 ` [RFC PATCH man-pages] link.2: Document new AT_LINK_REPLACE flag Omar Sandoval 2020-01-29 8:58 ` [RFC PATCH xfsprogs] xfs_io: add support for linkat() AT_LINK_REPLACE Omar Sandoval 2020-01-29 8:58 ` [RFC PATCH v4 0/4] fs: add flag to linkat() for replacing destination Omar Sandoval 2020-01-29 8:58 ` [RFC PATCH v4 1/4] fs: add flags argument to i_op->link() Omar Sandoval 2020-01-29 8:58 ` [RFC PATCH v4 2/4] fs: add AT_LINK_REPLACE flag for linkat() which replaces the target Omar Sandoval 2020-01-29 8:58 ` [RFC PATCH v4 3/4] Btrfs: fix inode reference count leak in btrfs_link() error path Omar Sandoval 2020-01-29 8:58 ` [RFC PATCH v4 4/4] Btrfs: add support for linkat() AT_REPLACE Omar Sandoval 2020-01-31 13:48 ` [RFC PATCH v4 1/4] fs: add flags argument to i_op->link() David Howells 2020-01-31 20:24 ` Omar Sandoval 2020-01-31 20:24 ` Omar Sandoval
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=885829e37b0cdf75e26f4605e34110a7b23fe162.1580251857.git.osandov@fb.com \ --to=osandov@osandov.com \ --cc=kernel-team@fb.com \ --cc=linux-fsdevel@vger.kernel.org \ --cc=viro@zeniv.linux.org.uk \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.