Skip to content
Permalink
1139b72d5e
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
242 lines (201 sloc) 6.31 KB
/*
* (C) 2003 Clemson University and The University of Chicago
*
* See COPYING in top-level directory.
*/
/** \file
* \ingroup mgmtint
*
* PVFS2 management interface routines for obtaining the handle of
* the object that holds directory data (the dirdata object).
*
* These routines are used primarily for file system check and repair
* purposes, and expose internal details of PVFS2 that may change.
*/
#include <string.h>
#include <assert.h>
#include "client-state-machine.h"
#include "pvfs2-debug.h"
#include "job.h"
#include "gossip.h"
#include "str-utils.h"
#include "pint-cached-config.h"
#include "PINT-reqproto-encode.h"
#include "pvfs2-internal.h"
extern job_context_id pint_client_sm_context;
static int mgmt_get_dirdata_handle_comp_fn(
void *v_p, struct PVFS_server_resp *resp_p, int i);
%%
machine pvfs2_client_mgmt_get_dirdata_handle_sm
{
state init
{
run mgmt_get_dirdata_handle_init;
default => get_dirdata_handle_setup_msgpair;
}
state get_dirdata_handle_setup_msgpair
{
run mgmt_get_dirdata_handle_setup_msgpair;
success => get_dirdata_handle_xfer_msgpair;
default => cleanup;
}
state get_dirdata_handle_xfer_msgpair
{
jump pvfs2_msgpairarray_sm;
default => cleanup;
}
state cleanup
{
run mgmt_get_dirdata_handle_cleanup;
default => terminate;
}
}
%%
/** Initiate retrieval of handle for dirdata object for a specific
* directory.
*/
PVFS_error PVFS_imgmt_get_dirdata_handle(
PVFS_object_ref parent_ref,
PVFS_handle *out_dirdata_handle,
PVFS_credentials *credentials,
PVFS_mgmt_op_id *op_id,
PVFS_hint hints,
void *user_ptr)
{
PVFS_error ret = -PVFS_EINVAL;
PINT_smcb *smcb = NULL;
PINT_client_sm *sm_p = NULL;
gossip_debug(GOSSIP_CLIENT_DEBUG,
"PVFS_imgmt_get_dirdata_handle entered\n");
if ((parent_ref.handle == PVFS_HANDLE_NULL) ||
(parent_ref.fs_id == PVFS_FS_ID_NULL) || !out_dirdata_handle)
{
gossip_err("invalid (NULL) required argument\n");
return ret;
}
PINT_smcb_alloc(&smcb, PVFS_MGMT_GET_DIRDATA_HANDLE,
sizeof(struct PINT_client_sm),
client_op_state_get_machine,
client_state_machine_terminate,
pint_client_sm_context);
if (smcb == NULL)
{
return -PVFS_ENOMEM;
}
sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
PINT_init_msgarray_params(sm_p, parent_ref.fs_id);
PINT_init_sysint_credentials(sm_p->cred_p, credentials);
sm_p->parent_ref = parent_ref;
sm_p->u.mgmt_get_dirdata_handle.dirdata_handle = out_dirdata_handle;
PVFS_hint_copy(hints, &sm_p->hints);
gossip_debug(
GOSSIP_CLIENT_DEBUG, "Trying to get dirdata object of parent "
"dir %llu,%d\n", llu(parent_ref.handle), parent_ref.fs_id);
return PINT_client_state_machine_post(
smcb, op_id, user_ptr);
}
/** Obtain handle for dirdata object for a specific directory.
*/
PVFS_error PVFS_mgmt_get_dirdata_handle(
PVFS_object_ref parent_ref,
PVFS_handle *out_dirdata_handle,
PVFS_credentials *credentials,
PVFS_hint hints)
{
PVFS_error ret = -PVFS_EINVAL, error = 0;
PVFS_mgmt_op_id op_id;
gossip_debug(GOSSIP_CLIENT_DEBUG,
"PVFS_mgmt_get_dirdata_handle entered\n");
ret = PVFS_imgmt_get_dirdata_handle(
parent_ref, out_dirdata_handle, credentials, &op_id, hints, NULL);
if (ret)
{
PVFS_perror_gossip("PVFS_imgmt_get_dirdata_handle call", ret);
error = ret;
}
else
{
ret = PVFS_mgmt_wait(op_id, "get_dirdata_handle", &error);
if (ret)
{
PVFS_perror_gossip("PVFS_mgmt_wait call", ret);
error = ret;
}
}
PINT_mgmt_release(op_id);
return error;
}
static int mgmt_get_dirdata_handle_init(
struct PINT_smcb *smcb, job_status_s *js_p)
{
assert(js_p->error_code == 0);
return SM_ACTION_COMPLETE;
}
static int mgmt_get_dirdata_handle_setup_msgpair(
struct PINT_smcb *smcb, job_status_s *js_p)
{
struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
int ret = -PVFS_EINVAL;
PINT_sm_msgpair_state *msg_p = NULL;
js_p->error_code = 0;
PINT_msgpair_init(&sm_p->msgarray_op);
msg_p = &sm_p->msgarray_op.msgpair;
PINT_SERVREQ_MGMT_GET_DIRDATA_HANDLE_FILL(
msg_p->req,
*sm_p->cred_p,
sm_p->parent_ref.fs_id,
sm_p->parent_ref.handle,
sm_p->hints);
gossip_debug(GOSSIP_CLIENT_DEBUG, "- doing MGMT_GET_DIRDATA_HANDLE "
"under %llu,%d\n", llu(sm_p->parent_ref.handle),
sm_p->parent_ref.fs_id);
msg_p->fs_id = sm_p->parent_ref.fs_id;
msg_p->handle = sm_p->parent_ref.handle;
msg_p->retry_flag = PVFS_MSGPAIR_NO_RETRY;
msg_p->comp_fn = mgmt_get_dirdata_handle_comp_fn;
ret = PINT_cached_config_map_to_server(
&msg_p->svr_addr, msg_p->handle, msg_p->fs_id);
if (ret)
{
gossip_err("Failed to map server address\n");
js_p->error_code = ret;
}
PINT_sm_push_frame(smcb, 0, &sm_p->msgarray_op);
return SM_ACTION_COMPLETE;
}
static int mgmt_get_dirdata_handle_comp_fn(
void *v_p, struct PVFS_server_resp *resp_p, int index)
{
PINT_smcb *smcb = v_p;
PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_MSGPAIR_PARENT_SM);
assert(resp_p->op == PVFS_SERV_MGMT_GET_DIRDATA_HANDLE);
if (resp_p->status == 0)
{
assert(sm_p->u.mgmt_get_dirdata_handle.dirdata_handle);
*sm_p->u.mgmt_get_dirdata_handle.dirdata_handle =
resp_p->u.mgmt_get_dirdata_handle.handle;
gossip_debug(
GOSSIP_CLIENT_DEBUG, " mgmt_get_dirdata_handle_comp_fn: "
"got dirdata handle %llu under %llu,%d removed\n",
llu(*sm_p->u.mgmt_get_dirdata_handle.dirdata_handle),
llu(sm_p->parent_ref.handle), sm_p->parent_ref.fs_id);
}
return resp_p->status;
}
static PINT_sm_action mgmt_get_dirdata_handle_cleanup(
struct PINT_smcb *smcb, job_status_s *js_p)
{
struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
sm_p->error_code = js_p->error_code;
PINT_SET_OP_COMPLETE;
return SM_ACTION_TERMINATE;
}
/*
* Local variables:
* mode: c
* c-indent-level: 4
* c-basic-offset: 4
* End:
*
* vim: ft=c ts=8 sts=4 sw=4 expandtab
*/