Skip to content

Commit d0118d7

Browse files
Tetsuo Handaakpm00
authored andcommitted
ocfs2: update d_splice_alias() return code checking
When commit d3556ba ("ocfs2: fix d_splice_alias() return code checking") was merged into v3.18-rc3, d_splice_alias() was returning one of a valid dentry, NULL or an ERR_PTR. When commit b5ae6b1 ("merge d_materialise_unique() into d_splice_alias()") was merged into v3.19-rc1, d_splice_alias() started returning -ELOOP as one of ERR_PTR values. Now, when syzkaller mounts a crafted ocfs2 filesystem image that hits d_splice_alias() == -ELOOP case from ocfs2_lookup(), ocfs2_lookup() fails to handle -ELOOP case and generic_shutdown_super() hits "VFS: Busy inodes after unmount" message. Instead of calling ocfs2_dentry_attach_lock() or ocfs2_dentry_attach_gen() when d_splice_alias() returned an ERR_PTR value, change ocfs2_lookup() to bail out immediately. Also, ocfs2_lookup() needs to call dupt() when ocfs2_dentry_attach_lock() returned an ERR_PTR value. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Tetsuo Handa <[email protected]> Reported-by: syzbot <[email protected]> Closes: https://syzkaller.appspot.com/bug?extid=1134d3a5b062e9665a7a Suggested-by: Al Viro <[email protected]> Reviewed-by: Joseph Qi <[email protected]> Cc: Al Viro <[email protected]> Cc: Joel Becker <[email protected]> Cc: Mark Fasheh <[email protected]> Cc: Richard Weinberger <[email protected]> Cc: Tetsuo Handa <[email protected]> Cc: Junxiao Bi <[email protected]> Cc: Changwei Ge <[email protected]> Cc: Jun Piao <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent ad0039d commit d0118d7

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

fs/ocfs2/namei.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry,
142142

143143
bail_add:
144144
ret = d_splice_alias(inode, dentry);
145+
if (IS_ERR(ret))
146+
goto bail_unlock;
145147

146148
if (inode) {
147149
/*
@@ -154,15 +156,16 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry,
154156
* NOTE: This dentry already has ->d_op set from
155157
* ocfs2_get_parent() and ocfs2_get_dentry()
156158
*/
157-
if (!IS_ERR_OR_NULL(ret))
159+
if (ret)
158160
dentry = ret;
159161

160162
status = ocfs2_dentry_attach_lock(dentry, inode,
161163
OCFS2_I(dir)->ip_blkno);
162164
if (status) {
163165
mlog_errno(status);
166+
if (ret)
167+
dput(ret);
164168
ret = ERR_PTR(status);
165-
goto bail_unlock;
166169
}
167170
} else
168171
ocfs2_dentry_attach_gen(dentry);

0 commit comments

Comments
 (0)