summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/qib/qib_fs.c7
-rw-r--r--fs/aio.c4
-rw-r--r--fs/dcache.c13
-rw-r--r--fs/locks.c1
4 files changed, 18 insertions, 7 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);
diff --git a/fs/aio.c b/fs/aio.c
index 1f602d9be4c5..823efcbb6ccd 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -163,8 +163,8 @@ static struct file *aio_private_file(struct kioctx *ctx, loff_t nr_pages)
struct file *file;
struct path path;
struct inode *inode = alloc_anon_inode(aio_mnt->mnt_sb);
- if (!inode)
- return ERR_PTR(-ENOMEM);
+ if (IS_ERR(inode))
+ return ERR_CAST(inode);
inode->i_mapping->a_ops = &aio_ctx_aops;
inode->i_mapping->private_data = ctx;
diff --git a/fs/dcache.c b/fs/dcache.c
index 1f24cd684c51..a9dd384c5e80 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2912,9 +2912,9 @@ static int prepend_path(const struct path *path,
const struct path *root,
char **buffer, int *buflen)
{
- struct dentry *dentry = path->dentry;
- struct vfsmount *vfsmnt = path->mnt;
- struct mount *mnt = real_mount(vfsmnt);
+ struct dentry *dentry;
+ struct vfsmount *vfsmnt;
+ struct mount *mnt;
int error = 0;
unsigned seq, m_seq = 0;
char *bptr;
@@ -2924,10 +2924,14 @@ static int prepend_path(const struct path *path,
restart_mnt:
read_seqbegin_or_lock(&mount_lock, &m_seq);
seq = 0;
+ rcu_read_lock();
restart:
bptr = *buffer;
blen = *buflen;
error = 0;
+ dentry = path->dentry;
+ vfsmnt = path->mnt;
+ mnt = real_mount(vfsmnt);
read_seqbegin_or_lock(&rename_lock, &seq);
while (dentry != root->dentry || vfsmnt != root->mnt) {
struct dentry * parent;
@@ -2971,6 +2975,9 @@ restart:
goto restart;
}
done_seqretry(&rename_lock, seq);
+
+ if (!(m_seq & 1))
+ rcu_read_unlock();
if (need_seqretry(&mount_lock, m_seq)) {
m_seq = 1;
goto restart_mnt;
diff --git a/fs/locks.c b/fs/locks.c
index f99d52bdd05a..92a0f0a52b06 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1494,6 +1494,7 @@ static int generic_add_lease(struct file *filp, long arg, struct file_lock **flp
if (is_deleg && arg == F_WRLCK) {
/* Write delegations are not currently supported: */
+ mutex_unlock(&inode->i_mutex);
WARN_ON_ONCE(1);
return -EINVAL;
}