diff options
Diffstat (limited to 'fs/nfs/dir.c')
| -rw-r--r-- | fs/nfs/dir.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 8a0530921685..c82a21228a34 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -2431,6 +2431,20 @@ int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags) | |||
| 2431 | } | 2431 | } |
| 2432 | EXPORT_SYMBOL_GPL(nfs_may_open); | 2432 | EXPORT_SYMBOL_GPL(nfs_may_open); |
| 2433 | 2433 | ||
| 2434 | static int nfs_execute_ok(struct inode *inode, int mask) | ||
| 2435 | { | ||
| 2436 | struct nfs_server *server = NFS_SERVER(inode); | ||
| 2437 | int ret; | ||
| 2438 | |||
| 2439 | if (mask & MAY_NOT_BLOCK) | ||
| 2440 | ret = nfs_revalidate_inode_rcu(server, inode); | ||
| 2441 | else | ||
| 2442 | ret = nfs_revalidate_inode(server, inode); | ||
| 2443 | if (ret == 0 && !execute_ok(inode)) | ||
| 2444 | ret = -EACCES; | ||
| 2445 | return ret; | ||
| 2446 | } | ||
| 2447 | |||
| 2434 | int nfs_permission(struct inode *inode, int mask) | 2448 | int nfs_permission(struct inode *inode, int mask) |
| 2435 | { | 2449 | { |
| 2436 | struct rpc_cred *cred; | 2450 | struct rpc_cred *cred; |
| @@ -2448,6 +2462,9 @@ int nfs_permission(struct inode *inode, int mask) | |||
| 2448 | case S_IFLNK: | 2462 | case S_IFLNK: |
| 2449 | goto out; | 2463 | goto out; |
| 2450 | case S_IFREG: | 2464 | case S_IFREG: |
| 2465 | if ((mask & MAY_OPEN) && | ||
| 2466 | nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN)) | ||
| 2467 | return 0; | ||
| 2451 | break; | 2468 | break; |
| 2452 | case S_IFDIR: | 2469 | case S_IFDIR: |
| 2453 | /* | 2470 | /* |
| @@ -2480,8 +2497,8 @@ force_lookup: | |||
| 2480 | res = PTR_ERR(cred); | 2497 | res = PTR_ERR(cred); |
| 2481 | } | 2498 | } |
| 2482 | out: | 2499 | out: |
| 2483 | if (!res && (mask & MAY_EXEC) && !execute_ok(inode)) | 2500 | if (!res && (mask & MAY_EXEC)) |
| 2484 | res = -EACCES; | 2501 | res = nfs_execute_ok(inode, mask); |
| 2485 | 2502 | ||
| 2486 | dfprintk(VFS, "NFS: permission(%s/%lu), mask=0x%x, res=%d\n", | 2503 | dfprintk(VFS, "NFS: permission(%s/%lu), mask=0x%x, res=%d\n", |
| 2487 | inode->i_sb->s_id, inode->i_ino, mask, res); | 2504 | inode->i_sb->s_id, inode->i_ino, mask, res); |
