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 / list-attr.sm < prev    next >
Text File  |  2010-09-02  |  9KB  |  310 lines

  1. /* 
  2.  * (C) 2001 Clemson University and The University of Chicago 
  3.  *
  4.  * See COPYING in top-level directory.
  5.  *
  6.  */
  7.  
  8. /* pvfs2_list_attr_sm
  9.  *
  10.  * This state machine handles incoming server listattr operations for a list of handles.  These
  11.  * are the operations sent by PVFS_sys_readdirplus().
  12.  *
  13.  */
  14.  
  15. #include <string.h>
  16. #include <assert.h>
  17.  
  18. #include "server-config.h"
  19. #include "pvfs2-server.h"
  20. #include "pvfs2-attr.h"
  21. #include "pvfs2-types.h"
  22. #include "pvfs2-types-debug.h"
  23. #include "pvfs2-util.h"
  24. #include "pint-util.h"
  25. #include "pvfs2-internal.h"
  26.  
  27. #define GETATTR 100
  28.  
  29.  
  30. %%
  31.  
  32.  
  33. machine pvfs2_list_attr_sm
  34. {
  35.     state prelude
  36.     {
  37.         jump pvfs2_prelude_sm;
  38.         success => read_basic_attrs;
  39.         default => final_response;
  40.     }
  41.  
  42.     state read_basic_attrs
  43.     {
  44.         run listattr_read_basic_attrs;
  45.         success => setup_getattr; 
  46.         default => final_response;
  47.     }
  48.     
  49.     state setup_getattr
  50.     {
  51.         pjmp listattr_setup_getattr
  52.         {
  53.             GETATTR => pvfs2_pjmp_get_attr_work_sm;
  54.         }
  55.         success => interpret_getattrs;
  56.         default => final_response;
  57.     }
  58.  
  59.     state interpret_getattrs
  60.     {
  61.         run listattr_interpret_getattrs;
  62.         default => final_response;
  63.     }
  64.  
  65.     state final_response
  66.     {
  67.         jump pvfs2_final_response_sm;
  68.         default => cleanup;
  69.     }
  70.  
  71.     state cleanup
  72.     {
  73.         run listattr_cleanup;
  74.         default => terminate;
  75.     }
  76. }
  77.  
  78. %%
  79.  
  80. static PINT_sm_action listattr_read_basic_attrs(
  81.     struct PINT_smcb *smcb, job_status_s *js_p)
  82. {    
  83.     int ret;
  84.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  85.     job_id_t tmp_id;
  86.  
  87.     s_op->u.listattr.ds_attr_a = (PVFS_ds_attributes *) 
  88.         calloc(s_op->req->u.listattr.nhandles * sizeof(PVFS_ds_attributes), 1);
  89.     if (s_op->u.listattr.ds_attr_a == NULL) {
  90.         js_p->error_code = -PVFS_ENOMEM;
  91.         return SM_ACTION_COMPLETE;
  92.     }
  93.  
  94.     s_op->u.listattr.errors = (PVFS_error *)
  95.         calloc(s_op->req->u.listattr.nhandles * sizeof(PVFS_error), 1);
  96.     if (s_op->u.listattr.errors == NULL) {
  97.         js_p->error_code = -PVFS_ENOMEM;
  98.         return SM_ACTION_COMPLETE;
  99.     }
  100.     s_op->u.listattr.attr_a = (PVFS_object_attr *)
  101.         calloc(s_op->req->u.listattr.nhandles * sizeof(PVFS_object_attr), 1);
  102.     if (s_op->u.listattr.attr_a == NULL) {
  103.         js_p->error_code = -PVFS_ENOMEM;
  104.         return SM_ACTION_COMPLETE;
  105.     }
  106.  
  107.     js_p->error_code = 0;
  108.     /* initiate retrieval of the attributes from the dspace */
  109.     ret = job_trove_dspace_getattr_list(
  110.             s_op->req->u.listattr.fs_id,
  111.             s_op->req->u.listattr.nhandles,
  112.             s_op->req->u.listattr.handles,
  113.             smcb,
  114.             s_op->u.listattr.errors,
  115.             s_op->u.listattr.ds_attr_a,
  116.             0,
  117.             js_p,
  118.             &tmp_id,
  119.             server_job_context,
  120.             s_op->req->hints);
  121.  
  122.     return ret;
  123. }
  124.  
  125.  
  126. static PINT_sm_action listattr_setup_getattr(
  127.     struct PINT_smcb *smcb, job_status_s *js_p)
  128. {    
  129.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  130.     struct PINT_server_op *getattr_op;
  131.     int ret;
  132.     int i;
  133.  
  134.     s_op->u.listattr.parallel_sms = 0;
  135.     js_p->error_code = 0;
  136.  
  137.     for(i=0; i<s_op->req->u.listattr.nhandles; i++)
  138.     {
  139.         if(s_op->u.listattr.errors[i])
  140.         {
  141.             gossip_debug(GOSSIP_SERVER_DEBUG, 
  142.                 "listattr: dspace_getattr_list failed to get attrs for handle: %llu\n", 
  143.                 llu(s_op->req->u.listattr.handles[i]));
  144.             /* skip nested machine for this handle */
  145.             continue;
  146.         }
  147.  
  148.         getattr_op = malloc(sizeof(*getattr_op));
  149.         if(!getattr_op)
  150.         {
  151.             s_op->u.listattr.errors[i] = -PVFS_ENOMEM;
  152.             gossip_debug(GOSSIP_SERVER_DEBUG, 
  153.                 "listattr: failed to setup nested sm for handle: %llu\n", 
  154.                 llu(s_op->req->u.listattr.handles[i]));
  155.             continue;
  156.         }
  157.         memset(getattr_op, 0, sizeof(*getattr_op));
  158.  
  159.         /* TODO: need a way to explicitly set the right inputs to the
  160.          * getattr nested sm.  This code block is very fragile.
  161.          */
  162.  
  163.         /* need attrs that the prelude would have read normally */
  164.         PVFS_ds_attr_to_object_attr(&s_op->u.listattr.ds_attr_a[i],
  165.             &getattr_op->attr);
  166.         getattr_op->attr.mask = PVFS_ATTR_COMMON_ALL;
  167.         getattr_op->ds_attr = s_op->u.listattr.ds_attr_a[i];
  168.         /* need a valid request structure for some generic features like access
  169.          * logging 
  170.          */
  171.         getattr_op->req = s_op->req;
  172.         /* need to fill in the input parameters to the getattr nested machine */
  173.         getattr_op->u.getattr.fs_id = s_op->req->u.listattr.fs_id;
  174.         getattr_op->u.getattr.handle = s_op->req->u.listattr.handles[i];
  175.         getattr_op->u.getattr.attrmask = s_op->req->u.listattr.attrmask;
  176.  
  177.         ret = PINT_sm_push_frame(smcb, GETATTR, getattr_op);
  178.         if(ret < 0)
  179.         {
  180.             s_op->u.listattr.errors[i] = -PVFS_ENOMEM;
  181.             gossip_debug(GOSSIP_SERVER_DEBUG, 
  182.                 "listattr: failed to setup nested sm for handle: %llu\n", 
  183.                 llu(s_op->req->u.listattr.handles[i]));
  184.             continue;
  185.         }
  186.  
  187.         s_op->u.listattr.parallel_sms++;
  188.     }
  189.  
  190.     gossip_debug(GOSSIP_SERVER_DEBUG, 
  191.         "listattr: set up %d parallel nested getattr machines.\n", 
  192.         s_op->u.listattr.parallel_sms);
  193.  
  194.     if(s_op->u.listattr.parallel_sms > 0)
  195.     {
  196.         js_p->error_code = 0;
  197.         return SM_ACTION_COMPLETE;
  198.     }
  199.     else
  200.     {
  201.         /* we didn't kick off any parallel machines.  Pick an error code and
  202.          * move along...
  203.          */
  204.         js_p->error_code = s_op->u.listattr.errors[0];
  205.         return SM_ACTION_COMPLETE;
  206.     }
  207. }
  208.  
  209. static PINT_sm_action listattr_interpret_getattrs(struct PINT_smcb *smcb, 
  210.     job_status_s *js_p)
  211. {    
  212.     struct PINT_server_op *getattr_op = NULL;
  213.     /* note: this gives us a pointer to the base frame (list_attr), 
  214.      * _not_ the getattr frames that were previously pushed.
  215.      */
  216.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  217.     int task_id;
  218.     int remaining;
  219.     PVFS_error tmp_err;
  220.     int i, j;
  221.  
  222.     assert(s_op);
  223.     assert(s_op->op == PVFS_SERV_LISTATTR);
  224.  
  225.     gossip_debug(GOSSIP_SERVER_DEBUG, 
  226.         "listattr: trying to interpret results from %d nested parallel getattr machines.\n", 
  227.         s_op->u.listattr.parallel_sms);
  228.  
  229.     /* gather results */
  230.     for(i=0; i<s_op->u.listattr.parallel_sms; i++)
  231.     {
  232.         getattr_op = PINT_sm_pop_frame(smcb, &task_id, &tmp_err, 
  233.             &remaining);
  234.         gossip_debug(GOSSIP_SERVER_DEBUG, "getattr_op is %s.\n",(getattr_op ? "okay" : "NULL"));
  235.         gossip_debug(GOSSIP_SERVER_DEBUG, "listattr: nested sm returned error code: %d\n", tmp_err);
  236.         gossip_debug(GOSSIP_SERVER_DEBUG, "s_op is %p \t getattr_op is %p",s_op,getattr_op );
  237.         /* match it up with the correct array entry */
  238.         for(j=0; j<s_op->req->u.listattr.nhandles; j++)
  239.         {
  240.             if(s_op->req->u.listattr.handles[j] == getattr_op->u.getattr.handle)
  241.             {
  242.                 s_op->u.listattr.attr_a[j] = getattr_op->resp.u.getattr.attr;
  243.                 s_op->u.listattr.errors[j] = tmp_err;
  244.                 free(getattr_op);
  245.                 break;
  246.             }
  247.         }
  248.     }
  249.  
  250.     /* if we reached this point, then we have a successful ack to send back;
  251.      * set remaining response fields
  252.      */
  253.     s_op->resp.u.listattr.attr = s_op->u.listattr.attr_a;
  254.     s_op->resp.u.listattr.error = s_op->u.listattr.errors;
  255.     s_op->resp.u.listattr.nhandles = s_op->req->u.listattr.nhandles;
  256.  
  257.     js_p->error_code = 0;
  258.     return SM_ACTION_COMPLETE;
  259. }
  260.  
  261. static PINT_sm_action listattr_cleanup(struct PINT_smcb *smcb, job_status_s *js_p)
  262. {
  263.     int i;
  264.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  265.  
  266.     if (s_op->u.listattr.attr_a)
  267.     {
  268.         for (i = 0; i < s_op->req->u.listattr.nhandles; i++) 
  269.         {
  270.             PINT_free_object_attr(&s_op->u.listattr.attr_a[i]);
  271.         }
  272.         free(s_op->u.listattr.attr_a);
  273.     }
  274.     if (s_op->u.listattr.ds_attr_a)
  275.         free(s_op->u.listattr.ds_attr_a);
  276.     if (s_op->u.listattr.errors)
  277.         free(s_op->u.listattr.errors);
  278.  
  279.     return(server_state_machine_complete(smcb));
  280. }
  281.  
  282. static inline int PINT_get_object_ref_listattr(
  283.     struct PVFS_server_req *req, PVFS_fs_id *fs_id, PVFS_handle *handle)
  284. {
  285.     *fs_id = req->u.listattr.fs_id;
  286.     *handle = PVFS_HANDLE_NULL;
  287.     return 0;
  288. };
  289.  
  290. struct PINT_server_req_params pvfs2_list_attr_params =
  291. {
  292.     .string_name = "list_attr",
  293.     .perm = PINT_SERVER_CHECK_NONE,
  294.     .access_type = PINT_server_req_readonly,
  295.     .sched_policy = PINT_SERVER_REQ_SCHEDULE,
  296.     .get_object_ref = PINT_get_object_ref_listattr,
  297.     .state_machine = &pvfs2_list_attr_sm
  298. };
  299.  
  300. /*
  301.  * Local variables:
  302.  *  mode: c
  303.  *  c-indent-level: 4
  304.  *  c-basic-offset: 4
  305.  * End:
  306.  *
  307.  * vim: ft=c ts=8 sts=4 sw=4 expandtab
  308.  */
  309.  
  310.