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
280 lines (236 sloc) 7.43 KB
/*
* (C) 2003 Clemson University and The University of Chicago
*
* See COPYING in top-level directory.
*/
/** \file
* \ingroup sysint
*
* PVFS2 system interface routines for flushing data to disk on servers.
*/
#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 "pint-util.h"
#include "pvfs2-internal.h"
extern job_context_id pint_client_sm_context;
%%
machine pvfs2_client_flush_sm
{
state flush_getattr
{
jump pvfs2_client_getattr_sm;
success => flush_datafile_setup_msgpairarray;
default => cleanup;
}
state flush_datafile_setup_msgpairarray
{
run flush_datafile_setup_msgpairarray;
success => flush_datafile_xfer_msgpairarray;
default => cleanup;
}
state flush_datafile_xfer_msgpairarray
{
jump pvfs2_msgpairarray_sm;
success => cleanup;
default => flush_datafile_flush_failure;
}
state flush_datafile_flush_failure
{
run flush_datafile_flush_failure;
default => cleanup;
}
state cleanup
{
run flush_cleanup;
default => terminate;
}
}
%%
/** Initiate flushing of file data to storage on servers.
*/
PVFS_error PVFS_isys_flush(
PVFS_object_ref ref,
const PVFS_credentials *credentials,
PVFS_sys_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_isys_flush entered\n");
if ((ref.fs_id == PVFS_FS_ID_NULL) ||
(ref.handle == PVFS_HANDLE_NULL))
{
gossip_err("Invalid handle/fs_id specified\n");
return ret;
}
PINT_smcb_alloc(&smcb, PVFS_SYS_FLUSH,
sizeof(struct PINT_client_sm),
client_op_state_get_machine,
client_state_machine_terminate,
pint_client_sm_context);
if (!smcb)
{
return -PVFS_ENOMEM;
}
sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
PINT_init_msgarray_params(sm_p, ref.fs_id);
PINT_init_sysint_credentials(sm_p->cred_p, credentials);
sm_p->object_ref = ref;
PVFS_hint_copy(hints, &sm_p->hints);
PVFS_hint_add(&sm_p->hints, PVFS_HINT_HANDLE_NAME, sizeof(PVFS_handle), &ref.handle);
/* NOTE: This state machine previously multiplied the default job timeout
* by five to allow for potentially long sync delays. We instead now set
* the default client BMI timeout higher for all operations: if a sync can
* go slow then so can any other arbitrary operation queued behind it. -PHC
*/
PINT_SM_GETATTR_STATE_FILL(
sm_p->getattr,
ref,
PVFS_ATTR_META_ALL|PVFS_ATTR_COMMON_TYPE,
PVFS_TYPE_METAFILE,
0);
return PINT_client_state_machine_post(
smcb, op_id, user_ptr);
}
/** Flush file data to storage on servers.
*/
PVFS_error PVFS_sys_flush(
PVFS_object_ref ref,
const PVFS_credentials *credentials,
PVFS_hint hints)
{
PVFS_error ret = -PVFS_EINVAL, error = 0;
PVFS_sys_op_id op_id;
gossip_debug(GOSSIP_CLIENT_DEBUG, "PVFS_sys_flush entered\n");
ret = PVFS_isys_flush(ref, credentials, &op_id, hints, NULL);
if (ret)
{
PVFS_perror_gossip("PVFS_isys_flush call", ret);
error = ret;
}
else
{
ret = PVFS_sys_wait(op_id, "flush", &error);
if (ret)
{
PVFS_perror_gossip("PVFS_sys_wait call", ret);
error = ret;
}
}
PINT_sys_release(op_id);
return error;
}
static int flush_datafile_setup_msgpairarray(
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, i = 0;
PVFS_object_attr *attr = NULL;
PINT_sm_msgpair_state *msg_p = NULL;
gossip_debug(GOSSIP_CLIENT_DEBUG, "(%p) flush state: "
"datafile_setup_msgpairarray\n", sm_p);
js_p->error_code = 0;
attr = &sm_p->getattr.attr;
assert(attr);
if(!(attr->mask & PVFS_ATTR_META_DFILES) ||
!(attr->u.meta.dfile_count > 0))
{
/* this object does not have defiles - sync not supported */
js_p->error_code = -PVFS_EINVAL;
return SM_ACTION_COMPLETE;
}
ret = PINT_msgpairarray_init(&sm_p->msgarray_op, (attr->u.meta.dfile_count + 1));
if(ret != 0)
{
gossip_err("Failed to initialize %d msgpairs\n",
(attr->u.meta.dfile_count + 1));
js_p->error_code = ret;
return SM_ACTION_COMPLETE;
}
/* datafile count + 1 metafile */
foreach_msgpair(&sm_p->msgarray_op, msg_p, i)
{
if (i < attr->u.meta.dfile_count)
{
gossip_debug(GOSSIP_CLIENT_DEBUG,
" datafile_flush: flushing handle %llu\n",
llu(attr->u.meta.dfile_array[i]));
PINT_SERVREQ_FLUSH_FILL(msg_p->req,
*sm_p->cred_p,
sm_p->object_ref.fs_id,
attr->u.meta.dfile_array[i],
sm_p->hints);
msg_p->fs_id = sm_p->object_ref.fs_id;
msg_p->handle = attr->u.meta.dfile_array[i];
msg_p->retry_flag = PVFS_MSGPAIR_RETRY;
msg_p->comp_fn = NULL;
}
else
{
assert(i == (sm_p->msgarray_op.count - 1));
gossip_debug(GOSSIP_CLIENT_DEBUG,
" metafile_flush: flushing handle %llu\n",
llu(sm_p->object_ref.handle));
PINT_SERVREQ_FLUSH_FILL(msg_p->req,
*sm_p->cred_p,
sm_p->object_ref.fs_id,
sm_p->object_ref.handle,
sm_p->hints);
msg_p->fs_id = sm_p->object_ref.fs_id;
msg_p->handle = sm_p->object_ref.handle;
msg_p->retry_flag = PVFS_MSGPAIR_RETRY;
msg_p->comp_fn = NULL;
}
}
ret = PINT_serv_msgpairarray_resolve_addrs(&sm_p->msgarray_op);
if (ret)
{
gossip_err("Error: failed to resolve server addresses.\n");
js_p->error_code = ret;
}
PINT_sm_push_frame(smcb, 0, &sm_p->msgarray_op);
return SM_ACTION_COMPLETE;
}
static int flush_datafile_flush_failure(
struct PINT_smcb *smcb, job_status_s *js_p)
{
struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
gossip_debug(GOSSIP_CLIENT_DEBUG,
"(%p) flush state: datafile_flush_failure\n",
sm_p);
return SM_ACTION_COMPLETE;
}
static int flush_cleanup(
struct PINT_smcb *smcb, job_status_s *js_p)
{
struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
gossip_debug(GOSSIP_CLIENT_DEBUG,
"(%p) flush state: flush_cleanup\n", sm_p);
sm_p->error_code = js_p->error_code;
if(sm_p->error_code != 0)
{
PINT_acache_invalidate(sm_p->object_ref);
}
PINT_SM_GETATTR_STATE_CLEAR(sm_p->getattr);
PINT_msgpairarray_destroy(&sm_p->msgarray_op);
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
*/