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 8ae5abfe6ba2..27d74a294515 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 | |||
279 | { | 279 | { |
280 | struct svc_fh *current_fh = &cstate->current_fh; | 280 | struct svc_fh *current_fh = &cstate->current_fh; |
281 | __be32 status; | 281 | __be32 status; |
282 | int accmode = 0; | ||
282 | 283 | ||
283 | /* We don't know the target directory, and therefore can not | 284 | /* We don't know the target directory, and therefore can not |
284 | * set the change info | 285 | * set the change info |
@@ -290,9 +291,19 @@ do_open_fhandle(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, str | |||
290 | 291 | ||
291 | open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) && | 292 | open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) && |
292 | (open->op_iattr.ia_size == 0); | 293 | (open->op_iattr.ia_size == 0); |
294 | /* | ||
295 | * In the delegation case, the client is telling us about an | ||
296 | * open that it *already* performed locally, some time ago. We | ||
297 | * should let it succeed now if possible. | ||
298 | * | ||
299 | * In the case of a CLAIM_FH open, on the other hand, the client | ||
300 | * may be counting on us to enforce permissions (the Linux 4.1 | ||
301 | * client uses this for normal opens, for example). | ||
302 | */ | ||
303 | if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEG_CUR_FH) | ||
304 | accmode = NFSD_MAY_OWNER_OVERRIDE; | ||
293 | 305 | ||
294 | status = do_open_permission(rqstp, current_fh, open, | 306 | status = do_open_permission(rqstp, current_fh, open, accmode); |
295 | NFSD_MAY_OWNER_OVERRIDE); | ||
296 | 307 | ||
297 | return status; | 308 | return status; |
298 | } | 309 | } |