aboutsummaryrefslogtreecommitdiff
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-07-18 07:53:27 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-07-18 07:53:27 +0000
commit2684a6c505531426bb7d4c8a68aab91abe6af05c (patch)
tree1636806f0c5f37c506bf5b38aa7ee3e7c4c48644 /fs/nfs/dir.c
parent39b9a227eb927f4a8963f60d763bd43fa5b2bb5b (diff)
parentcc3d2b7361cf10851f579da257fdf2f1a7bd66b4 (diff)
downloadv4.4-2684a6c505531426bb7d4c8a68aab91abe6af05c.tar.gz
release-request-b8734135-c578-454d-bc9f-628062b9de89-for-git_nyc-iot-release-4188548 snap-temp-L42600000083191324
Change-Id: If12f2ca34c92ce87169ba986b5b24a1b6b377a3d
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 5fc2162afb67..5b21b1ca2341 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -462,7 +462,7 @@ void nfs_force_use_readdirplus(struct inode *dir)
{
if (!list_empty(&NFS_I(dir)->open_files)) {
nfs_advise_use_readdirplus(dir);
- nfs_zap_mapping(dir, dir->i_mapping);
+ invalidate_mapping_pages(dir->i_mapping, 0, -1);
}
}
@@ -847,17 +847,6 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc)
goto out;
}
-static bool nfs_dir_mapping_need_revalidate(struct inode *dir)
-{
- struct nfs_inode *nfsi = NFS_I(dir);
-
- if (nfs_attribute_cache_expired(dir))
- return true;
- if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
- return true;
- return false;
-}
-
/* The file offset position represents the dirent entry number. A
last cookie cache takes care of the common case of reading the
whole directory.
@@ -890,7 +879,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
desc->plus = nfs_use_readdirplus(inode, ctx) ? 1 : 0;
nfs_block_sillyrename(dentry);
- if (ctx->pos == 0 || nfs_dir_mapping_need_revalidate(inode))
+ if (ctx->pos == 0 || nfs_attribute_cache_expired(inode))
res = nfs_revalidate_mapping(inode, file->f_mapping);
if (res < 0)
goto out;
@@ -1531,9 +1520,9 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
err = PTR_ERR(inode);
trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
put_nfs_open_context(ctx);
+ d_drop(dentry);
switch (err) {
case -ENOENT:
- d_drop(dentry);
d_add(dentry, NULL);
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
break;
@@ -2432,6 +2421,20 @@ int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags)
}
EXPORT_SYMBOL_GPL(nfs_may_open);
+static int nfs_execute_ok(struct inode *inode, int mask)
+{
+ struct nfs_server *server = NFS_SERVER(inode);
+ int ret;
+
+ if (mask & MAY_NOT_BLOCK)
+ ret = nfs_revalidate_inode_rcu(server, inode);
+ else
+ ret = nfs_revalidate_inode(server, inode);
+ if (ret == 0 && !execute_ok(inode))
+ ret = -EACCES;
+ return ret;
+}
+
int nfs_permission(struct inode *inode, int mask)
{
struct rpc_cred *cred;
@@ -2449,6 +2452,9 @@ int nfs_permission(struct inode *inode, int mask)
case S_IFLNK:
goto out;
case S_IFREG:
+ if ((mask & MAY_OPEN) &&
+ nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN))
+ return 0;
break;
case S_IFDIR:
/*
@@ -2481,8 +2487,8 @@ force_lookup:
res = PTR_ERR(cred);
}
out:
- if (!res && (mask & MAY_EXEC) && !execute_ok(inode))
- res = -EACCES;
+ if (!res && (mask & MAY_EXEC))
+ res = nfs_execute_ok(inode, mask);
dfprintk(VFS, "NFS: permission(%s/%lu), mask=0x%x, res=%d\n",
inode->i_sb->s_id, inode->i_ino, mask, res);