diff options
| -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 | } |
