mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-02-22 07:43:45 -05:00
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 <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
@@ -6242,6 +6242,17 @@ static void nfsd4_deleg_xgrade_none_ext(struct nfsd4_open *open,
|
||||
*/
|
||||
}
|
||||
|
||||
/* Are we returning only a delegation stateid? */
|
||||
static bool open_xor_delegation(struct nfsd4_open *open)
|
||||
{
|
||||
if (!(open->op_deleg_want & OPEN4_SHARE_ACCESS_WANT_OPEN_XOR_DELEGATION))
|
||||
return false;
|
||||
/* Did we actually get a delegation? */
|
||||
if (!deleg_is_read(open->op_delegate_type) && !deleg_is_write(open->op_delegate_type))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* nfsd4_process_open2 - finish open processing
|
||||
* @rqstp: the RPC transaction being executed
|
||||
@@ -6339,6 +6350,17 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
|
||||
* OPEN succeeds even if we fail.
|
||||
*/
|
||||
nfs4_open_delegation(open, stp, &resp->cstate.current_fh);
|
||||
|
||||
/*
|
||||
* If there is an existing open stateid, it must be updated and
|
||||
* returned. Only respect WANT_OPEN_XOR_DELEGATION when a new
|
||||
* open stateid would have to be created.
|
||||
*/
|
||||
if (new_stp && open_xor_delegation(open)) {
|
||||
memcpy(&open->op_stateid, &zero_stateid, sizeof(open->op_stateid));
|
||||
open->op_rflags |= OPEN4_RESULT_NO_OPEN_STATEID;
|
||||
release_open_stateid(stp);
|
||||
}
|
||||
nodeleg:
|
||||
status = nfs_ok;
|
||||
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
|
||||
/*
|
||||
* To finish the open response, we just need to set the rflags.
|
||||
*/
|
||||
open->op_rflags = NFS4_OPEN_RESULT_LOCKTYPE_POSIX;
|
||||
open->op_rflags |= NFS4_OPEN_RESULT_LOCKTYPE_POSIX;
|
||||
if (nfsd4_has_session(&resp->cstate))
|
||||
open->op_rflags |= NFS4_OPEN_RESULT_MAY_NOTIFY_LOCK;
|
||||
else if (!(open->op_openowner->oo_flags & NFS4_OO_CONFIRMED))
|
||||
|
||||
@@ -3421,7 +3421,8 @@ static __be32 nfsd4_encode_fattr4_xattr_support(struct xdr_stream *xdr,
|
||||
#define NFSD_OA_SHARE_ACCESS_WANT (BIT(OPEN_ARGS_SHARE_ACCESS_WANT_ANY_DELEG) | \
|
||||
BIT(OPEN_ARGS_SHARE_ACCESS_WANT_NO_DELEG) | \
|
||||
BIT(OPEN_ARGS_SHARE_ACCESS_WANT_CANCEL) | \
|
||||
BIT(OPEN_ARGS_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS))
|
||||
BIT(OPEN_ARGS_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS) | \
|
||||
BIT(OPEN_ARGS_SHARE_ACCESS_WANT_OPEN_XOR_DELEGATION))
|
||||
|
||||
#define NFSD_OA_OPEN_CLAIM (BIT(OPEN_ARGS_OPEN_CLAIM_NULL) | \
|
||||
BIT(OPEN_ARGS_OPEN_CLAIM_PREVIOUS) | \
|
||||
|
||||
Reference in New Issue
Block a user