X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=fs%2Fnfsd%2Fnfs4proc.c;h=27d74a2945151cfbdf76e41cd381b90a0efe4d09;hb=9a0e5110f736437bb683f49ceac058a4fce9e47e;hp=8ae5abfe6ba24fd699aed2e156a2b2f815695c04;hpb=5647ac0ad4f355817b788372a01cb293ed63bde4;p=~andy%2Flinux 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; }