diff options
author | Niels de Vos <ndevos@redhat.com> | 2013-07-17 08:53:53 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-07-28 19:30:07 -0400 |
commit | 05ac7b3a7db7823aecde55df6a5f8d6bb45693f4 (patch) | |
tree | d141871c29e281efcca627976892f3210162b2fd /fs | |
parent | df18f5f93ce9ed27bd9a779196614afd7a0aa017 (diff) |
fuse: readdirplus: fix dentry leak
commit 53ce9a3364de0723b27d861de93bfc882f7db050 upstream.
In case d_lookup() returns a dentry with d_inode == NULL, the dentry is not
returned with dput(). This results in triggering a BUG() in
shrink_dcache_for_umount_subtree():
BUG: Dentry ...{i=0,n=...} still in use (1) [unmount of fuse fuse]
[SzM: need to d_drop() as well]
Reported-by: Justin Clift <jclift@redhat.com>
Signed-off-by: Niels de Vos <ndevos@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Tested-by: Brian Foster <bfoster@redhat.com>
Tested-by: Niels de Vos <ndevos@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/fuse/dir.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index f3f783dc4f75..5532bf416f9b 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -1229,9 +1229,15 @@ static int fuse_direntplus_link(struct file *file, | |||
1229 | 1229 | ||
1230 | name.hash = full_name_hash(name.name, name.len); | 1230 | name.hash = full_name_hash(name.name, name.len); |
1231 | dentry = d_lookup(parent, &name); | 1231 | dentry = d_lookup(parent, &name); |
1232 | if (dentry && dentry->d_inode) { | 1232 | if (dentry) { |
1233 | inode = dentry->d_inode; | 1233 | inode = dentry->d_inode; |
1234 | if (get_node_id(inode) == o->nodeid) { | 1234 | if (!inode) { |
1235 | d_drop(dentry); | ||
1236 | } else if (get_node_id(inode) != o->nodeid) { | ||
1237 | err = d_invalidate(dentry); | ||
1238 | if (err) | ||
1239 | goto out; | ||
1240 | } else { | ||
1235 | struct fuse_inode *fi; | 1241 | struct fuse_inode *fi; |
1236 | fi = get_fuse_inode(inode); | 1242 | fi = get_fuse_inode(inode); |
1237 | spin_lock(&fc->lock); | 1243 | spin_lock(&fc->lock); |
@@ -1244,9 +1250,6 @@ static int fuse_direntplus_link(struct file *file, | |||
1244 | */ | 1250 | */ |
1245 | goto found; | 1251 | goto found; |
1246 | } | 1252 | } |
1247 | err = d_invalidate(dentry); | ||
1248 | if (err) | ||
1249 | goto out; | ||
1250 | dput(dentry); | 1253 | dput(dentry); |
1251 | dentry = NULL; | 1254 | dentry = NULL; |
1252 | } | 1255 | } |