Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull VFS fixes from Al Viro:
 "Several fixes, mostly for regressions in the last pile.  Howeover,
  prepend_path() forgetting to reininitalize dentry/vfsmount is in 3.12
  as well and qib_fs had been leaking all along..."

The unpaired RCU lock issue was also independently reported by Dave
Jones with his fuzzer tool..

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  qib_fs: fix (some) dcache abuses
  prepend_path() needs to reinitialize dentry/vfsmount/mnt on restarts
  fix unpaired rcu lock in prepend_path()
  locks: missing unlock on error in generic_add_lease()
  aio: checking for NULL instead of IS_ERR
diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c
index f247fc6e..c61e2a9 100644
--- a/drivers/infiniband/hw/qib/qib_fs.c
+++ b/drivers/infiniband/hw/qib/qib_fs.c
@@ -456,13 +456,13 @@
 
 	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 @@
 		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 @@
 		}
 	}
 	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 1f602d9..823efcb 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -163,8 +163,8 @@
 	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 1f24cd6..a9dd384 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2912,9 +2912,9 @@
 			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 @@
 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 @@
 		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 f99d52b..92a0f0a 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1494,6 +1494,7 @@
 
 	if (is_deleg && arg == F_WRLCK) {
 		/* Write delegations are not currently supported: */
+		mutex_unlock(&inode->i_mutex);
 		WARN_ON_ONCE(1);
 		return -EINVAL;
 	}