diff --git a/daemon/nfs41_client.c b/daemon/nfs41_client.c index 3d0e28a..8756ca5 100644 --- a/daemon/nfs41_client.c +++ b/daemon/nfs41_client.c @@ -209,6 +209,7 @@ void nfs41_client_free( { dprintf(2, "nfs41_client_free(%llu)\n", client->clnt_id); if (client->session) nfs41_session_free(client->session); + nfs41_destroy_clientid(client->rpc, client->clnt_id); if (client->server) nfs41_server_deref(client->server); nfs41_rpc_clnt_free(client->rpc); if (client->layouts) pnfs_layout_list_free(client->layouts); diff --git a/daemon/nfs41_ops.c b/daemon/nfs41_ops.c index 0089b26..3d0bd9f 100644 --- a/daemon/nfs41_ops.c +++ b/daemon/nfs41_ops.c @@ -231,6 +231,31 @@ out: return status; } +int nfs41_destroy_clientid( + IN nfs41_rpc_clnt *rpc, + IN uint64_t clientid) +{ + int status; + nfs41_compound compound; + nfs_argop4 argops; + nfs_resop4 resops; + nfs41_destroy_clientid_args dc_args; + nfs41_destroy_clientid_res dc_res; + + compound_init(&compound, &argops, &resops, "destroy_clientid"); + + compound_add_op(&compound, OP_DESTROY_CLIENTID, &dc_args, &dc_res); + + status = nfs41_send_compound(rpc, (char *)&compound.args, + (char *)&compound.res); + if (status) + goto out; + + compound_error(status = compound.res.status); +out: + return status; +} + enum nfsstat4 nfs41_reclaim_complete( IN nfs41_session *session) { diff --git a/daemon/nfs41_ops.h b/daemon/nfs41_ops.h index 1647c78..0c6922f 100644 --- a/daemon/nfs41_ops.h +++ b/daemon/nfs41_ops.h @@ -197,6 +197,17 @@ typedef struct __nfs41_destroy_session_res { } nfs41_destroy_session_res; +/* OP_DESTROY_CLIENTID */ +typedef struct __nfs41_destroy_clientid_args { + uint64_t dca_clientid; +} nfs41_destroy_clientid_args; + +typedef struct __nfs41_destroy_clientid_res { + uint32_t dcr_status; +} nfs41_destroy_clientid_res; + + + /* OP_SEQUENCE */ typedef struct __nfs41_sequence_args { unsigned char *sa_sessionid; @@ -898,6 +909,10 @@ enum nfsstat4 nfs41_bind_conn_to_session( int nfs41_destroy_session( IN nfs41_session *session); +int nfs41_destroy_clientid( + IN nfs41_rpc_clnt *rpc, + IN uint64_t clientid); + int nfs41_send_sequence( IN nfs41_session *session); diff --git a/daemon/nfs41_xdr.c b/daemon/nfs41_xdr.c index 77a2862..38e1e82 100644 --- a/daemon/nfs41_xdr.c +++ b/daemon/nfs41_xdr.c @@ -888,6 +888,33 @@ static bool_t decode_op_destroy_session( return xdr_u_int32_t(xdr, &res->dsr_status); } +/* + * OP_DESTROY_CLIENTID + */ +static bool_t encode_op_destroy_clientid( + XDR *xdr, + nfs_argop4 *argop) +{ + nfs41_destroy_clientid_args *args = (nfs41_destroy_clientid_args*)argop->arg; + + if (unexpected_op(argop->op, OP_DESTROY_CLIENTID)) + return FALSE; + + return xdr_u_hyper(xdr, &args->dca_clientid); +} + +static bool_t decode_op_destroy_clientid( + XDR *xdr, + nfs_resop4 *resop) +{ + nfs41_destroy_clientid_res *res = (nfs41_destroy_clientid_res*)resop->res; + + if (unexpected_op(resop->op, OP_DESTROY_CLIENTID)) + return FALSE; + + return xdr_u_int32_t(xdr, &res->dcr_status); +} + /* * OP_SEQUENCE @@ -3171,7 +3198,7 @@ static const op_table_entry g_op_table[] = { { NULL, NULL }, /* OP_SET_SSV = 54 */ { NULL, NULL }, /* OP_TEST_STATEID = 55 */ { NULL, NULL }, /* OP_WANT_DELEGATION = 56 */ - { NULL, NULL }, /* OP_DESTROY_CLIENTID = 57 */ + { encode_op_destroy_clientid, decode_op_destroy_clientid }, /* OP_DESTROY_CLIENTID = 57 */ { encode_op_reclaim_complete, decode_op_reclaim_complete }, /* OP_RECLAIM_COMPLETE = 58 */ }; static const uint32_t g_op_table_size = ARRAYSIZE(g_op_table);