diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-29 16:04:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-29 16:04:13 -0400 |
commit | 878e580e211c519c1b32a2c65786d308a759ec24 (patch) | |
tree | abb7a44574589d016d3a94898187fb2ea86bb95f /fs | |
parent | 848298c6fb36fbe459854e376ce90af32ba6e1ce (diff) | |
parent | f87d928f6d98644d39809a013a22f981d39017cf (diff) |
Merge tag 'nfs-for-3.17-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client fixes from Trond Myklebust:
"Highlights:
- NFSv3 stable fix for another POSIX ACL regression
- NFSv4 stable fix for a regression with OPEN_DOWNGRADE
- NFSv4 stable fix for bad close() behaviour when holding a delegation"
* tag 'nfs-for-3.17-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
NFSv3: Fix another acl regression
NFSv4: Don't clear the open state when we just did an OPEN_DOWNGRADE
NFSv4: Fix problems with close in the presence of a delegation
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/nfs3acl.c | 5 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 26 |
2 files changed, 21 insertions, 10 deletions
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index d0fec260132a..24c6898159cc 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c | |||
@@ -129,7 +129,10 @@ static int __nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
129 | .rpc_argp = &args, | 129 | .rpc_argp = &args, |
130 | .rpc_resp = &fattr, | 130 | .rpc_resp = &fattr, |
131 | }; | 131 | }; |
132 | int status; | 132 | int status = 0; |
133 | |||
134 | if (acl == NULL && (!S_ISDIR(inode->i_mode) || dfacl == NULL)) | ||
135 | goto out; | ||
133 | 136 | ||
134 | status = -EOPNOTSUPP; | 137 | status = -EOPNOTSUPP; |
135 | if (!nfs_server_capable(inode, NFS_CAP_ACLS)) | 138 | if (!nfs_server_capable(inode, NFS_CAP_ACLS)) |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 75ae8d22f067..7dd8aca31c29 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -2560,6 +2560,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data) | |||
2560 | struct nfs4_closedata *calldata = data; | 2560 | struct nfs4_closedata *calldata = data; |
2561 | struct nfs4_state *state = calldata->state; | 2561 | struct nfs4_state *state = calldata->state; |
2562 | struct nfs_server *server = NFS_SERVER(calldata->inode); | 2562 | struct nfs_server *server = NFS_SERVER(calldata->inode); |
2563 | nfs4_stateid *res_stateid = NULL; | ||
2563 | 2564 | ||
2564 | dprintk("%s: begin!\n", __func__); | 2565 | dprintk("%s: begin!\n", __func__); |
2565 | if (!nfs4_sequence_done(task, &calldata->res.seq_res)) | 2566 | if (!nfs4_sequence_done(task, &calldata->res.seq_res)) |
@@ -2570,12 +2571,12 @@ static void nfs4_close_done(struct rpc_task *task, void *data) | |||
2570 | */ | 2571 | */ |
2571 | switch (task->tk_status) { | 2572 | switch (task->tk_status) { |
2572 | case 0: | 2573 | case 0: |
2573 | if (calldata->roc) | 2574 | res_stateid = &calldata->res.stateid; |
2575 | if (calldata->arg.fmode == 0 && calldata->roc) | ||
2574 | pnfs_roc_set_barrier(state->inode, | 2576 | pnfs_roc_set_barrier(state->inode, |
2575 | calldata->roc_barrier); | 2577 | calldata->roc_barrier); |
2576 | nfs_clear_open_stateid(state, &calldata->res.stateid, 0); | ||
2577 | renew_lease(server, calldata->timestamp); | 2578 | renew_lease(server, calldata->timestamp); |
2578 | goto out_release; | 2579 | break; |
2579 | case -NFS4ERR_ADMIN_REVOKED: | 2580 | case -NFS4ERR_ADMIN_REVOKED: |
2580 | case -NFS4ERR_STALE_STATEID: | 2581 | case -NFS4ERR_STALE_STATEID: |
2581 | case -NFS4ERR_OLD_STATEID: | 2582 | case -NFS4ERR_OLD_STATEID: |
@@ -2589,7 +2590,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data) | |||
2589 | goto out_release; | 2590 | goto out_release; |
2590 | } | 2591 | } |
2591 | } | 2592 | } |
2592 | nfs_clear_open_stateid(state, NULL, calldata->arg.fmode); | 2593 | nfs_clear_open_stateid(state, res_stateid, calldata->arg.fmode); |
2593 | out_release: | 2594 | out_release: |
2594 | nfs_release_seqid(calldata->arg.seqid); | 2595 | nfs_release_seqid(calldata->arg.seqid); |
2595 | nfs_refresh_inode(calldata->inode, calldata->res.fattr); | 2596 | nfs_refresh_inode(calldata->inode, calldata->res.fattr); |
@@ -2601,6 +2602,7 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) | |||
2601 | struct nfs4_closedata *calldata = data; | 2602 | struct nfs4_closedata *calldata = data; |
2602 | struct nfs4_state *state = calldata->state; | 2603 | struct nfs4_state *state = calldata->state; |
2603 | struct inode *inode = calldata->inode; | 2604 | struct inode *inode = calldata->inode; |
2605 | bool is_rdonly, is_wronly, is_rdwr; | ||
2604 | int call_close = 0; | 2606 | int call_close = 0; |
2605 | 2607 | ||
2606 | dprintk("%s: begin!\n", __func__); | 2608 | dprintk("%s: begin!\n", __func__); |
@@ -2608,18 +2610,24 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) | |||
2608 | goto out_wait; | 2610 | goto out_wait; |
2609 | 2611 | ||
2610 | task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; | 2612 | task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; |
2611 | calldata->arg.fmode = FMODE_READ|FMODE_WRITE; | ||
2612 | spin_lock(&state->owner->so_lock); | 2613 | spin_lock(&state->owner->so_lock); |
2614 | is_rdwr = test_bit(NFS_O_RDWR_STATE, &state->flags); | ||
2615 | is_rdonly = test_bit(NFS_O_RDONLY_STATE, &state->flags); | ||
2616 | is_wronly = test_bit(NFS_O_WRONLY_STATE, &state->flags); | ||
2617 | /* Calculate the current open share mode */ | ||
2618 | calldata->arg.fmode = 0; | ||
2619 | if (is_rdonly || is_rdwr) | ||
2620 | calldata->arg.fmode |= FMODE_READ; | ||
2621 | if (is_wronly || is_rdwr) | ||
2622 | calldata->arg.fmode |= FMODE_WRITE; | ||
2613 | /* Calculate the change in open mode */ | 2623 | /* Calculate the change in open mode */ |
2614 | if (state->n_rdwr == 0) { | 2624 | if (state->n_rdwr == 0) { |
2615 | if (state->n_rdonly == 0) { | 2625 | if (state->n_rdonly == 0) { |
2616 | call_close |= test_bit(NFS_O_RDONLY_STATE, &state->flags); | 2626 | call_close |= is_rdonly || is_rdwr; |
2617 | call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags); | ||
2618 | calldata->arg.fmode &= ~FMODE_READ; | 2627 | calldata->arg.fmode &= ~FMODE_READ; |
2619 | } | 2628 | } |
2620 | if (state->n_wronly == 0) { | 2629 | if (state->n_wronly == 0) { |
2621 | call_close |= test_bit(NFS_O_WRONLY_STATE, &state->flags); | 2630 | call_close |= is_wronly || is_rdwr; |
2622 | call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags); | ||
2623 | calldata->arg.fmode &= ~FMODE_WRITE; | 2631 | calldata->arg.fmode &= ~FMODE_WRITE; |
2624 | } | 2632 | } |
2625 | } | 2633 | } |