qib_fs: fix (some) dcache abuses
authorAl Viro <viro@zeniv.linux.org.uk>
Wed, 13 Nov 2013 12:52:33 +0000 (07:52 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Wed, 13 Nov 2013 13:08:19 +0000 (08:08 -0500)
* 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>
drivers/infiniband/hw/qib/qib_fs.c

index f247fc6e61826db010b2ac6c267e5fe1ee3ae09b..c61e2a92b3c115b4ab0b6c3ceb3f52d0d49a10ea 100644 (file)
@@ -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);