home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.parl.clemson.edu
/
2015-02-07.ftp.parl.clemson.edu.tar
/
ftp.parl.clemson.edu
/
pub
/
pvfs2
/
orangefs-2.8.3-20110323.tar.gz
/
orangefs-2.8.3-20110323.tar
/
orangefs
/
src
/
server
/
mkdir.sm
< prev
next >
Wrap
Text File
|
2008-11-25
|
8KB
|
335 lines
/*
* (C) 2001 Clemson University and The University of Chicago
*
* See COPYING in top-level directory.
*/
#include <string.h>
#include <assert.h>
#include "server-config.h"
#include "pvfs2-server.h"
#include "pvfs2-attr.h"
#include "pvfs2-util.h"
#include "pvfs2-internal.h"
#include "pint-util.h"
%%
nested machine pvfs2_mkdir_work_sm
{
state create
{
run mkdir_create;
success => set_attrib;
default => err_msg;
}
state set_attrib
{
run mkdir_setattrib;
success => create_dirdata_dspace;
default => err_msg;
}
state create_dirdata_dspace
{
run mkdir_create_dirdata_dspace;
success => write_dirdata_handle;
default => err_msg;
}
state write_dirdata_handle
{
run mkdir_write_dirdata_handle;
success => return;
default => err_msg;
}
state err_msg
{
run mkdir_error;
default => return;
}
}
machine pvfs2_mkdir_sm
{
state prelude
{
jump pvfs2_prelude_sm;
success => prep_sm;
default => final_response;
}
state prep_sm
{
run mkdir_prep_sm;
default => work;
}
state work
{
jump pvfs2_mkdir_work_sm;
default => final_response;
}
state final_response
{
jump pvfs2_final_response_sm;
default => cleanup;
}
state cleanup
{
run mkdir_cleanup;
default => terminate;
}
}
%%
/*
* Function: mkdir_create
*
* Params: server_op *s_op,
* job_status_s *js_p
*
* Returns: int
*
* Synopsis:
*
* NOTE: returned handle will pop out in js_p->handle (the job status
* struct).
*/
static PINT_sm_action mkdir_create(
struct PINT_smcb *smcb, job_status_s *js_p)
{
struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
int ret;
job_id_t i;
gossip_debug(GOSSIP_MKDIR_DEBUG, " creating dspace on coll_id %d\n",
s_op->u.mkdir.fs_id);
gossip_debug(
GOSSIP_MKDIR_DEBUG, " directory handle will "
"be in starting hrange[0] %llu-%llu\n",
llu(s_op->u.mkdir.handle_extent_array.extent_array[0].first),
llu(s_op->u.mkdir.handle_extent_array.extent_array[0].last));
ret = job_trove_dspace_create(
s_op->u.mkdir.fs_id, &s_op->u.mkdir.handle_extent_array,
PVFS_TYPE_DIRECTORY, NULL,
TROVE_SYNC,
smcb, 0, js_p, &i,
server_job_context, s_op->req->hints);
return ret;
}
/*
* Function: mkdir_setattrib
*
* Params: server_op *s_op,
* job_status_s *js_p
*
* Returns: int
*
* Synopsis:
*
*/
static PINT_sm_action mkdir_setattrib(
struct PINT_smcb *smcb, job_status_s *js_p)
{
struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
int ret = -1;
job_id_t j_id;
PVFS_ds_attributes *ds_attr = NULL;
/* save the handle from the mkdir in the response */
s_op->resp.u.mkdir.handle = js_p->handle;
gossip_debug(GOSSIP_MKDIR_DEBUG, " *** new directory has handle %llu\n",
llu(js_p->handle));
ds_attr = (&s_op->ds_attr);
PVFS_ds_init_time(ds_attr);
gossip_debug(GOSSIP_MKDIR_DEBUG, " setting directory version to "
"%llu\n\tmtime is %llu\n", llu(ds_attr->mtime),
llu(PINT_util_mkversion_time(ds_attr->mtime)));
ret = job_trove_dspace_setattr(
s_op->u.mkdir.fs_id, s_op->resp.u.mkdir.handle,
ds_attr,
TROVE_SYNC,
smcb, 0, js_p, &j_id, server_job_context, s_op->req->hints);
return ret;
}
static int mkdir_create_dirdata_dspace(
struct PINT_smcb *smcb, job_status_s *js_p)
{
struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
int ret = -PVFS_ENOMEM;
job_id_t i;
PVFS_handle_extent_array extent_array;
struct server_configuration_s *user_opts = get_server_config_struct();
gossip_debug(GOSSIP_MKDIR_DEBUG, " creating dspace on coll_id %d\n",
s_op->u.mkdir.fs_id);
/* find our meta handle range for this create */
ret = PINT_config_get_meta_handle_extent_array(
user_opts, s_op->u.mkdir.fs_id, &extent_array);
assert(ret == 0);
assert(extent_array.extent_count > 0);
gossip_debug(GOSSIP_MKDIR_DEBUG, " dirdata handle will "
"be in starting hrange[0] %llu-%llu\n",
llu(extent_array.extent_array[0].first),
llu(extent_array.extent_array[0].last));
ret = job_trove_dspace_create(
s_op->u.mkdir.fs_id, &extent_array, PVFS_TYPE_DIRDATA, NULL,
TROVE_SYNC,
smcb, 0, js_p, &i,
server_job_context, s_op->req->hints);
free(extent_array.extent_array);
extent_array.extent_array = NULL;
return ret;
}
static PINT_sm_action mkdir_write_dirdata_handle(
struct PINT_smcb *smcb, job_status_s *js_p)
{
struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
int ret = -PVFS_EINVAL;
job_id_t i;
if (js_p->error_code)
{
return SM_ACTION_COMPLETE;
}
js_p->error_code = 0;
s_op->u.mkdir.dirent_handle = js_p->handle;
gossip_debug(GOSSIP_MKDIR_DEBUG, " *** new dirdata has handle %llu\n",
llu(s_op->u.mkdir.dirent_handle));
s_op->key.buffer = Trove_Common_Keys[DIR_ENT_KEY].key;
s_op->key.buffer_sz = Trove_Common_Keys[DIR_ENT_KEY].size;
s_op->val.buffer = &s_op->u.mkdir.dirent_handle;
s_op->val.buffer_sz = sizeof(PVFS_handle);
gossip_debug(
GOSSIP_MKDIR_DEBUG, " writing dirdata handle (%llu) "
"into parent dir (%llu)\n", llu(s_op->u.mkdir.dirent_handle),
llu(s_op->resp.u.mkdir.handle));
/* we don't sync here since we're going to anyway in the following
* operation (setting the dirent count).
*/
ret = job_trove_keyval_write(
s_op->u.mkdir.fs_id, s_op->resp.u.mkdir.handle,
&s_op->key, &s_op->val,
0,
NULL, smcb, 0, js_p, &i, server_job_context, s_op->req->hints);
return ret;
}
static int mkdir_error(struct PINT_smcb *smcb, job_status_s *js_p)
{
struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
s_op->resp.u.mkdir.handle = 0;
if (js_p->error_code > -1)
{
js_p->error_code = -PVFS_EINVAL;
}
return 1;
}
/*
* Function: mkdir_cleanup
*
* Params: server_op *b,
* job_status_s *js_p
*
* Returns: int
*
* Synopsis: free memory and return
*
*/
static PINT_sm_action mkdir_cleanup(
struct PINT_smcb *smcb, job_status_s *js_p)
{
return(server_state_machine_complete(smcb));
}
static PINT_sm_action mkdir_prep_sm(
struct PINT_smcb *smcb, job_status_s *js_p)
{
struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
PVFS_object_attr *a_p = NULL;
PVFS_ds_attributes *ds_attr = NULL;
s_op->u.mkdir.fs_id = s_op->req->u.mkdir.fs_id;
s_op->u.mkdir.handle_extent_array =
s_op->req->u.mkdir.handle_extent_array;
a_p = &(s_op->req->u.mkdir.attr);
if (a_p->objtype != PVFS_TYPE_DIRECTORY)
{
js_p->error_code = -PVFS_EINVAL;
return SM_ACTION_COMPLETE;
}
gossip_debug(GOSSIP_MKDIR_DEBUG, " attrs to write: [owner = %d, "
"group = %d, perms = %o]\n", a_p->owner, a_p->group,
a_p->perms);
/* translate attrs to storage attr format */
ds_attr = (&s_op->ds_attr);
PVFS_object_attr_to_ds_attr(a_p, ds_attr);
js_p->error_code = 0;
return SM_ACTION_COMPLETE;
}
static inline int PINT_get_object_ref_mkdir(
struct PVFS_server_req *req, PVFS_fs_id *fs_id, PVFS_handle *handle)
{
*fs_id = req->u.mkdir.fs_id;
*handle = PVFS_HANDLE_NULL;
return 0;
};
struct PINT_server_req_params pvfs2_mkdir_params =
{
.string_name = "mkdir",
.perm = PINT_SERVER_CHECK_NONE,
.access_type = PINT_server_req_modify,
.state_machine = &pvfs2_mkdir_sm
};
/*
* Local variables:
* mode: c
* c-indent-level: 4
* c-basic-offset: 4
* End:
*
* vim: ft=c ts=8 sts=4 sw=4 expandtab
*/