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 / chdirent.sm < prev    next >
Text File  |  2010-04-30  |  9KB  |  344 lines

  1. /* 
  2.  * (C) 2001 Clemson University and The University of Chicago 
  3.  *
  4.  * See COPYING in top-level directory.
  5.  */
  6.  
  7. #include <string.h>
  8. #include <assert.h>
  9.  
  10. #include "server-config.h"
  11. #include "pvfs2-server.h"
  12. #include "pvfs2-attr.h"
  13. #include "gossip.h"
  14. #include "pvfs2-util.h"
  15. #include "pvfs2-internal.h"
  16. #include "pint-util.h"
  17.  
  18. enum
  19. {
  20.     UPDATE_DIR_ATTR_REQUIRED = 135
  21. };
  22.  
  23. %%
  24.  
  25. machine pvfs2_chdirent_sm
  26. {
  27.     state prelude
  28.     {
  29.         jump pvfs2_prelude_sm;
  30.         success => verify_parent_metadata_and_read_directory_entry_handle;
  31.         default => final_response;
  32.     }
  33.  
  34.     state verify_parent_metadata_and_read_directory_entry_handle
  35.     {
  36.         run chdirent_verify_parent_metadata_and_read_directory_entry_handle;
  37.         success => read_directory_entry;
  38.         default => setup_resp;
  39.     }
  40.  
  41.     state read_directory_entry
  42.     {
  43.         run chdirent_read_directory_entry;
  44.         success => change_directory_entry;
  45.         default => read_directory_entry_failure;
  46.     }
  47.  
  48.     state read_directory_entry_failure
  49.     {
  50.         run chdirent_read_directory_entry_failure;
  51.         default => setup_resp;
  52.     }
  53.  
  54.     state change_directory_entry
  55.     {
  56.         run chdirent_change_directory_entry;
  57.         success => check_for_req_dir_update;
  58.         default => change_directory_entry_failure;
  59.     }
  60.  
  61.     state change_directory_entry_failure
  62.     {
  63.         run chdirent_change_directory_entry_failure;
  64.         default => setup_resp;
  65.     }
  66.  
  67.     state check_for_req_dir_update
  68.     {
  69.         run chdirent_check_for_req_dir_update;
  70.         UPDATE_DIR_ATTR_REQUIRED => update_directory_attr;
  71.         default => setup_resp;
  72.     }
  73.  
  74.     state update_directory_attr
  75.     {
  76.         run chdirent_update_directory_attr;
  77.         default => setup_resp;
  78.     }
  79.  
  80.     state setup_resp
  81.     {
  82.         run chdirent_setup_resp;
  83.         default => final_response;
  84.     }
  85.  
  86.     state final_response
  87.     {
  88.         jump pvfs2_final_response_sm;
  89.         default => cleanup;
  90.     }
  91.  
  92.     state cleanup
  93.     {
  94.         run chdirent_cleanup;
  95.         default => terminate;
  96.     }
  97. }
  98.  
  99. %%
  100.  
  101. static PINT_sm_action chdirent_verify_parent_metadata_and_read_directory_entry_handle(
  102.         struct PINT_smcb *smcb, job_status_s *js_p)
  103. {
  104.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  105.     int ret = -PVFS_EINVAL;
  106.     job_id_t i;
  107.  
  108.     s_op->key.buffer = Trove_Common_Keys[DIR_ENT_KEY].key;
  109.     s_op->key.buffer_sz = Trove_Common_Keys[DIR_ENT_KEY].size;
  110.  
  111.     s_op->val.buffer = &s_op->u.chdirent.dirdata_handle;
  112.     s_op->val.buffer_sz = sizeof(PVFS_handle);
  113.  
  114.     gossip_debug(
  115.         GOSSIP_SERVER_DEBUG,
  116.         "  reading dirdata handle (coll_id = 0x%x, handle = %llu, "
  117.         "key = %s (%d), val_buf = %p (%d))\n",
  118.         s_op->req->u.chdirent.fs_id,
  119.         llu(s_op->req->u.chdirent.handle),
  120.         (char *) s_op->key.buffer,
  121.         s_op->key.buffer_sz,
  122.         s_op->val.buffer,
  123.         s_op->val.buffer_sz);
  124.  
  125.     ret = job_trove_keyval_read(
  126.         s_op->req->u.chdirent.fs_id,
  127.         s_op->req->u.chdirent.handle,
  128.         &s_op->key,
  129.         &s_op->val,
  130.         0,
  131.         NULL,
  132.         smcb,
  133.         0,
  134.         js_p,
  135.         &i,
  136.         server_job_context, s_op->req->hints);
  137.  
  138.     return ret;
  139. }
  140.  
  141. static PINT_sm_action chdirent_read_directory_entry(
  142.         struct PINT_smcb *smcb, job_status_s *js_p)
  143. {
  144.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  145.     int ret = -PVFS_EINVAL;
  146.     job_id_t j_id;
  147.  
  148.     gossip_debug(GOSSIP_SERVER_DEBUG,
  149.          "  reading from dirent handle = %llu, name = %s\n",
  150.          llu(s_op->u.chdirent.dirdata_handle),
  151.          s_op->req->u.chdirent.entry);
  152.  
  153.     s_op->key.buffer = s_op->req->u.chdirent.entry;
  154.     s_op->key.buffer_sz = strlen(s_op->req->u.chdirent.entry) + 1;
  155.     s_op->val.buffer = &s_op->u.chdirent.old_dirent_handle;
  156.     s_op->val.buffer_sz = sizeof(PVFS_handle);
  157.  
  158.     ret = job_trove_keyval_read(
  159.         s_op->req->u.chdirent.fs_id,
  160.         s_op->u.chdirent.dirdata_handle,
  161.         &s_op->key,
  162.         &s_op->val,
  163.         0,
  164.         NULL,
  165.         smcb,
  166.         0,
  167.         js_p,
  168.         &j_id,
  169.         server_job_context, s_op->req->hints);
  170.  
  171.     return ret;
  172. }
  173.  
  174. static PINT_sm_action chdirent_read_directory_entry_failure(
  175.         struct PINT_smcb *smcb, job_status_s *js_p)
  176. {
  177.     switch (js_p->error_code)
  178.     {
  179.     case -TROVE_ENOENT:
  180.         js_p->error_code = -PVFS_ENOENT;
  181.         break;
  182.     default:
  183.         gossip_err("chdirent_read_directory_entry_failure: "
  184.                        "unexpected error %d\n", js_p->error_code);
  185.         break;
  186.     }
  187.     return SM_ACTION_COMPLETE;
  188. }
  189.  
  190. static PINT_sm_action chdirent_change_directory_entry(
  191.         struct PINT_smcb *smcb, job_status_s *js_p)
  192. {
  193.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  194.     int ret = -PVFS_EINVAL;
  195.     job_id_t j_id;
  196.  
  197.     js_p->error_code = 0;
  198.  
  199.     s_op->u.chdirent.new_dirent_handle =
  200.         s_op->req->u.chdirent.new_dirent_handle;
  201.  
  202.     if (s_op->u.chdirent.old_dirent_handle ==
  203.         s_op->u.chdirent.new_dirent_handle)
  204.     {
  205.         /* FIXME: return an error since a dirent is
  206.            being changed to itself (?) */
  207.     }
  208.  
  209.     s_op->key.buffer = s_op->req->u.chdirent.entry;
  210.     s_op->key.buffer_sz = strlen(s_op->req->u.chdirent.entry) + 1;
  211.  
  212.     s_op->val.buffer = &s_op->u.chdirent.new_dirent_handle;
  213.     s_op->val.buffer_sz = sizeof(PVFS_handle);
  214.  
  215.     gossip_debug(GOSSIP_SERVER_DEBUG,
  216.                  "  changing dir entry for %s from handle value "
  217.                  "%llu to %llu\n", s_op->req->u.chdirent.entry,
  218.                  llu(s_op->u.chdirent.old_dirent_handle),
  219.                  llu(s_op->u.chdirent.new_dirent_handle));
  220.  
  221.     ret = job_trove_keyval_write(
  222.         s_op->req->u.chdirent.fs_id, s_op->u.chdirent.dirdata_handle,
  223.         &s_op->key, &s_op->val, 
  224.         TROVE_SYNC |
  225.         0,
  226.         NULL, smcb, 0, js_p, &j_id, server_job_context, s_op->req->hints);
  227.  
  228.     s_op->u.chdirent.dir_attr_update_required = 1;
  229.     return ret;
  230. }
  231.  
  232. static PINT_sm_action chdirent_check_for_req_dir_update(
  233.         struct PINT_smcb *smcb, job_status_s *js_p)
  234. {
  235.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  236.     if ((js_p->error_code == 0) &&
  237.         (s_op->u.chdirent.dir_attr_update_required))
  238.     {
  239.         js_p->error_code = UPDATE_DIR_ATTR_REQUIRED;
  240.     }
  241.     return SM_ACTION_COMPLETE;
  242. }
  243.  
  244. static PINT_sm_action chdirent_update_directory_attr(
  245.         struct PINT_smcb *smcb, job_status_s *js_p)
  246. {
  247.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  248.     int ret = -1;
  249.     job_id_t j_id;
  250.     PVFS_object_attr tmp_attr, *tmp_attr_ptr = &tmp_attr;
  251.     PVFS_object_attr *dspace_attr = NULL;
  252.     PVFS_ds_attributes *ds_attr = NULL;
  253.  
  254.     if (js_p->error_code != UPDATE_DIR_ATTR_REQUIRED)
  255.     {
  256.         PVFS_perror_gossip("previous keyval write failed",
  257.                            js_p->error_code);
  258.         return SM_ACTION_COMPLETE;
  259.     }
  260.  
  261.     memset(&tmp_attr, 0, sizeof(PVFS_object_attr));
  262.     dspace_attr = &s_op->attr;
  263.     dspace_attr->mask |= (PVFS_ATTR_COMMON_ATIME | PVFS_ATTR_COMMON_MTIME | PVFS_ATTR_COMMON_CTIME);
  264.  
  265.     PVFS_object_attr_overwrite_setable(tmp_attr_ptr, dspace_attr);
  266.     ds_attr = &(s_op->ds_attr);
  267.     PVFS_object_attr_to_ds_attr(tmp_attr_ptr, ds_attr);
  268.  
  269.     ret = job_trove_dspace_setattr(
  270.         s_op->req->u.chdirent.fs_id, s_op->req->u.chdirent.handle,
  271.         ds_attr, 
  272.         TROVE_SYNC |
  273.         0,
  274.         smcb, 0, js_p, &j_id, server_job_context, s_op->req->hints);
  275.  
  276.     return ret;
  277. }
  278.  
  279. static PINT_sm_action chdirent_change_directory_entry_failure(
  280.         struct PINT_smcb *smcb, job_status_s *js_p)
  281. {
  282.     assert(js_p->error_code != -TROVE_ENOENT);
  283.         
  284.     switch (js_p->error_code)
  285.     {
  286.     case -TROVE_ENOENT:
  287.         js_p->error_code = -PVFS_ENOENT;
  288.         break;
  289.     default:
  290.         break;
  291.     }
  292.     gossip_err("unexpected error %d\n", js_p->error_code);
  293.     return SM_ACTION_COMPLETE;
  294. }
  295.  
  296. static PINT_sm_action chdirent_setup_resp(
  297.         struct PINT_smcb *smcb, job_status_s *js_p)
  298. {
  299.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  300.     if (js_p->error_code == 0)
  301.     {
  302.     /* return original dirent handle in the response */
  303.     s_op->resp.u.chdirent.old_dirent_handle =
  304.             s_op->u.chdirent.old_dirent_handle;
  305.  
  306.     gossip_debug(GOSSIP_SERVER_DEBUG,
  307.              "  succeeded; returning handle %llu in response\n",
  308.              llu(s_op->resp.u.chdirent.old_dirent_handle));
  309.     }
  310.     else
  311.     {
  312.     gossip_debug(GOSSIP_SERVER_DEBUG, "  sending error response\n");
  313.     }
  314.     return SM_ACTION_COMPLETE;
  315. }
  316.  
  317. static PINT_sm_action chdirent_cleanup(
  318.         struct PINT_smcb *smcb, job_status_s *js_p)
  319. {
  320.     return (server_state_machine_complete(smcb));
  321. }
  322.  
  323. PINT_GET_OBJECT_REF_DEFINE(chdirent);
  324.  
  325. struct PINT_server_req_params pvfs2_chdirent_params =
  326. {
  327.     .string_name = "chdirent",
  328.     .perm = PINT_SERVER_CHECK_WRITE,
  329.     .access_type = PINT_server_req_modify,
  330.     .sched_policy = PINT_SERVER_REQ_SCHEDULE,
  331.     .get_object_ref = PINT_get_object_ref_chdirent,
  332.     .state_machine = &pvfs2_chdirent_sm
  333. };
  334.  
  335. /*
  336.  * Local variables:
  337.  *  mode: c
  338.  *  c-indent-level: 4
  339.  *  c-basic-offset: 4
  340.  * End:
  341.  *
  342.  * vim: ft=c ts=8 sts=4 sw=4 expandtab
  343.  */
  344.