aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/file.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2011-11-04 13:31:21 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-11-04 16:39:04 -0400
commit1788ea6e3b2a58cf4fb00206e362d9caff8d86a7 (patch)
tree24846fddf8b55f516f365a735defd79b6ea6d28a /fs/nfs/file.c
parent1583171492eb514e267c7b51e96846b38de0f544 (diff)
nfs: when attempting to open a directory, fall back on normal lookup (try #5)
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, add a NFSv4-specific f_ops->open routine that just returns -ENOTDIR. This should never be called if things are working properly, but if it ever is, then the dprintk may help in debugging. To facilitate this, a new file_operations field is also added to the nfs_rpc_ops struct. Cc: stable@kernel.org Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r--fs/nfs/file.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 0a1f8312b4dc..6d93e0754b5e 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -886,3 +886,35 @@ static int nfs_setlease(struct file *file, long arg, struct file_lock **fl)
886 file->f_path.dentry->d_name.name, arg); 886 file->f_path.dentry->d_name.name, arg);
887 return -EINVAL; 887 return -EINVAL;
888} 888}
889
890#ifdef CONFIG_NFS_V4
891static int
892nfs4_file_open(struct inode *inode, struct file *filp)
893{
894 /*
895 * NFSv4 opens are handled in d_lookup and d_revalidate. If we get to
896 * this point, then something is very wrong
897 */
898 dprintk("NFS: %s called! inode=%p filp=%p\n", __func__, inode, filp);
899 return -ENOTDIR;
900}
901
902const struct file_operations nfs4_file_operations = {
903 .llseek = nfs_file_llseek,
904 .read = do_sync_read,
905 .write = do_sync_write,
906 .aio_read = nfs_file_read,
907 .aio_write = nfs_file_write,
908 .mmap = nfs_file_mmap,
909 .open = nfs4_file_open,
910 .flush = nfs_file_flush,
911 .release = nfs_file_release,
912 .fsync = nfs_file_fsync,
913 .lock = nfs_lock,
914 .flock = nfs_flock,
915 .splice_read = nfs_file_splice_read,
916 .splice_write = nfs_file_splice_write,
917 .check_flags = nfs_check_flags,
918 .setlease = nfs_setlease,
919};
920#endif /* CONFIG_NFS_V4 */