[PATCH] nfs: when attempting to open a directory, fall back on normal lookup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



commit d953126 changed how nfs_atomic_lookup handles an -EISDIR return
from an OPEN call. Prior to that patch, that caused the client to fall
back to doing a normal lookup. When that patch went in, the code began
returning that error to userspace. The d_revalidate codepath however
never had the corresponding change, so it was still possible to end up
with a NULL ctx->state pointer after that.

That patch caused a regression. When we attempt to open a directory that
does not have a cached dentry, that open now errors out with EISDIR. If
you attempt the same open with a cached dentry, it will succeed.

Fix this by reverting the change in nfs_atomic_lookup and allowing
attempts to open directories to fall back to a normal lookup. Also, have
the f_ops->open routine for NFS check to see if we're attempting to open
a regular file on NFSv4. If so, then something is very wrong since that
should have been handled by the lookup. Have it return an error
(ENOTDIR) to userspace in that case.

Cc: stable@xxxxxxxxxx
Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
---
 fs/nfs/dir.c   |    2 +-
 fs/nfs/inode.c |    8 ++++++++
 2 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index b238d95..ac28990 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1468,12 +1468,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
 				res = NULL;
 				goto out;
 			/* This turned out not to be a regular file */
+			case -EISDIR:
 			case -ENOTDIR:
 				goto no_open;
 			case -ELOOP:
 				if (!(nd->intent.open.flags & O_NOFOLLOW))
 					goto no_open;
-			/* case -EISDIR: */
 			/* case -EINVAL: */
 			default:
 				res = ERR_CAST(inode);
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index fe12037..44948a6 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -740,6 +740,14 @@ int nfs_open(struct inode *inode, struct file *filp)
 	struct nfs_open_context *ctx;
 	struct rpc_cred *cred;
 
+	/*
+	 * NFSv4 opens should be handled during the lookup. If we get to this
+	 * point on a NFSv4 open and this is a regular file, then something is
+	 * very wrong.
+	 */
+	if (S_ISREG(inode->i_mode) && NFS_PROTO(inode)->version == 4)
+		return -ENOTDIR;
+
 	cred = rpc_lookup_cred();
 	if (IS_ERR(cred))
 		return PTR_ERR(cred);
-- 
1.7.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux