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) | |
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) | |||
| 456 | 456 | ||
| 457 | spin_lock(&tmp->d_lock); | 457 | spin_lock(&tmp->d_lock); |
| 458 | if (!(d_unhashed(tmp) && tmp->d_inode)) { | 458 | if (!(d_unhashed(tmp) && tmp->d_inode)) { |
| 459 | dget_dlock(tmp); | ||
| 460 | __d_drop(tmp); | 459 | __d_drop(tmp); |
| 461 | spin_unlock(&tmp->d_lock); | 460 | spin_unlock(&tmp->d_lock); |
| 462 | simple_unlink(parent->d_inode, tmp); | 461 | simple_unlink(parent->d_inode, tmp); |
| 463 | } else { | 462 | } else { |
| 464 | spin_unlock(&tmp->d_lock); | 463 | spin_unlock(&tmp->d_lock); |
| 465 | } | 464 | } |
| 465 | dput(tmp); | ||
| 466 | 466 | ||
| 467 | ret = 0; | 467 | ret = 0; |
| 468 | bail: | 468 | bail: |
| @@ -491,6 +491,7 @@ static int remove_device_files(struct super_block *sb, | |||
| 491 | goto bail; | 491 | goto bail; |
| 492 | } | 492 | } |
| 493 | 493 | ||
| 494 | mutex_lock(&dir->d_inode->i_mutex); | ||
| 494 | remove_file(dir, "counters"); | 495 | remove_file(dir, "counters"); |
| 495 | remove_file(dir, "counter_names"); | 496 | remove_file(dir, "counter_names"); |
| 496 | remove_file(dir, "portcounter_names"); | 497 | remove_file(dir, "portcounter_names"); |
| @@ -505,8 +506,10 @@ static int remove_device_files(struct super_block *sb, | |||
| 505 | } | 506 | } |
| 506 | } | 507 | } |
| 507 | remove_file(dir, "flash"); | 508 | remove_file(dir, "flash"); |
| 508 | d_delete(dir); | 509 | mutex_unlock(&dir->d_inode->i_mutex); |
| 509 | ret = simple_rmdir(root->d_inode, dir); | 510 | ret = simple_rmdir(root->d_inode, dir); |
| 511 | d_delete(dir); | ||
| 512 | dput(dir); | ||
| 510 | 513 | ||
| 511 | bail: | 514 | bail: |
| 512 | mutex_unlock(&root->d_inode->i_mutex); | 515 | mutex_unlock(&root->d_inode->i_mutex); |
