diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-11-13 07:52:33 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-11-13 08:08:19 -0500 |
commit | 441a9d0e1e827e6433e3487145fbb0c5513301e2 (patch) | |
tree | 853602df86aeb2b95d955e40edddce774aed52b0 | |
parent | ede4cebce16f5643c61aedd6d88d9070a1d23a68 (diff) | |
download | linux-441a9d0e1e827e6433e3487145fbb0c5513301e2.tar.bz2 |
qib_fs: fix (some) dcache abuses
* lookup_one_len() really wants i_mutex held on directory.
* leaks galore - just mount ipathfs, then
cd /sys/bus/pci/drivers/qib_ib; echo *:*:*.* >unbind
on a box with that card present and try to umount ipathfs...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | drivers/infiniband/hw/qib/qib_fs.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c index f247fc6e6182..c61e2a92b3c1 100644 --- a/drivers/infiniband/hw/qib/qib_fs.c +++ b/drivers/infiniband/hw/qib/qib_fs.c @@ -456,13 +456,13 @@ static int remove_file(struct dentry *parent, char *name) spin_lock(&tmp->d_lock); if (!(d_unhashed(tmp) && tmp->d_inode)) { - dget_dlock(tmp); __d_drop(tmp); spin_unlock(&tmp->d_lock); simple_unlink(parent->d_inode, tmp); } else { spin_unlock(&tmp->d_lock); } + dput(tmp); ret = 0; bail: @@ -491,6 +491,7 @@ static int remove_device_files(struct super_block *sb, goto bail; } + mutex_lock(&dir->d_inode->i_mutex); remove_file(dir, "counters"); remove_file(dir, "counter_names"); remove_file(dir, "portcounter_names"); @@ -505,8 +506,10 @@ static int remove_device_files(struct super_block *sb, } } remove_file(dir, "flash"); - d_delete(dir); + mutex_unlock(&dir->d_inode->i_mutex); ret = simple_rmdir(root->d_inode, dir); + d_delete(dir); + dput(dir); bail: mutex_unlock(&root->d_inode->i_mutex); |