mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-04-14 09:37:32 +07:00
nfsd41: implement NFS4_SHARE_WANT_NO_DELEG, NFS4_OPEN_DELEGATE_NONE_EXT, why_no_deleg
Respect client request for not getting a delegation in NFSv4.1 Appropriately return delegation "type" NFS4_OPEN_DELEGATE_NONE_EXT and WND4_NOT_WANTED reason. [nfsd41: add missing break when encoding op_why_no_deleg] Signed-off-by: Benny Halevy <bhalevy@tonian.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
parent
03cfb42025
commit
d24433cdc9
@ -2866,7 +2866,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_ol_
|
|||||||
struct nfs4_delegation *dp;
|
struct nfs4_delegation *dp;
|
||||||
struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner);
|
struct nfs4_openowner *oo = container_of(stp->st_stateowner, struct nfs4_openowner, oo_owner);
|
||||||
int cb_up;
|
int cb_up;
|
||||||
int status, flag = 0;
|
int status = 0, flag = 0;
|
||||||
|
|
||||||
cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client);
|
cb_up = nfsd4_cb_channel_good(oo->oo_owner.so_client);
|
||||||
flag = NFS4_OPEN_DELEGATE_NONE;
|
flag = NFS4_OPEN_DELEGATE_NONE;
|
||||||
@ -2907,11 +2907,32 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_ol_
|
|||||||
dprintk("NFSD: delegation stateid=" STATEID_FMT "\n",
|
dprintk("NFSD: delegation stateid=" STATEID_FMT "\n",
|
||||||
STATEID_VAL(&dp->dl_stid.sc_stateid));
|
STATEID_VAL(&dp->dl_stid.sc_stateid));
|
||||||
out:
|
out:
|
||||||
if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS
|
|
||||||
&& flag == NFS4_OPEN_DELEGATE_NONE
|
|
||||||
&& open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE)
|
|
||||||
dprintk("NFSD: WARNING: refusing delegation reclaim\n");
|
|
||||||
open->op_delegate_type = flag;
|
open->op_delegate_type = flag;
|
||||||
|
if (flag == NFS4_OPEN_DELEGATE_NONE) {
|
||||||
|
if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS &&
|
||||||
|
open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE)
|
||||||
|
dprintk("NFSD: WARNING: refusing delegation reclaim\n");
|
||||||
|
|
||||||
|
if (open->op_deleg_want) {
|
||||||
|
open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT;
|
||||||
|
if (status == -EAGAIN)
|
||||||
|
open->op_why_no_deleg = WND4_CONTENTION;
|
||||||
|
else {
|
||||||
|
open->op_why_no_deleg = WND4_RESOURCE;
|
||||||
|
switch (open->op_deleg_want) {
|
||||||
|
case NFS4_SHARE_WANT_READ_DELEG:
|
||||||
|
case NFS4_SHARE_WANT_WRITE_DELEG:
|
||||||
|
case NFS4_SHARE_WANT_ANY_DELEG:
|
||||||
|
break;
|
||||||
|
case NFS4_SHARE_WANT_CANCEL:
|
||||||
|
open->op_why_no_deleg = WND4_CANCELLED;
|
||||||
|
break;
|
||||||
|
case NFS4_SHARE_WANT_NO_DELEG:
|
||||||
|
BUG(); /* not supposed to get here */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
out_free:
|
out_free:
|
||||||
nfs4_put_delegation(dp);
|
nfs4_put_delegation(dp);
|
||||||
@ -2981,20 +3002,45 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
|
|||||||
update_stateid(&stp->st_stid.sc_stateid);
|
update_stateid(&stp->st_stid.sc_stateid);
|
||||||
memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
|
memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
|
||||||
|
|
||||||
if (nfsd4_has_session(&resp->cstate))
|
if (nfsd4_has_session(&resp->cstate)) {
|
||||||
open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
|
open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
|
||||||
|
|
||||||
|
if (open->op_deleg_want & NFS4_SHARE_WANT_NO_DELEG) {
|
||||||
|
open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT;
|
||||||
|
open->op_why_no_deleg = WND4_NOT_WANTED;
|
||||||
|
goto nodeleg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attempt to hand out a delegation. No error return, because the
|
* Attempt to hand out a delegation. No error return, because the
|
||||||
* OPEN succeeds even if we fail.
|
* OPEN succeeds even if we fail.
|
||||||
*/
|
*/
|
||||||
nfs4_open_delegation(current_fh, open, stp);
|
nfs4_open_delegation(current_fh, open, stp);
|
||||||
|
nodeleg:
|
||||||
status = nfs_ok;
|
status = nfs_ok;
|
||||||
|
|
||||||
dprintk("%s: stateid=" STATEID_FMT "\n", __func__,
|
dprintk("%s: stateid=" STATEID_FMT "\n", __func__,
|
||||||
STATEID_VAL(&stp->st_stid.sc_stateid));
|
STATEID_VAL(&stp->st_stid.sc_stateid));
|
||||||
out:
|
out:
|
||||||
|
/* 4.1 client trying to upgrade/downgrade delegation? */
|
||||||
|
if (open->op_delegate_type == NFS4_OPEN_DELEGATE_NONE && dp &&
|
||||||
|
open->op_deleg_want) {
|
||||||
|
if (open->op_deleg_want == NFS4_SHARE_WANT_READ_DELEG &&
|
||||||
|
dp->dl_type == NFS4_OPEN_DELEGATE_WRITE) {
|
||||||
|
open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT;
|
||||||
|
open->op_why_no_deleg = WND4_NOT_SUPP_DOWNGRADE;
|
||||||
|
} else if (open->op_deleg_want == NFS4_SHARE_WANT_WRITE_DELEG &&
|
||||||
|
dp->dl_type == NFS4_OPEN_DELEGATE_WRITE) {
|
||||||
|
open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT;
|
||||||
|
open->op_why_no_deleg = WND4_NOT_SUPP_UPGRADE;
|
||||||
|
}
|
||||||
|
/* Otherwise the client must be confused wanting a delegation
|
||||||
|
* it already has, therefore we don't return
|
||||||
|
* NFS4_OPEN_DELEGATE_NONE_EXT and reason.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
if (fp)
|
if (fp)
|
||||||
put_nfs4_file(fp);
|
put_nfs4_file(fp);
|
||||||
if (status == 0 && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
|
if (status == 0 && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
|
||||||
|
@ -2849,6 +2849,20 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op
|
|||||||
WRITE32(0); /* XXX: is NULL principal ok? */
|
WRITE32(0); /* XXX: is NULL principal ok? */
|
||||||
ADJUST_ARGS();
|
ADJUST_ARGS();
|
||||||
break;
|
break;
|
||||||
|
case NFS4_OPEN_DELEGATE_NONE_EXT: /* 4.1 */
|
||||||
|
switch (open->op_why_no_deleg) {
|
||||||
|
case WND4_CONTENTION:
|
||||||
|
case WND4_RESOURCE:
|
||||||
|
RESERVE_SPACE(8);
|
||||||
|
WRITE32(open->op_why_no_deleg);
|
||||||
|
WRITE32(0); /* deleg signaling not supported yet */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
RESERVE_SPACE(4);
|
||||||
|
WRITE32(open->op_why_no_deleg);
|
||||||
|
}
|
||||||
|
ADJUST_ARGS();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
@ -223,6 +223,7 @@ struct nfsd4_open {
|
|||||||
struct xdr_netobj op_fname; /* request - everything but CLAIM_PREV */
|
struct xdr_netobj op_fname; /* request - everything but CLAIM_PREV */
|
||||||
u32 op_delegate_type; /* request - CLAIM_PREV only */
|
u32 op_delegate_type; /* request - CLAIM_PREV only */
|
||||||
stateid_t op_delegate_stateid; /* request - response */
|
stateid_t op_delegate_stateid; /* request - response */
|
||||||
|
u32 op_why_no_deleg; /* response - DELEG_NONE_EXT only */
|
||||||
u32 op_create; /* request */
|
u32 op_create; /* request */
|
||||||
u32 op_createmode; /* request */
|
u32 op_createmode; /* request */
|
||||||
u32 op_bmval[3]; /* request */
|
u32 op_bmval[3]; /* request */
|
||||||
|
@ -441,7 +441,20 @@ enum limit_by4 {
|
|||||||
enum open_delegation_type4 {
|
enum open_delegation_type4 {
|
||||||
NFS4_OPEN_DELEGATE_NONE = 0,
|
NFS4_OPEN_DELEGATE_NONE = 0,
|
||||||
NFS4_OPEN_DELEGATE_READ = 1,
|
NFS4_OPEN_DELEGATE_READ = 1,
|
||||||
NFS4_OPEN_DELEGATE_WRITE = 2
|
NFS4_OPEN_DELEGATE_WRITE = 2,
|
||||||
|
NFS4_OPEN_DELEGATE_NONE_EXT = 3, /* 4.1 */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum why_no_delegation4 { /* new to v4.1 */
|
||||||
|
WND4_NOT_WANTED = 0,
|
||||||
|
WND4_CONTENTION = 1,
|
||||||
|
WND4_RESOURCE = 2,
|
||||||
|
WND4_NOT_SUPP_FTYPE = 3,
|
||||||
|
WND4_WRITE_DELEG_NOT_SUPP_FTYPE = 4,
|
||||||
|
WND4_NOT_SUPP_UPGRADE = 5,
|
||||||
|
WND4_NOT_SUPP_DOWNGRADE = 6,
|
||||||
|
WND4_CANCELLED = 7,
|
||||||
|
WND4_IS_DIR = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum lock_type4 {
|
enum lock_type4 {
|
||||||
|
Loading…
Reference in New Issue
Block a user