diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-07-03 13:04:56 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-07-10 23:40:40 -0400 |
commit | 1b45c46cf75d9c48eb611d5cc41607ac1f046606 (patch) | |
tree | 866cbb5a15aec70a3da159da663f435475a2db4f /fs/nfs/nfs4proc.c | |
parent | 9f958ab8858c75df800e0121b1920182820cbc39 (diff) |
NFSv4: Fix atomic open for execute...
Currently we do not check for the FMODE_EXEC flag as we should. For that
particular case, we need to perform an ACCESS call to the server in order
to check that the file is executable.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 1840ebc78fd3..69aab8db4947 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -769,6 +769,8 @@ static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred, int openf | |||
769 | mask |= MAY_READ; | 769 | mask |= MAY_READ; |
770 | if (openflags & FMODE_WRITE) | 770 | if (openflags & FMODE_WRITE) |
771 | mask |= MAY_WRITE; | 771 | mask |= MAY_WRITE; |
772 | if (openflags & FMODE_EXEC) | ||
773 | mask |= MAY_EXEC; | ||
772 | status = nfs_access_get_cached(inode, cred, &cache); | 774 | status = nfs_access_get_cached(inode, cred, &cache); |
773 | if (status == 0) | 775 | if (status == 0) |
774 | goto out; | 776 | goto out; |
@@ -1269,7 +1271,16 @@ out: | |||
1269 | static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct nfs4_state *state) | 1271 | static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct nfs4_state *state) |
1270 | { | 1272 | { |
1271 | struct file *filp; | 1273 | struct file *filp; |
1274 | int ret; | ||
1272 | 1275 | ||
1276 | /* If the open_intent is for execute, we have an extra check to make */ | ||
1277 | if (nd->intent.open.flags & FMODE_EXEC) { | ||
1278 | ret = _nfs4_do_access(state->inode, | ||
1279 | state->owner->so_cred, | ||
1280 | nd->intent.open.flags); | ||
1281 | if (ret < 0) | ||
1282 | goto out_close; | ||
1283 | } | ||
1273 | filp = lookup_instantiate_filp(nd, path->dentry, NULL); | 1284 | filp = lookup_instantiate_filp(nd, path->dentry, NULL); |
1274 | if (!IS_ERR(filp)) { | 1285 | if (!IS_ERR(filp)) { |
1275 | struct nfs_open_context *ctx; | 1286 | struct nfs_open_context *ctx; |
@@ -1277,8 +1288,10 @@ static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct | |||
1277 | ctx->state = state; | 1288 | ctx->state = state; |
1278 | return 0; | 1289 | return 0; |
1279 | } | 1290 | } |
1291 | ret = PTR_ERR(filp); | ||
1292 | out_close: | ||
1280 | nfs4_close_state(path, state, nd->intent.open.flags); | 1293 | nfs4_close_state(path, state, nd->intent.open.flags); |
1281 | return PTR_ERR(filp); | 1294 | return ret; |
1282 | } | 1295 | } |
1283 | 1296 | ||
1284 | struct dentry * | 1297 | struct dentry * |