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-eattr.sm < prev    next >
Text File  |  2011-02-25  |  8KB  |  289 lines

  1. /* 
  2.  * (C) 2001 Clemson University and The University of Chicago 
  3.  *
  4.  * See COPYING in top-level directory.
  5.  */
  6.  
  7. /* pvfs2_list_eattr_sm
  8.  *
  9.  * This state machine handles incoming server listxattr operations.  These
  10.  * are the operations sent by PVFS_sys_listeattr() among others.
  11.  *
  12.  * The pvfs2_prelude_sm is responsible for reading the actual metadata
  13.  * to begin with, because it does this as part of the permission checking
  14.  * process.
  15.  */
  16.  
  17. #include <string.h>
  18. #include <assert.h>
  19.  
  20. #include "server-config.h"
  21. #include "pvfs2-server.h"
  22. #include "pvfs2-attr.h"
  23. #include "pvfs2-types.h"
  24. #include "pvfs2-util.h"
  25. #include "pint-util.h"
  26. #include "pint-eattr.h"
  27.  
  28. %%
  29.  
  30. machine pvfs2_list_eattr_sm
  31. {
  32.     state prelude
  33.     {
  34.         jump pvfs2_prelude_sm;
  35.         success => setup_resp;
  36.         default => final_response;
  37.     }
  38.  
  39.     state setup_resp
  40.     {
  41.         run listeattr_setup_resp;
  42.         success => list_eattrib;
  43.         default => final_response;
  44.     }
  45.  
  46.     state list_eattrib
  47.     {
  48.         run listeattr_list_eattrib;
  49.         default => check_resp;
  50.     }
  51.  
  52.     state check_resp
  53.     {
  54.         run listeattr_check_resp;
  55.         default => final_response;
  56.     }
  57.  
  58.     state final_response
  59.     {
  60.         jump pvfs2_final_response_sm;
  61.         default => cleanup;
  62.     }
  63.  
  64.     state cleanup
  65.     {
  66.         run listeattr_cleanup;
  67.         default => terminate;
  68.     }
  69. }
  70.  
  71. %%
  72.  
  73. /*
  74.  * listeattr_setup_resp()
  75.  * Set up the response - allocate needed resources
  76.  */
  77. static PINT_sm_action listeattr_setup_resp(
  78.         struct PINT_smcb *smcb, job_status_s *js_p)
  79. {
  80.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  81.     int i, tsz;
  82.     gossip_debug(GOSSIP_LISTEATTR_DEBUG, "listeattr requesting %d keys\n",
  83.             s_op->req->u.listeattr.nkey);
  84.  
  85.     js_p->error_code = 0;
  86.  
  87.     /* ensure not too many keys were requested */
  88.     if( s_op->req->u.listeattr.nkey > PVFS_MAX_XATTR_LISTLEN )
  89.     {
  90.         js_p->error_code = -PVFS_EINVAL;
  91.         return SM_ACTION_COMPLETE;
  92.     }
  93.  
  94.     /* enforce that no key size be larger than PVFS_MAX_XATTR_NAMELEN.
  95.      * Otherwise, when a blind memcpy happens inside dbpf based on the key 
  96.      * size we won't over run our fixed length buffer. fixed buffer size is: 
  97.      * PVFS_NAME_MAX ==  DBPF_MAX_KEY_LENGTH == PVFS_MAX_XATTR_NAMELEN */
  98.     for( i = 0; i < s_op->req->u.listeattr.nkey; i++)
  99.     {
  100.         if( s_op->req->u.listeattr.keysz[i] > PVFS_MAX_XATTR_NAMELEN )
  101.         {
  102.              gossip_debug(GOSSIP_LISTEATTR_DEBUG, "%s: requested key %d "
  103.                           "size of %ld is greater than maximum of %d\n",
  104.                           __func__, i, (int64_t)s_op->req->u.listeattr.keysz[i],
  105.                           PVFS_MAX_XATTR_NAMELEN );
  106.             js_p->error_code = -PVFS_EINVAL;
  107.             return SM_ACTION_COMPLETE;
  108.         }
  109.     }
  110.  
  111.     s_op->resp.u.listeattr.key =
  112.         malloc(s_op->req->u.listeattr.nkey * sizeof(PVFS_ds_keyval));
  113.     if (!s_op->resp.u.listeattr.key)
  114.     {
  115.         js_p->error_code = -PVFS_ENOMEM;
  116.         return SM_ACTION_COMPLETE;
  117.     }
  118.  
  119.     s_op->resp.u.listeattr.nkey = s_op->req->u.listeattr.nkey;
  120.  
  121.     for (i = 0, tsz = 0; i < s_op->req->u.listeattr.nkey; i++)
  122.     {
  123.         tsz += s_op->req->u.listeattr.keysz[i];
  124.     }
  125.     s_op->u.eattr.buffer = malloc(tsz);
  126.     if (!s_op->u.eattr.buffer)
  127.     {
  128.         s_op->resp.u.listeattr.nkey = 0;
  129.         free (s_op->resp.u.listeattr.key);
  130.         js_p->error_code = -PVFS_ENOMEM;
  131.         return SM_ACTION_COMPLETE;
  132.     }
  133.     gossip_debug(GOSSIP_LISTEATTR_DEBUG,"listeattr buffer size %d bytes\n",
  134.             tsz);
  135.     for (i = 0, tsz = 0; i < s_op->req->u.listeattr.nkey; i++)
  136.     {
  137.         s_op->resp.u.listeattr.key[i].buffer_sz =
  138.             s_op->req->u.listeattr.keysz[i];
  139.         s_op->resp.u.listeattr.key[i].buffer =
  140.             (char *)s_op->u.eattr.buffer + tsz;
  141.         tsz += s_op->req->u.listeattr.keysz[i];
  142.     }
  143.     return SM_ACTION_COMPLETE;
  144. }
  145.  
  146. /*
  147.  * listeattr_list_eattrib()
  148.  * Here is where the eattrib get listed.
  149.  */
  150. static PINT_sm_action listeattr_list_eattrib(
  151.         struct PINT_smcb *smcb, job_status_s *js_p)
  152. {
  153.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  154.     int ret = -PVFS_EINVAL;
  155.     job_id_t i;
  156.  
  157.     js_p->error_code = 0;
  158.  
  159.     ret = job_trove_keyval_iterate_keys(
  160.         s_op->req->u.listeattr.fs_id,
  161.         s_op->req->u.listeattr.handle,
  162.         s_op->req->u.listeattr.token,
  163.         s_op->resp.u.listeattr.key,
  164.         s_op->req->u.listeattr.nkey,
  165.         0,
  166.         NULL,
  167.         smcb,
  168.         0,
  169.         js_p,
  170.         &i,
  171.         server_job_context, s_op->req->hints);
  172.  
  173.     return ret;
  174. }
  175.  
  176. #if 0
  177. static void print_string(char *buffer, size_t length)
  178. {
  179.     int i;
  180.     if (length == 0 || buffer == NULL)
  181.     {
  182.         return;
  183.     }
  184.     for (i = 0; i < length; i++)
  185.     {
  186.         printf("%c", buffer[i]);
  187.     }
  188.     printf("\n");
  189.     return;
  190. }
  191. #endif
  192.  
  193. /* listeattr_check_resp()
  194.  *
  195.  * checks what attributes we found, handles errors, filters for appropriate
  196.  * extended attribute name spaces
  197.  *
  198.  * NOTE: all attributes should fall into one of the name spaces defined in 
  199.  * the PINT_eattr_namespaces array.  If we find a key that does not, then we
  200.  * will translate it so that it appears in the "system.pvfs2." name
  201.  * space on the client side.
  202.  */
  203. static PINT_sm_action listeattr_check_resp(
  204.         struct PINT_smcb *smcb, job_status_s *js_p)
  205. {
  206.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  207.     int num_found = 0;
  208.     int i = 0;
  209.  
  210.     /* Nothing was requested? then fill token to hold the max available keys */
  211.     if (s_op->resp.u.listeattr.nkey == 0)
  212.     {
  213.         s_op->resp.u.listeattr.token = js_p->count;
  214.         js_p->error_code = 0;
  215.         return SM_ACTION_COMPLETE;
  216.     }
  217.  
  218.     /* how many entries did we find that we can process? */
  219.     num_found = js_p->count;
  220.     if(num_found > s_op->resp.u.listeattr.nkey)
  221.     {
  222.         num_found = s_op->resp.u.listeattr.nkey;
  223.     }
  224.  
  225.     s_op->resp.u.listeattr.token = js_p->position;
  226.     s_op->resp.u.listeattr.nkey = num_found;
  227.  
  228.     if(num_found == 0)
  229.     {
  230.         /* there aren't any extended attr's; go ahead and return */
  231.         js_p->error_code = 0;
  232.         return SM_ACTION_COMPLETE;
  233.     }
  234.  
  235.     /* iterate through the keys that we found */
  236.     for(i=0; i<num_found; i++)
  237.     {
  238.         js_p->error_code = PINT_eattr_list_access(
  239.             &s_op->resp.u.listeattr.key[i],
  240.             NULL);
  241.         if(js_p->error_code != 0)
  242.         {
  243.             return SM_ACTION_COMPLETE;
  244.         }
  245.  
  246.         s_op->resp.u.listeattr.key[i].buffer_sz =
  247.             s_op->resp.u.listeattr.key[i].read_sz;
  248.     }
  249.  
  250.     js_p->error_code = 0;
  251.     return SM_ACTION_COMPLETE;
  252. }
  253.  
  254. /* listeattr_cleanup()
  255.  * free resources alloc'd by state machine
  256.  */
  257. static PINT_sm_action listeattr_cleanup(
  258.         struct PINT_smcb *smcb, job_status_s *js_p)
  259. {
  260.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  261.     if (s_op->resp.u.listeattr.key)
  262.         free(s_op->resp.u.listeattr.key);
  263.     if (s_op->u.eattr.buffer)
  264.         free(s_op->u.eattr.buffer);
  265.     return(server_state_machine_complete(smcb));
  266. }
  267.  
  268. PINT_GET_OBJECT_REF_DEFINE(listeattr);
  269.  
  270. struct PINT_server_req_params pvfs2_list_eattr_params =
  271. {
  272.     .string_name = "listeattr",
  273.     .perm = PINT_SERVER_CHECK_ATTR,
  274.     .sched_policy = PINT_SERVER_REQ_SCHEDULE,
  275.     .get_object_ref = PINT_get_object_ref_listeattr,
  276.     .state_machine = &pvfs2_list_eattr_sm
  277. };
  278.  
  279. /*
  280.  * Local variables:
  281.  *  mode: c
  282.  *  c-indent-level: 4
  283.  *  c-basic-offset: 4
  284.  * End:
  285.  *
  286.  * vim: ft=c ts=8 sts=4 sw=4 expandtab
  287.  */
  288.  
  289.