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 >
Text File  |  2008-11-25  |  8KB  |  335 lines

  1. /* 
  2.  * (C) 2001 Clemson University and The University of Chicago 
  3.  *
  4.  * See COPYING in top-level directory.
  5.  */
  6.  
  7.  
  8. #include <string.h>
  9. #include <assert.h>
  10.  
  11. #include "server-config.h"
  12. #include "pvfs2-server.h"
  13. #include "pvfs2-attr.h"
  14. #include "pvfs2-util.h"
  15. #include "pvfs2-internal.h"
  16. #include "pint-util.h"
  17.  
  18. %%
  19.  
  20. nested machine pvfs2_mkdir_work_sm
  21. {
  22.     state create
  23.     {
  24.         run mkdir_create;
  25.         success => set_attrib;
  26.         default => err_msg;
  27.     }
  28.  
  29.     state set_attrib
  30.     {
  31.         run mkdir_setattrib;
  32.         success => create_dirdata_dspace;
  33.         default => err_msg;
  34.     }
  35.  
  36.     state create_dirdata_dspace
  37.     {
  38.         run mkdir_create_dirdata_dspace;
  39.         success => write_dirdata_handle;
  40.         default => err_msg;
  41.     }
  42.  
  43.     state write_dirdata_handle
  44.     {
  45.         run mkdir_write_dirdata_handle;
  46.         success => return;
  47.         default => err_msg;
  48.     }
  49.  
  50.     state err_msg 
  51.     {
  52.         run mkdir_error;
  53.         default => return;
  54.     }
  55. }
  56.  
  57. machine pvfs2_mkdir_sm
  58. {
  59.     state prelude
  60.     {
  61.         jump pvfs2_prelude_sm;
  62.         success => prep_sm;
  63.         default => final_response;
  64.     }
  65.  
  66.     state prep_sm
  67.     {
  68.         run mkdir_prep_sm;
  69.         default => work;
  70.     }
  71.  
  72.     state work
  73.     {
  74.         jump pvfs2_mkdir_work_sm;
  75.         default => final_response;
  76.     }
  77.  
  78.     state final_response
  79.     {
  80.         jump pvfs2_final_response_sm;
  81.         default => cleanup;
  82.     }
  83.  
  84.     state cleanup
  85.     {
  86.         run mkdir_cleanup;
  87.         default => terminate;
  88.     }
  89. }
  90.  
  91. %%
  92.  
  93. /*
  94.  * Function: mkdir_create
  95.  *
  96.  * Params:   server_op *s_op, 
  97.  *           job_status_s *js_p
  98.  *
  99.  * Returns:  int
  100.  *
  101.  * Synopsis: 
  102.  *
  103.  * NOTE: returned handle will pop out in js_p->handle (the job status
  104.  * struct).
  105.  */
  106. static PINT_sm_action mkdir_create(
  107.         struct PINT_smcb *smcb, job_status_s *js_p)
  108. {
  109.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  110.     int ret;
  111.     job_id_t i;
  112.  
  113.     gossip_debug(GOSSIP_MKDIR_DEBUG, " creating dspace on coll_id %d\n",
  114.                  s_op->u.mkdir.fs_id);
  115.  
  116.     gossip_debug(
  117.         GOSSIP_MKDIR_DEBUG, " directory handle will "
  118.         "be in starting hrange[0] %llu-%llu\n",
  119.         llu(s_op->u.mkdir.handle_extent_array.extent_array[0].first),
  120.         llu(s_op->u.mkdir.handle_extent_array.extent_array[0].last));
  121.  
  122.     ret = job_trove_dspace_create(
  123.         s_op->u.mkdir.fs_id, &s_op->u.mkdir.handle_extent_array,
  124.         PVFS_TYPE_DIRECTORY, NULL,
  125.         TROVE_SYNC, 
  126.         smcb, 0, js_p, &i,
  127.         server_job_context, s_op->req->hints);
  128.  
  129.     return ret;
  130. }
  131.  
  132. /*
  133.  * Function: mkdir_setattrib
  134.  *
  135.  * Params:   server_op *s_op, 
  136.  *           job_status_s *js_p
  137.  *
  138.  * Returns:  int
  139.  *
  140.  * Synopsis: 
  141.  *           
  142.  */
  143. static PINT_sm_action mkdir_setattrib(
  144.         struct PINT_smcb *smcb, job_status_s *js_p)
  145. {
  146.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  147.     int ret = -1;
  148.     job_id_t j_id;
  149.     PVFS_ds_attributes *ds_attr = NULL;
  150.  
  151.     /* save the handle from the mkdir in the response */
  152.     s_op->resp.u.mkdir.handle = js_p->handle;
  153.  
  154.     gossip_debug(GOSSIP_MKDIR_DEBUG, " *** new directory has handle %llu\n",
  155.                  llu(js_p->handle));
  156.  
  157.     ds_attr = (&s_op->ds_attr);
  158.     PVFS_ds_init_time(ds_attr);
  159.  
  160.     gossip_debug(GOSSIP_MKDIR_DEBUG, " setting directory version to "
  161.                  "%llu\n\tmtime is %llu\n", llu(ds_attr->mtime),
  162.                  llu(PINT_util_mkversion_time(ds_attr->mtime)));
  163.  
  164.     ret = job_trove_dspace_setattr(
  165.         s_op->u.mkdir.fs_id, s_op->resp.u.mkdir.handle,
  166.         ds_attr, 
  167.         TROVE_SYNC,
  168.         smcb, 0, js_p, &j_id, server_job_context, s_op->req->hints);
  169.  
  170.     return ret;
  171. }
  172.  
  173. static int mkdir_create_dirdata_dspace(
  174.     struct PINT_smcb *smcb, job_status_s *js_p)
  175. {
  176.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  177.     int ret = -PVFS_ENOMEM;
  178.     job_id_t i;
  179.     PVFS_handle_extent_array extent_array;
  180.     struct server_configuration_s *user_opts = get_server_config_struct();
  181.  
  182.     gossip_debug(GOSSIP_MKDIR_DEBUG, " creating dspace on coll_id %d\n",
  183.                  s_op->u.mkdir.fs_id);
  184.  
  185.     /* find our meta handle range for this create */
  186.     ret = PINT_config_get_meta_handle_extent_array(
  187.         user_opts, s_op->u.mkdir.fs_id, &extent_array);
  188.     assert(ret == 0);
  189.     assert(extent_array.extent_count > 0);
  190.  
  191.     gossip_debug(GOSSIP_MKDIR_DEBUG, " dirdata handle will "
  192.                  "be in starting hrange[0] %llu-%llu\n",
  193.                  llu(extent_array.extent_array[0].first),
  194.                  llu(extent_array.extent_array[0].last));
  195.  
  196.     ret = job_trove_dspace_create(
  197.         s_op->u.mkdir.fs_id, &extent_array, PVFS_TYPE_DIRDATA, NULL,
  198.         TROVE_SYNC,
  199.         smcb, 0, js_p, &i,
  200.         server_job_context, s_op->req->hints);
  201.  
  202.     free(extent_array.extent_array);
  203.     extent_array.extent_array = NULL;
  204.  
  205.     return ret;
  206. }
  207.  
  208. static PINT_sm_action mkdir_write_dirdata_handle(
  209.         struct PINT_smcb *smcb, job_status_s *js_p)
  210. {
  211.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  212.     int ret = -PVFS_EINVAL;
  213.     job_id_t i;
  214.  
  215.     if (js_p->error_code)
  216.     {
  217.         return SM_ACTION_COMPLETE;
  218.     }
  219.     js_p->error_code = 0;
  220.  
  221.  
  222.     s_op->u.mkdir.dirent_handle = js_p->handle;
  223.  
  224.     gossip_debug(GOSSIP_MKDIR_DEBUG, " *** new dirdata has handle %llu\n",
  225.                  llu(s_op->u.mkdir.dirent_handle));
  226.  
  227.     s_op->key.buffer = Trove_Common_Keys[DIR_ENT_KEY].key;
  228.     s_op->key.buffer_sz = Trove_Common_Keys[DIR_ENT_KEY].size;
  229.  
  230.     s_op->val.buffer = &s_op->u.mkdir.dirent_handle;
  231.     s_op->val.buffer_sz = sizeof(PVFS_handle);
  232.  
  233.     gossip_debug(
  234.         GOSSIP_MKDIR_DEBUG, "  writing dirdata handle (%llu) "
  235.         "into parent dir (%llu)\n", llu(s_op->u.mkdir.dirent_handle),
  236.         llu(s_op->resp.u.mkdir.handle));
  237.  
  238.     /* we don't sync here since we're going to anyway in the following
  239.      * operation (setting the dirent count).
  240.      */
  241.     ret = job_trove_keyval_write(
  242.         s_op->u.mkdir.fs_id, s_op->resp.u.mkdir.handle,
  243.         &s_op->key, &s_op->val, 
  244.         0,
  245.         NULL, smcb, 0, js_p, &i, server_job_context, s_op->req->hints);
  246.  
  247.     return ret;
  248. }
  249.  
  250. static int mkdir_error(struct PINT_smcb *smcb, job_status_s *js_p)
  251. {
  252.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  253.     s_op->resp.u.mkdir.handle = 0;
  254.  
  255.     if (js_p->error_code > -1)
  256.     {
  257.         js_p->error_code = -PVFS_EINVAL;
  258.     }
  259.     return 1;
  260. }
  261.  
  262. /*
  263.  * Function: mkdir_cleanup
  264.  *
  265.  * Params:   server_op *b, 
  266.  *           job_status_s *js_p
  267.  *
  268.  * Returns:  int
  269.  *
  270.  * Synopsis: free memory and return
  271.  *           
  272.  */
  273. static PINT_sm_action mkdir_cleanup(
  274.         struct PINT_smcb *smcb, job_status_s *js_p)
  275. {
  276.     return(server_state_machine_complete(smcb));
  277. }
  278.  
  279. static PINT_sm_action mkdir_prep_sm(
  280.         struct PINT_smcb *smcb, job_status_s *js_p)
  281. {
  282.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  283.     PVFS_object_attr *a_p = NULL;
  284.     PVFS_ds_attributes *ds_attr = NULL;
  285.  
  286.     s_op->u.mkdir.fs_id = s_op->req->u.mkdir.fs_id;
  287.     s_op->u.mkdir.handle_extent_array =
  288.         s_op->req->u.mkdir.handle_extent_array;
  289.  
  290.     a_p = &(s_op->req->u.mkdir.attr);
  291.  
  292.     if (a_p->objtype != PVFS_TYPE_DIRECTORY)
  293.     {
  294.         js_p->error_code = -PVFS_EINVAL;
  295.         return SM_ACTION_COMPLETE;
  296.     }
  297.  
  298.     gossip_debug(GOSSIP_MKDIR_DEBUG, " attrs to write: [owner = %d, "
  299.                  "group = %d, perms = %o]\n", a_p->owner, a_p->group,
  300.                  a_p->perms);
  301.  
  302.     /* translate attrs to storage attr format */
  303.     ds_attr = (&s_op->ds_attr);
  304.     PVFS_object_attr_to_ds_attr(a_p, ds_attr);
  305.  
  306.     js_p->error_code = 0;
  307.     return SM_ACTION_COMPLETE;
  308. }
  309.  
  310. static inline int PINT_get_object_ref_mkdir(
  311.     struct PVFS_server_req *req, PVFS_fs_id *fs_id, PVFS_handle *handle)
  312. {
  313.     *fs_id = req->u.mkdir.fs_id;
  314.     *handle = PVFS_HANDLE_NULL;
  315.     return 0;
  316. };
  317.  
  318. struct PINT_server_req_params pvfs2_mkdir_params =
  319. {
  320.     .string_name = "mkdir",
  321.     .perm = PINT_SERVER_CHECK_NONE,
  322.     .access_type = PINT_server_req_modify,
  323.     .state_machine = &pvfs2_mkdir_sm
  324. };
  325.  
  326. /*
  327.  * Local variables:
  328.  *  mode: c
  329.  *  c-indent-level: 4
  330.  *  c-basic-offset: 4
  331.  * End:
  332.  *
  333.  * vim: ft=c ts=8 sts=4 sw=4 expandtab
  334.  */
  335.