Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 66245539 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFSv4.1: Add DESTROY_CLIENTID



Ensure that we destroy our lease on last unmount

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 2cf047c9
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -209,6 +209,7 @@ static void nfs4_shutdown_session(struct nfs_client *clp)
	if (nfs4_has_session(clp)) {
	if (nfs4_has_session(clp)) {
		nfs4_deviceid_purge_client(clp);
		nfs4_deviceid_purge_client(clp);
		nfs4_destroy_session(clp->cl_session);
		nfs4_destroy_session(clp->cl_session);
		nfs4_destroy_clientid(clp);
	}
	}


}
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -214,6 +214,7 @@ extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setcli
extern int nfs4_proc_get_rootfh(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
extern int nfs4_proc_get_rootfh(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
extern int nfs4_proc_bind_conn_to_session(struct nfs_client *, struct rpc_cred *cred);
extern int nfs4_proc_bind_conn_to_session(struct nfs_client *, struct rpc_cred *cred);
extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred);
extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred);
extern int nfs4_destroy_clientid(struct nfs_client *clp);
extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *);
extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *);
extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *);
extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *);
extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc);
extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc);
+59 −0
Original line number Original line Diff line number Diff line
@@ -5261,6 +5261,65 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
	return status;
	return status;
}
}


static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
		struct rpc_cred *cred)
{
	struct rpc_message msg = {
		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DESTROY_CLIENTID],
		.rpc_argp = clp,
		.rpc_cred = cred,
	};
	int status;

	status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
	if (status)
		pr_warn("NFS: Got error %d from the server %s on "
			"DESTROY_CLIENTID.", status, clp->cl_hostname);
	return status;
}

static int nfs4_proc_destroy_clientid(struct nfs_client *clp,
		struct rpc_cred *cred)
{
	unsigned int loop;
	int ret;

	for (loop = NFS4_MAX_LOOP_ON_RECOVER; loop != 0; loop--) {
		ret = _nfs4_proc_destroy_clientid(clp, cred);
		switch (ret) {
		case -NFS4ERR_DELAY:
		case -NFS4ERR_CLIENTID_BUSY:
			ssleep(1);
			break;
		default:
			return ret;
		}
	}
	return 0;
}

int nfs4_destroy_clientid(struct nfs_client *clp)
{
	struct rpc_cred *cred;
	int ret = 0;

	if (clp->cl_mvops->minor_version < 1)
		goto out;
	if (clp->cl_exchange_flags == 0)
		goto out;
	cred = nfs4_get_exchange_id_cred(clp);
	ret = nfs4_proc_destroy_clientid(clp, cred);
	if (cred)
		put_rpccred(cred);
	switch (ret) {
	case 0:
	case -NFS4ERR_STALE_CLIENTID:
		clp->cl_exchange_flags = 0;
	}
out:
	return ret;
}

struct nfs4_get_lease_time_data {
struct nfs4_get_lease_time_data {
	struct nfs4_get_lease_time_args *args;
	struct nfs4_get_lease_time_args *args;
	struct nfs4_get_lease_time_res *res;
	struct nfs4_get_lease_time_res *res;
+52 −0
Original line number Original line Diff line number Diff line
@@ -338,6 +338,8 @@ static int nfs4_stat_to_errno(int);
				     1 /* bctsr_use_conn_in_rdma_mode */)
				     1 /* bctsr_use_conn_in_rdma_mode */)
#define encode_destroy_session_maxsz    (op_encode_hdr_maxsz + 4)
#define encode_destroy_session_maxsz    (op_encode_hdr_maxsz + 4)
#define decode_destroy_session_maxsz    (op_decode_hdr_maxsz)
#define decode_destroy_session_maxsz    (op_decode_hdr_maxsz)
#define encode_destroy_clientid_maxsz   (op_encode_hdr_maxsz + 2)
#define decode_destroy_clientid_maxsz   (op_decode_hdr_maxsz)
#define encode_sequence_maxsz	(op_encode_hdr_maxsz + \
#define encode_sequence_maxsz	(op_encode_hdr_maxsz + \
				XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 4)
				XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 4)
#define decode_sequence_maxsz	(op_decode_hdr_maxsz + \
#define decode_sequence_maxsz	(op_decode_hdr_maxsz + \
@@ -751,6 +753,10 @@ static int nfs4_stat_to_errno(int);
					 encode_destroy_session_maxsz)
					 encode_destroy_session_maxsz)
#define NFS4_dec_destroy_session_sz	(compound_decode_hdr_maxsz + \
#define NFS4_dec_destroy_session_sz	(compound_decode_hdr_maxsz + \
					 decode_destroy_session_maxsz)
					 decode_destroy_session_maxsz)
#define NFS4_enc_destroy_clientid_sz	(compound_encode_hdr_maxsz + \
					 encode_destroy_clientid_maxsz)
#define NFS4_dec_destroy_clientid_sz	(compound_decode_hdr_maxsz + \
					 decode_destroy_clientid_maxsz)
#define NFS4_enc_sequence_sz \
#define NFS4_enc_sequence_sz \
				(compound_decode_hdr_maxsz + \
				(compound_decode_hdr_maxsz + \
				 encode_sequence_maxsz)
				 encode_sequence_maxsz)
@@ -1804,6 +1810,14 @@ static void encode_destroy_session(struct xdr_stream *xdr,
	encode_opaque_fixed(xdr, session->sess_id.data, NFS4_MAX_SESSIONID_LEN);
	encode_opaque_fixed(xdr, session->sess_id.data, NFS4_MAX_SESSIONID_LEN);
}
}


static void encode_destroy_clientid(struct xdr_stream *xdr,
				   uint64_t clientid,
				   struct compound_hdr *hdr)
{
	encode_op_hdr(xdr, OP_DESTROY_CLIENTID, decode_destroy_clientid_maxsz, hdr);
	encode_uint64(xdr, clientid);
}

static void encode_reclaim_complete(struct xdr_stream *xdr,
static void encode_reclaim_complete(struct xdr_stream *xdr,
				    struct nfs41_reclaim_complete_args *args,
				    struct nfs41_reclaim_complete_args *args,
				    struct compound_hdr *hdr)
				    struct compound_hdr *hdr)
@@ -2723,6 +2737,22 @@ static void nfs4_xdr_enc_destroy_session(struct rpc_rqst *req,
	encode_nops(&hdr);
	encode_nops(&hdr);
}
}


/*
 * a DESTROY_CLIENTID request
 */
static void nfs4_xdr_enc_destroy_clientid(struct rpc_rqst *req,
					 struct xdr_stream *xdr,
					 struct nfs_client *clp)
{
	struct compound_hdr hdr = {
		.minorversion = clp->cl_mvops->minor_version,
	};

	encode_compound_hdr(xdr, req, &hdr);
	encode_destroy_clientid(xdr, clp->cl_clientid, &hdr);
	encode_nops(&hdr);
}

/*
/*
 * a SEQUENCE request
 * a SEQUENCE request
 */
 */
@@ -5479,6 +5509,11 @@ static int decode_destroy_session(struct xdr_stream *xdr, void *dummy)
	return decode_op_hdr(xdr, OP_DESTROY_SESSION);
	return decode_op_hdr(xdr, OP_DESTROY_SESSION);
}
}


static int decode_destroy_clientid(struct xdr_stream *xdr, void *dummy)
{
	return decode_op_hdr(xdr, OP_DESTROY_CLIENTID);
}

static int decode_reclaim_complete(struct xdr_stream *xdr, void *dummy)
static int decode_reclaim_complete(struct xdr_stream *xdr, void *dummy)
{
{
	return decode_op_hdr(xdr, OP_RECLAIM_COMPLETE);
	return decode_op_hdr(xdr, OP_RECLAIM_COMPLETE);
@@ -6788,6 +6823,22 @@ static int nfs4_xdr_dec_destroy_session(struct rpc_rqst *rqstp,
	return status;
	return status;
}
}


/*
 * Decode DESTROY_CLIENTID response
 */
static int nfs4_xdr_dec_destroy_clientid(struct rpc_rqst *rqstp,
					struct xdr_stream *xdr,
					void *res)
{
	struct compound_hdr hdr;
	int status;

	status = decode_compound_hdr(xdr, &hdr);
	if (!status)
		status = decode_destroy_clientid(xdr, res);
	return status;
}

/*
/*
 * Decode SEQUENCE response
 * Decode SEQUENCE response
 */
 */
@@ -7237,6 +7288,7 @@ struct rpc_procinfo nfs4_procedures[] = {
	PROC(GETDEVICELIST,	enc_getdevicelist,	dec_getdevicelist),
	PROC(GETDEVICELIST,	enc_getdevicelist,	dec_getdevicelist),
	PROC(BIND_CONN_TO_SESSION,
	PROC(BIND_CONN_TO_SESSION,
			enc_bind_conn_to_session, dec_bind_conn_to_session),
			enc_bind_conn_to_session, dec_bind_conn_to_session),
	PROC(DESTROY_CLIENTID,	enc_destroy_clientid,	dec_destroy_clientid),
#endif /* CONFIG_NFS_V4_1 */
#endif /* CONFIG_NFS_V4_1 */
};
};


+1 −0
Original line number Original line Diff line number Diff line
@@ -608,6 +608,7 @@ enum {
	NFSPROC4_CLNT_FREE_STATEID,
	NFSPROC4_CLNT_FREE_STATEID,
	NFSPROC4_CLNT_GETDEVICELIST,
	NFSPROC4_CLNT_GETDEVICELIST,
	NFSPROC4_CLNT_BIND_CONN_TO_SESSION,
	NFSPROC4_CLNT_BIND_CONN_TO_SESSION,
	NFSPROC4_CLNT_DESTROY_CLIENTID,
};
};


/* nfs41 types */
/* nfs41 types */