Skip to content

Commit d3edfd9

Browse files
jtlaytonchucklever
authored andcommitted
nfsd: implement OPEN_ARGS_SHARE_ACCESS_WANT_OPEN_XOR_DELEGATION
Allow clients to request getting a delegation xor an open stateid if a delegation isn't available. This allows the client to avoid sending a final CLOSE for the (useless) open stateid, when it is granted a delegation. If this flag is requested by the client and there isn't already a new open stateid, discard the new open stateid before replying. Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: Chuck Lever <[email protected]>
1 parent 7e13f4f commit d3edfd9

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

fs/nfsd/nfs4state.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6242,6 +6242,17 @@ static void nfsd4_deleg_xgrade_none_ext(struct nfsd4_open *open,
62426242
*/
62436243
}
62446244

6245+
/* Are we returning only a delegation stateid? */
6246+
static bool open_xor_delegation(struct nfsd4_open *open)
6247+
{
6248+
if (!(open->op_deleg_want & OPEN4_SHARE_ACCESS_WANT_OPEN_XOR_DELEGATION))
6249+
return false;
6250+
/* Did we actually get a delegation? */
6251+
if (!deleg_is_read(open->op_delegate_type) && !deleg_is_write(open->op_delegate_type))
6252+
return false;
6253+
return true;
6254+
}
6255+
62456256
/**
62466257
* nfsd4_process_open2 - finish open processing
62476258
* @rqstp: the RPC transaction being executed
@@ -6339,6 +6350,17 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
63396350
* OPEN succeeds even if we fail.
63406351
*/
63416352
nfs4_open_delegation(open, stp, &resp->cstate.current_fh);
6353+
6354+
/*
6355+
* If there is an existing open stateid, it must be updated and
6356+
* returned. Only respect WANT_OPEN_XOR_DELEGATION when a new
6357+
* open stateid would have to be created.
6358+
*/
6359+
if (new_stp && open_xor_delegation(open)) {
6360+
memcpy(&open->op_stateid, &zero_stateid, sizeof(open->op_stateid));
6361+
open->op_rflags |= OPEN4_RESULT_NO_OPEN_STATEID;
6362+
release_open_stateid(stp);
6363+
}
63426364
nodeleg:
63436365
status = nfs_ok;
63446366
trace_nfsd_open(&stp->st_stid.sc_stateid);
@@ -6355,7 +6377,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
63556377
/*
63566378
* To finish the open response, we just need to set the rflags.
63576379
*/
6358-
open->op_rflags = NFS4_OPEN_RESULT_LOCKTYPE_POSIX;
6380+
open->op_rflags |= NFS4_OPEN_RESULT_LOCKTYPE_POSIX;
63596381
if (nfsd4_has_session(&resp->cstate))
63606382
open->op_rflags |= NFS4_OPEN_RESULT_MAY_NOTIFY_LOCK;
63616383
else if (!(open->op_openowner->oo_flags & NFS4_OO_CONFIRMED))

fs/nfsd/nfs4xdr.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3421,7 +3421,8 @@ static __be32 nfsd4_encode_fattr4_xattr_support(struct xdr_stream *xdr,
34213421
#define NFSD_OA_SHARE_ACCESS_WANT (BIT(OPEN_ARGS_SHARE_ACCESS_WANT_ANY_DELEG) | \
34223422
BIT(OPEN_ARGS_SHARE_ACCESS_WANT_NO_DELEG) | \
34233423
BIT(OPEN_ARGS_SHARE_ACCESS_WANT_CANCEL) | \
3424-
BIT(OPEN_ARGS_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS))
3424+
BIT(OPEN_ARGS_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS) | \
3425+
BIT(OPEN_ARGS_SHARE_ACCESS_WANT_OPEN_XOR_DELEGATION))
34253426

34263427
#define NFSD_OA_OPEN_CLAIM (BIT(OPEN_ARGS_OPEN_CLAIM_NULL) | \
34273428
BIT(OPEN_ARGS_OPEN_CLAIM_PREVIOUS) | \

0 commit comments

Comments
 (0)