From cda8fc9da96736bd67bdc9ad0a8a813f37570ced Mon Sep 17 00:00:00 2001
From: Al Viro <viro@zeniv.linux.org.uk>
Date: Fri, 30 Mar 2012 14:08:28 -0400
Subject: [PATCH] untangling do_lookup() - expand the area under ->i_mutex

keep holding ->i_mutex over revalidation parts

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/namei.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 157f3debbf988..48fc0fb8c9d17 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1173,6 +1173,7 @@ retry:
 		BUG_ON(nd->inode != dir);
 
 		mutex_lock(&dir->i_mutex);
+l:
 		dentry = d_lookup(parent, name);
 		if (likely(!dentry)) {
 			dentry = d_alloc_and_lookup(parent, name, nd);
@@ -1193,11 +1194,11 @@ retry:
 			need_reval = 0;
 			status = 1;
 		}
-		mutex_unlock(&dir->i_mutex);
 		if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE) && need_reval)
 			status = d_revalidate(dentry, nd);
 		if (unlikely(status <= 0)) {
 			if (status < 0) {
+				mutex_unlock(&dir->i_mutex);
 				dput(dentry);
 				return status;
 			}
@@ -1205,9 +1206,10 @@ retry:
 				dput(dentry);
 				dentry = NULL;
 				need_reval = 1;
-				goto retry;
+				goto l;
 			}
 		}
+		mutex_unlock(&dir->i_mutex);
 		goto done;
 	}
 	if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE) && need_reval)
-- 
2.39.5