diff options
Diffstat (limited to 'fs/nfsd/nfs4proc.c')
| -rw-r--r-- | fs/nfsd/nfs4proc.c | 15 | 
1 files changed, 13 insertions, 2 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 8ae5abfe6ba..27d74a29451 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -279,6 +279,7 @@ do_open_fhandle(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, str  {  	struct svc_fh *current_fh = &cstate->current_fh;  	__be32 status; +	int accmode = 0;  	/* We don't know the target directory, and therefore can not  	* set the change info @@ -290,9 +291,19 @@ do_open_fhandle(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, str  	open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) &&  		(open->op_iattr.ia_size == 0); +	/* +	 * In the delegation case, the client is telling us about an +	 * open that it *already* performed locally, some time ago.  We +	 * should let it succeed now if possible. +	 * +	 * In the case of a CLAIM_FH open, on the other hand, the client +	 * may be counting on us to enforce permissions (the Linux 4.1 +	 * client uses this for normal opens, for example). +	 */ +	if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEG_CUR_FH) +		accmode = NFSD_MAY_OWNER_OVERRIDE; -	status = do_open_permission(rqstp, current_fh, open, -				    NFSD_MAY_OWNER_OVERRIDE); +	status = do_open_permission(rqstp, current_fh, open, accmode);  	return status;  }  |