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 / client / sysint / sys-list-eattr.sm < prev    next >
Text File  |  2011-02-25  |  9KB  |  322 lines

  1. /* 
  2.  * (C) 2003 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. #include <unistd.h>
  10.  
  11. #include "client-state-machine.h"
  12. #include "pvfs2-debug.h"
  13. #include "pvfs2-util.h"
  14. #include "job.h"
  15. #include "gossip.h"
  16. #include "str-utils.h"
  17. #include "pint-cached-config.h"
  18. #include "PINT-reqproto-encode.h"
  19.  
  20. extern job_context_id pint_client_sm_context;
  21.  
  22. static int list_eattr_comp_fn(
  23.     void *v_p,
  24.     struct PVFS_server_resp *resp_p,
  25.     int i);
  26.  
  27. %%
  28.  
  29. machine pvfs2_client_list_eattr_sm
  30. {
  31.     state setup_msgpair
  32.     {
  33.         run list_eattr_setup_msgpair;
  34.         success => xfer_msgpair;
  35.         default => cleanup;
  36.     }
  37.  
  38.     state xfer_msgpair
  39.     {
  40.         jump pvfs2_msgpairarray_sm;
  41.         default => cleanup;
  42.     }
  43.  
  44.     state cleanup
  45.     {
  46.         run list_eattr_cleanup;
  47.         default => terminate;
  48.     }
  49. }
  50.  
  51. %%
  52.  
  53. PVFS_error PVFS_isys_listeattr(
  54.         PVFS_object_ref ref,
  55.         PVFS_ds_position token,
  56.         int32_t nkey,
  57.         const PVFS_credentials *credentials,
  58.         PVFS_sysresp_listeattr *resp_p,
  59.         PVFS_sys_op_id *op_id,
  60.         PVFS_hint hints,
  61.         void *user_ptr)
  62. {
  63.     int ret = -PVFS_EINVAL;
  64.     int i = 0;
  65.     PINT_smcb *smcb = NULL;
  66.     PINT_client_sm *sm_p = NULL;
  67.  
  68.     gossip_debug(GOSSIP_CLIENT_DEBUG,
  69.                  "PINT_isys_listeattr entered\n");
  70.  
  71.     if ((ref.handle == PVFS_HANDLE_NULL) ||
  72.        (ref.fs_id == PVFS_FS_ID_NULL) || (resp_p == NULL))
  73.     {
  74.         gossip_err("invalid (NULL) required argument\n");
  75.     return ret;
  76.     }
  77.  
  78.     /* the resp key array is used to determine how much we allocate,
  79.      * let's enfore the max key buffer of PVFS_MAX_XATTR_NAMELEN
  80.      */
  81.     if( resp_p->nkey > PVFS_REQ_LIMIT_EATTR_LIST )
  82.     {
  83.         gossip_debug(GOSSIP_CLIENT_DEBUG, "%s: requested number of keys, %d, "
  84.                      " is larger than the maximum of %d\n", __func__,
  85.                      resp_p->nkey, PVFS_REQ_LIMIT_EATTR_LIST );
  86.         return ret; 
  87.     }
  88.  
  89.     for( i=0; i < resp_p->nkey; i++ )
  90.     {
  91.         if( resp_p->key_array[i].buffer_sz > PVFS_MAX_XATTR_NAMELEN )
  92.         {
  93.             gossip_debug(GOSSIP_CLIENT_DEBUG, "%s: key_array item %d "
  94.                          "buffer_sz of %d is too big (max value %d)\n",
  95.                          __func__, i, resp_p->key_array[i].buffer_sz,
  96.                          PVFS_MAX_XATTR_NAMELEN);
  97.             return ret;
  98.         }
  99.     }
  100.  
  101.     PINT_smcb_alloc(&smcb, PVFS_SYS_LISTEATTR,
  102.              sizeof(struct PINT_client_sm),
  103.              client_op_state_get_machine,
  104.              client_state_machine_terminate,
  105.              pint_client_sm_context);
  106.     if (smcb == NULL)
  107.     {
  108.         return -PVFS_ENOMEM;
  109.     }
  110.     sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  111.  
  112.     PINT_init_msgarray_params(sm_p, ref.fs_id);
  113.     PINT_init_sysint_credentials(sm_p->cred_p, credentials);
  114.     sm_p->u.listeattr.nkey = nkey;
  115.     sm_p->u.listeattr.resp_p = resp_p;
  116.     sm_p->u.listeattr.pos_token = token;
  117.     sm_p->error_code = 0;
  118.     sm_p->object_ref = ref;
  119.     PVFS_hint_copy(hints, &sm_p->hints);
  120.  
  121.     return PINT_client_state_machine_post(
  122.             smcb,  op_id, user_ptr);
  123. }
  124.  
  125. PVFS_error PVFS_sys_listeattr(
  126.         PVFS_object_ref ref,
  127.         PVFS_ds_position token,
  128.         int32_t nkey,
  129.         const PVFS_credentials *credentials,
  130.         PVFS_sysresp_listeattr *resp_p,
  131.         PVFS_hint hints)
  132. {
  133.     PVFS_error ret = -PVFS_EINVAL, error = 0;
  134.     PVFS_sys_op_id op_id;
  135.  
  136.     gossip_debug(GOSSIP_CLIENT_DEBUG, "PVFS_sys_listeattr entered\n");
  137.  
  138.     ret = PVFS_isys_listeattr(ref, token, nkey, credentials,
  139.             resp_p, &op_id, hints, NULL);
  140.  
  141.     if (ret)
  142.     {
  143.         PVFS_perror_gossip("PVFS_isys_listeattr call", ret);
  144.         error = ret;
  145.     }
  146.     else
  147.     {
  148.         ret = PVFS_sys_wait(op_id, "listeattr", &error);
  149.         if (ret)
  150.         {
  151.              PVFS_perror_gossip("PVFS_sys_wait call", ret);
  152.              error = ret;
  153.         }
  154.     }
  155.  
  156.     PINT_sys_release(op_id);
  157.     return error;
  158. }
  159.  
  160. static PINT_sm_action list_eattr_setup_msgpair(
  161.         struct PINT_smcb *smcb, job_status_s *js_p)
  162. {
  163.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  164.     int ret = -PVFS_EINVAL;
  165.     int i;
  166.     PINT_sm_msgpair_state *msg_p;
  167.  
  168.     gossip_debug(GOSSIP_CLIENT_DEBUG,
  169.         "list_eattr state: list_eattr_setup_msgpair\n");
  170.  
  171.     /* this will be the array of key buffer sizes */
  172.     sm_p->u.listeattr.size_array =
  173.              (PVFS_size *)malloc(sm_p->u.listeattr.nkey *
  174.                                  sizeof (PVFS_size));
  175.  
  176.     for (i = 0; i < sm_p->u.listeattr.nkey; i++)
  177.         sm_p->u.listeattr.size_array[i] =
  178.             sm_p->u.listeattr.resp_p->key_array[i].buffer_sz;
  179.  
  180.     PINT_msgpair_init(&sm_p->msgarray_op);
  181.     msg_p = &sm_p->msgarray_op.msgpair;
  182.  
  183.     PINT_SERVREQ_LISTEATTR_FILL(
  184.             msg_p->req,
  185.             (*sm_p->cred_p),
  186.             sm_p->object_ref.fs_id,
  187.             sm_p->object_ref.handle,
  188.             sm_p->u.listeattr.pos_token,
  189.             sm_p->u.listeattr.nkey,
  190.             sm_p->u.listeattr.size_array,
  191.             sm_p->hints
  192.             );
  193.  
  194.     msg_p->fs_id = sm_p->object_ref.fs_id;
  195.     msg_p->handle = sm_p->object_ref.handle;
  196.     msg_p->retry_flag = PVFS_MSGPAIR_RETRY;
  197.     msg_p->comp_fn = list_eattr_comp_fn;
  198.  
  199.     ret = PINT_cached_config_map_to_server(
  200.             &msg_p->svr_addr,
  201.             msg_p->handle,
  202.             msg_p->fs_id);
  203.  
  204.     if (ret)
  205.     {
  206.         gossip_err("Failed to map meta server address\n");
  207.         js_p->error_code = 0;
  208.     }
  209.  
  210.     PINT_sm_push_frame(smcb, 0, &sm_p->msgarray_op);
  211.     return SM_ACTION_COMPLETE;
  212. }
  213.  
  214. static PINT_sm_action list_eattr_cleanup(
  215.         struct PINT_smcb *smcb, job_status_s *js_p)
  216. {
  217.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  218.     gossip_debug(GOSSIP_CLIENT_DEBUG,
  219.         "list_eattr state: list_eattr_cleanup\n");
  220.     /* free the array malloc'd above */
  221.     free(sm_p->u.listeattr.size_array);
  222.     sm_p->error_code  = js_p->error_code;
  223.  
  224.     PINT_SET_OP_COMPLETE;
  225.     return SM_ACTION_TERMINATE;
  226. }
  227.  
  228. static int list_eattr_comp_fn(
  229.     void *v_p,
  230.     struct PVFS_server_resp *resp_p,
  231.     int i)
  232. {
  233.     int ret = 0;
  234.     PINT_smcb *smcb = v_p;
  235.     PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_MSGPAIR_PARENT_SM);
  236.  
  237.     gossip_debug(GOSSIP_CLIENT_DEBUG,
  238.         "list_eattr completion fn: list_eattr_comp_fn\n");
  239.  
  240.     /* only posted one msgpair */
  241.     assert(i==0);
  242.  
  243.     if (resp_p->status != 0)
  244.     {
  245.         return resp_p->status;
  246.     }
  247.     if (sm_p->msgarray_op.msgarray[i].op_status != 0)
  248.     {
  249.         return sm_p->msgarray_op.msgarray[i].op_status;
  250.     }
  251.     sm_p->u.listeattr.resp_p->token = resp_p->u.listeattr.token;
  252.     sm_p->u.listeattr.resp_p->nkey  = resp_p->u.listeattr.nkey;
  253.  
  254.     /* If we requested more than 0 keys */
  255.     if (sm_p->u.listeattr.nkey)
  256.     {
  257.         gossip_debug(GOSSIP_LISTEATTR_DEBUG,"listeattr returned %d instead of %d keys\n",
  258.                 sm_p->u.listeattr.resp_p->nkey, sm_p->u.listeattr.nkey);
  259.     }
  260.     /* Else we use the token value as the total number of keys */
  261.     else
  262.     {
  263.         gossip_debug(GOSSIP_LISTEATTR_DEBUG,"listeattr returned %d keys\n",
  264.                 sm_p->u.listeattr.resp_p->nkey);
  265.         /* Copy the token and reset it */
  266.         sm_p->u.listeattr.resp_p->nkey = sm_p->u.listeattr.resp_p->token;
  267.         sm_p->u.listeattr.resp_p->token = PVFS_ITERATE_START;
  268.         return 0;
  269.     }
  270.     if (sm_p->u.listeattr.resp_p->nkey > 0)
  271.     {
  272.         int k;
  273.         if (!resp_p->u.listeattr.key)
  274.         {
  275.             gossip_err("Successful call returned NULL value list\n");
  276.             return -1;
  277.         }
  278.         for (k = 0; k < sm_p->u.listeattr.resp_p->nkey; k++)
  279.         {
  280.             gossip_debug(GOSSIP_LISTEATTR_DEBUG,"resp_read_sz = %d\n",
  281.                     resp_p->u.listeattr.key[k].read_sz);
  282.             gossip_debug(GOSSIP_LISTEATTR_DEBUG,"resp_buff_sz = %d\n",
  283.                     resp_p->u.listeattr.key[k].buffer_sz);
  284.             gossip_debug(GOSSIP_LISTEATTR_DEBUG,"sm_buff_sz = %d\n",
  285.                     sm_p->u.listeattr.resp_p->key_array[k].buffer_sz);
  286.             gossip_debug(GOSSIP_LISTEATTR_DEBUG,"resp_buff_ = %s\n",
  287.                     (char *)resp_p->u.listeattr.key[k].buffer);
  288.             /* put the actual read_sz in its place */
  289.             sm_p->u.listeattr.resp_p->key_array[k].read_sz =
  290.                     resp_p->u.listeattr.key[k].buffer_sz;
  291.             /* check for too big a return message */
  292.             if (sm_p->u.listeattr.resp_p->key_array[k].read_sz <=
  293.                     sm_p->u.listeattr.resp_p->key_array[k].buffer_sz)
  294.             {
  295.                 gossip_debug(GOSSIP_LISTEATTR_DEBUG,"copying\n");
  296.                 memcpy(sm_p->u.listeattr.resp_p->key_array[k].buffer,
  297.                         resp_p->u.listeattr.key[k].buffer,
  298.                         sm_p->u.listeattr.resp_p->key_array[k].read_sz);
  299.             }
  300.             else /* oops, error! returned too much data */
  301.             {
  302.                 gossip_debug(GOSSIP_LISTEATTR_DEBUG,"clearing on error\n");
  303.                 memset(sm_p->u.listeattr.resp_p->key_array[k].buffer,0,
  304.                         sm_p->u.listeattr.resp_p->key_array[k].buffer_sz);
  305.                 /* record an error, but keep going */
  306.                 ret = -PVFS_EMSGSIZE;
  307.             }
  308.         }
  309.     }
  310.     return ret;
  311. }
  312.  
  313. /*
  314.  * Local variables:
  315.  *  mode: c
  316.  *  c-indent-level: 4
  317.  *  c-basic-offset: 4
  318.  * End:
  319.  *
  320.  * vim: ft=c ts=8 sts=4 sw=4 expandtab
  321.  */
  322.