Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+21 -10
+4 -1
fs/nfs/nfs3acl.c
··· 129 129 .rpc_argp = &args, 130 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 137 status = -EOPNOTSUPP; 135 138 if (!nfs_server_capable(inode, NFS_CAP_ACLS))
+17 -9
fs/nfs/nfs4proc.c
··· 2560 2560 struct nfs4_closedata *calldata = data; 2561 2561 struct nfs4_state *state = calldata->state; 2562 2562 struct nfs_server *server = NFS_SERVER(calldata->inode); 2563 + nfs4_stateid *res_stateid = NULL; 2563 2564 2564 2565 dprintk("%s: begin!\n", __func__); 2565 2566 if (!nfs4_sequence_done(task, &calldata->res.seq_res)) ··· 2571 2570 */ 2572 2571 switch (task->tk_status) { 2573 2572 case 0: 2574 - if (calldata->roc) 2573 + res_stateid = &calldata->res.stateid; 2574 + if (calldata->arg.fmode == 0 && calldata->roc) 2575 2575 pnfs_roc_set_barrier(state->inode, 2576 2576 calldata->roc_barrier); 2577 - nfs_clear_open_stateid(state, &calldata->res.stateid, 0); 2578 2577 renew_lease(server, calldata->timestamp); 2579 - goto out_release; 2578 + break; 2580 2579 case -NFS4ERR_ADMIN_REVOKED: 2581 2580 case -NFS4ERR_STALE_STATEID: 2582 2581 case -NFS4ERR_OLD_STATEID: ··· 2590 2589 goto out_release; 2591 2590 } 2592 2591 } 2593 - nfs_clear_open_stateid(state, NULL, calldata->arg.fmode); 2592 + nfs_clear_open_stateid(state, res_stateid, calldata->arg.fmode); 2594 2593 out_release: 2595 2594 nfs_release_seqid(calldata->arg.seqid); 2596 2595 nfs_refresh_inode(calldata->inode, calldata->res.fattr); ··· 2602 2601 struct nfs4_closedata *calldata = data; 2603 2602 struct nfs4_state *state = calldata->state; 2604 2603 struct inode *inode = calldata->inode; 2604 + bool is_rdonly, is_wronly, is_rdwr; 2605 2605 int call_close = 0; 2606 2606 2607 2607 dprintk("%s: begin!\n", __func__); ··· 2610 2608 goto out_wait; 2611 2609 2612 2610 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; 2613 - calldata->arg.fmode = FMODE_READ|FMODE_WRITE; 2614 2611 spin_lock(&state->owner->so_lock); 2612 + is_rdwr = test_bit(NFS_O_RDWR_STATE, &state->flags); 2613 + is_rdonly = test_bit(NFS_O_RDONLY_STATE, &state->flags); 2614 + is_wronly = test_bit(NFS_O_WRONLY_STATE, &state->flags); 2615 + /* Calculate the current open share mode */ 2616 + calldata->arg.fmode = 0; 2617 + if (is_rdonly || is_rdwr) 2618 + calldata->arg.fmode |= FMODE_READ; 2619 + if (is_wronly || is_rdwr) 2620 + calldata->arg.fmode |= FMODE_WRITE; 2615 2621 /* Calculate the change in open mode */ 2616 2622 if (state->n_rdwr == 0) { 2617 2623 if (state->n_rdonly == 0) { 2618 - call_close |= test_bit(NFS_O_RDONLY_STATE, &state->flags); 2619 - call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags); 2624 + call_close |= is_rdonly || is_rdwr; 2620 2625 calldata->arg.fmode &= ~FMODE_READ; 2621 2626 } 2622 2627 if (state->n_wronly == 0) { 2623 - call_close |= test_bit(NFS_O_WRONLY_STATE, &state->flags); 2624 - call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags); 2628 + call_close |= is_wronly || is_rdwr; 2625 2629 calldata->arg.fmode &= ~FMODE_WRITE; 2626 2630 } 2627 2631 }