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 / proto / PINT-le-bytefield.c < prev    next >
C/C++ Source or Header  |  2010-04-30  |  37KB  |  1,142 lines

  1. /*
  2.  * (C) 2001 Clemson University and The University of Chicago
  3.  * (C) 2003 Pete Wyckoff, Ohio Supercomputer Center <pw@osc.edu>
  4.  *
  5.  * See COPYING in top-level directory.
  6.  */
  7.  
  8. #include <stdlib.h>
  9. #include <errno.h>
  10. #include <string.h>
  11. #include <assert.h>
  12.  
  13. #define __PINT_REQPROTO_ENCODE_FUNCS_C  /* trigger actual definitions */
  14. #include "endecode-funcs.h"
  15. #include "bmi.h"
  16. #include "bmi-byteswap.h"
  17. #include "gossip.h"
  18. #include "pvfs2-debug.h"
  19. #include "pvfs2-dist-basic.h"
  20. #include "pvfs2-types.h"
  21. #include "pvfs2-req-proto.h"
  22. #include "PINT-reqproto-encode.h"
  23. #include "PINT-reqproto-module.h"
  24. #include "src/io/description/pint-request.h"  /* for PINT_Request */
  25. #include "src/io/description/pint-distribution.h"  /* for PINT_dist_lookup */
  26. #include "pvfs2-internal.h"
  27. #include "pint-hint.h"
  28.  
  29. /* defined later */
  30. static int check_req_size(struct PVFS_server_req *req);
  31. static int check_resp_size(struct PVFS_server_resp *resp);
  32.  
  33. static int initializing_sizes = 0;
  34.  
  35. /* an array of structs for storing precalculated maximum encoding sizes
  36.  * for each type of server operation 
  37.  */
  38. static struct {
  39.     int req;
  40.     int resp;
  41. } *max_size_array = NULL;
  42.  
  43. /* lebf_initialize()
  44.  *
  45.  * initializes the encoder module, calculates max sizes of each request type 
  46.  * in advance
  47.  *
  48.  * no return value
  49.  */
  50. static void lebf_initialize(void)
  51. {
  52.     struct PVFS_server_req req = {0};
  53.     struct PVFS_server_resp resp = {0};
  54.     enum PVFS_server_op op_type;
  55.     int reqsize, respsize;
  56.     int noreq;
  57.     PINT_dist tmp_dist;
  58.     PINT_Request tmp_req;
  59.     char *tmp_name = strdup("foo");
  60.     const int init_big_size = 1024 * 1024;
  61.     int i;
  62.  
  63.     gossip_debug(GOSSIP_ENDECODE_DEBUG,"lebf_initialize\n");
  64.  
  65.     max_size_array = malloc(PVFS_SERV_NUM_OPS * sizeof(*max_size_array));
  66.     if (max_size_array == NULL)
  67.         return;
  68.  
  69.     /*
  70.      * Some messages have extra structures, and even indeterminate sizes
  71.      * which are hand-calculated here.  Also some fields must be initialized
  72.      * for encoding to work properly.
  73.      */
  74.     memset(&tmp_dist, 0, sizeof(tmp_dist));
  75.     tmp_dist.dist_name = strdup(PVFS_DIST_BASIC_NAME);
  76.     if (PINT_dist_lookup(&tmp_dist)) {
  77.     gossip_err("%s: dist %s does not exist?!?\n",
  78.       __func__, tmp_dist.dist_name);
  79.     exit(1);
  80.     }
  81.     memset(&tmp_req, 0, sizeof(tmp_req));
  82.  
  83.     initializing_sizes = 1;
  84.  
  85.     /* set number of hints in request to the max */
  86.     for(i = 0; i < PVFS_HINT_MAX; ++i)
  87.     {
  88.         char name[PVFS_HINT_MAX_NAME_LENGTH] = {0};
  89.         char val[PVFS_HINT_MAX_LENGTH] = {0};
  90.         PVFS_hint_add(&req.hints, name, PVFS_HINT_MAX_LENGTH, val);
  91.     }
  92.  
  93.     for (op_type=0; op_type<PVFS_SERV_NUM_OPS; op_type++) {
  94.         memset(&req.u, 0, sizeof(req.u));
  95.     req.op = resp.op = op_type;
  96.     reqsize = 0;
  97.     respsize = 0;
  98.     noreq = 0;
  99.     switch (op_type) {
  100.         case PVFS_SERV_INVALID:
  101.         case PVFS_SERV_PERF_UPDATE:
  102.         case PVFS_SERV_PRECREATE_POOL_REFILLER:
  103.         case PVFS_SERV_JOB_TIMER:
  104.         /* never used, skip initialization */
  105.         continue;
  106.         case PVFS_SERV_GETCONFIG:
  107.         resp.u.getconfig.fs_config_buf = tmp_name;
  108.         respsize = extra_size_PVFS_servresp_getconfig;
  109.         break;
  110.         case PVFS_SERV_LOOKUP_PATH:
  111.         req.u.lookup_path.path = "";
  112.         resp.u.lookup_path.handle_count = 0;
  113.         resp.u.lookup_path.attr_count = 0;
  114.         reqsize = extra_size_PVFS_servreq_lookup_path;
  115.         respsize = extra_size_PVFS_servresp_lookup_path;
  116.         break;
  117.         case PVFS_SERV_BATCH_CREATE:
  118.         /* can request a range of handles */
  119.         req.u.batch_create.handle_extent_array.extent_count = 0;
  120.         req.u.batch_create.object_count = 0;
  121.         resp.u.batch_create.handle_count = 0;
  122.         reqsize = extra_size_PVFS_servreq_batch_create;
  123.         respsize = extra_size_PVFS_servresp_batch_create;
  124.         break;
  125.         case PVFS_SERV_CREATE:
  126.         /* can request a range of handles */
  127.         reqsize = extra_size_PVFS_servreq_create;
  128.                 respsize = extra_size_PVFS_servresp_create;
  129.                 break;
  130.             case PVFS_SERV_MIRROR:
  131.                  req.u.mirror.dist = &tmp_dist;
  132.                  req.u.mirror.dst_count = 0;
  133.                  reqsize = extra_size_PVFS_servreq_mirror;
  134.                  respsize = extra_size_PVFS_servresp_mirror;
  135.                  break;
  136.             case PVFS_SERV_IMM_COPIES:
  137.                  break;
  138.         case PVFS_SERV_REMOVE:
  139.         /* nothing special, let normal encoding work */
  140.         break;
  141.         case PVFS_SERV_BATCH_REMOVE:
  142.         req.u.batch_remove.handles = NULL;
  143.         req.u.batch_remove.handle_count = 0;
  144.         reqsize = extra_size_PVFS_servreq_batch_remove;
  145.         break;
  146.         case PVFS_SERV_MGMT_REMOVE_OBJECT:
  147.         /* nothing special, let normal encoding work */
  148.         break;
  149.         case PVFS_SERV_MGMT_REMOVE_DIRENT:
  150.         req.u.mgmt_remove_dirent.entry = tmp_name;
  151.         reqsize = extra_size_PVFS_servreq_mgmt_remove_dirent;
  152.         break;
  153.         case PVFS_SERV_TREE_REMOVE:
  154.         req.u.tree_remove.handle_array = NULL;
  155.         req.u.tree_remove.num_data_files = 0;
  156.         reqsize = extra_size_PVFS_servreq_tree_remove;
  157.         break;
  158.         case PVFS_SERV_IO:
  159.         req.u.io.io_dist = &tmp_dist;
  160.         req.u.io.file_req = &tmp_req;
  161.         reqsize = extra_size_PVFS_servreq_io;
  162.         break;
  163.             case PVFS_SERV_SMALL_IO:
  164.                 req.u.small_io.dist = &tmp_dist;
  165.                 req.u.small_io.file_req = &tmp_req;
  166.                 reqsize = extra_size_PVFS_servreq_small_io;
  167.                 respsize = extra_size_PVFS_servresp_small_io;
  168.                 break;
  169.         case PVFS_SERV_GETATTR:
  170.         resp.u.getattr.attr.mask = 0;
  171.         respsize = extra_size_PVFS_servresp_getattr;
  172.         break;
  173.         case PVFS_SERV_UNSTUFF:
  174.         resp.u.unstuff.attr.mask = 0;
  175.         respsize = extra_size_PVFS_servresp_unstuff;
  176.         break;
  177.         case PVFS_SERV_SETATTR:
  178.         req.u.setattr.attr.mask = 0;
  179.         reqsize = extra_size_PVFS_servreq_setattr;
  180.         break;
  181.         case PVFS_SERV_CRDIRENT:
  182.         req.u.crdirent.name = tmp_name;
  183.         reqsize = extra_size_PVFS_servreq_crdirent;
  184.         break;
  185.         case PVFS_SERV_RMDIRENT:
  186.         req.u.rmdirent.entry = tmp_name;
  187.         reqsize = extra_size_PVFS_servreq_rmdirent;
  188.         break;
  189.         case PVFS_SERV_CHDIRENT:
  190.         req.u.chdirent.entry = tmp_name;
  191.         reqsize = extra_size_PVFS_servreq_chdirent;
  192.         break;
  193.         case PVFS_SERV_TRUNCATE:
  194.         /* nothing special */
  195.         break;
  196.         case PVFS_SERV_MKDIR:
  197.         req.u.mkdir.handle_extent_array.extent_count = 0;
  198.         req.u.mkdir.attr.mask = 0;
  199.         reqsize = extra_size_PVFS_servreq_mkdir;
  200.         break;
  201.         case PVFS_SERV_READDIR:
  202.         resp.u.readdir.directory_version = 0;
  203.         resp.u.readdir.dirent_count = 0;
  204.         respsize = extra_size_PVFS_servresp_readdir;
  205.         break;
  206.         case PVFS_SERV_FLUSH:
  207.         /* nothing special */
  208.         break;
  209.         case PVFS_SERV_MGMT_SETPARAM:
  210.         /* nothing special */
  211.         break;
  212.         case PVFS_SERV_MGMT_NOOP:
  213.         /* nothing special */
  214.         break;
  215.         case PVFS_SERV_STATFS:
  216.         /* nothing special */
  217.         break;
  218.         case PVFS_SERV_MGMT_GET_DIRDATA_HANDLE:
  219.         /* nothing special */
  220.         break;
  221.         case PVFS_SERV_WRITE_COMPLETION:
  222.         /* only a response, but nothing special there */
  223.         noreq = 1;
  224.         break;
  225.         case PVFS_SERV_MGMT_PERF_MON:
  226.         resp.u.mgmt_perf_mon.perf_array_count = 0;
  227.         respsize = extra_size_PVFS_servresp_mgmt_perf_mon;
  228.         break;
  229.         case PVFS_SERV_MGMT_ITERATE_HANDLES:
  230.         resp.u.mgmt_iterate_handles.handle_count = 0;
  231.         respsize = extra_size_PVFS_servresp_mgmt_iterate_handles;
  232.         break;
  233.         case PVFS_SERV_MGMT_DSPACE_INFO_LIST:
  234.         req.u.mgmt_dspace_info_list.handle_count = 0;
  235.         resp.u.mgmt_dspace_info_list.dspace_info_count = 0;
  236.         reqsize = extra_size_PVFS_servreq_mgmt_dspace_info_list;
  237.         respsize = extra_size_PVFS_servresp_mgmt_dspace_info_list;
  238.         break;
  239.         case PVFS_SERV_MGMT_EVENT_MON:
  240.         resp.u.mgmt_event_mon.event_count = 0;
  241.         respsize = extra_size_PVFS_servresp_mgmt_event_mon;
  242.         break;
  243.         case PVFS_SERV_PROTO_ERROR:
  244.         /* nothing special */
  245.         break;
  246.         case PVFS_SERV_GETEATTR:
  247.                 req.u.geteattr.nkey = 0;
  248.                 resp.u.geteattr.nkey = 0;
  249.         reqsize = extra_size_PVFS_servreq_geteattr;
  250.         respsize = extra_size_PVFS_servresp_geteattr;
  251.         break;
  252.         case PVFS_SERV_SETEATTR:
  253.                 req.u.seteattr.nkey = 0;
  254.         reqsize = extra_size_PVFS_servreq_seteattr;
  255.         break;
  256.         case PVFS_SERV_DELEATTR:
  257.                 req.u.deleattr.key.buffer_sz = 0;
  258.         reqsize = extra_size_PVFS_servreq_deleattr;
  259.         break;
  260.         case PVFS_SERV_LISTEATTR:
  261.         resp.u.listeattr.nkey = 0;
  262.         req.u.listeattr.nkey = 0;
  263.                 reqsize = extra_size_PVFS_servreq_listeattr;
  264.         respsize = extra_size_PVFS_servresp_listeattr;
  265.                 break;
  266.             case PVFS_SERV_LISTATTR:
  267.                 resp.u.listattr.nhandles = 0;
  268.                 req.u.listattr.nhandles = 0;
  269.                 reqsize = extra_size_PVFS_servreq_listattr;
  270.                 respsize = extra_size_PVFS_servresp_listattr;
  271.                 break;
  272.         case PVFS_SERV_TREE_GET_FILE_SIZE:
  273.         req.u.tree_get_file_size.handle_array = NULL;
  274.         req.u.tree_get_file_size.num_data_files = 0;
  275.         resp.u.tree_get_file_size.size = NULL;
  276.         resp.u.tree_get_file_size.error = NULL;
  277.         resp.u.tree_get_file_size.handle_count = 0;
  278.                 resp.u.tree_get_file_size.caller_handle_index = 0;
  279.         respsize = extra_size_PVFS_servresp_tree_get_file_size;
  280.         break;
  281.             case PVFS_SERV_NUM_OPS:  /* sentinel, should not hit */
  282.                 assert(0);
  283.                 break;
  284.     }
  285.     /* since these take the max size when mallocing in the encode,
  286.      * give them a huge number, then later fix it. */
  287.     max_size_array[op_type].req = 
  288.                                  max_size_array[op_type].resp = init_big_size;
  289.  
  290.     if (noreq)
  291.         reqsize = 0;
  292.     else
  293.         reqsize += check_req_size(&req);
  294.  
  295.     respsize += check_resp_size(&resp);
  296.  
  297.     if (reqsize > init_big_size)
  298.         gossip_err("%s: op %d reqsize %d exceeded prealloced %d\n",
  299.           __func__, op_type, reqsize, init_big_size);
  300.     if (respsize > init_big_size)
  301.         gossip_err("%s: op %d respsize %d exceeded prealloced %d\n",
  302.           __func__, op_type, respsize, init_big_size);
  303.     max_size_array[op_type].req = reqsize;
  304.     max_size_array[op_type].resp = respsize;
  305.     }
  306.  
  307.     /* clean up stuff just used for initialization */
  308.     PVFS_hint_free(req.hints);
  309.     free(tmp_dist.dist_name);
  310.     free(tmp_name);
  311.     initializing_sizes = 0;
  312. }
  313.  
  314. static void lebf_finalize(void)
  315. {
  316.     free(max_size_array);
  317. }
  318.  
  319. /* lebf_encode_calc_max_size()
  320.  *
  321.  * reports the maximum allowed encoded size for the given request type
  322.  *
  323.  * returns size on success, -errno on failure
  324.  */
  325. static int lebf_encode_calc_max_size(
  326.     enum PINT_encode_msg_type input_type,
  327.     enum PVFS_server_op op_type)
  328. {
  329.     if(input_type == PINT_ENCODE_REQ)
  330.     return(max_size_array[op_type].req);
  331.     else if(input_type == PINT_ENCODE_RESP)
  332.     return(max_size_array[op_type].resp);
  333.  
  334.     return -PVFS_EINVAL;
  335. }
  336. #define BF_ENCODE_TARGET_MSG_INIT(_msg) \
  337.     (_msg)->buffer_list = &target_msg->buffer_stub; \
  338.     (_msg)->size_list = &target_msg->size_stub; \
  339.     (_msg)->alloc_size_list = &target_msg->alloc_size_stub; \
  340.     (_msg)->list_count = 1; \
  341.     (_msg)->buffer_type = BMI_PRE_ALLOC;
  342.  
  343. /*
  344.  * Used by both encode functions, request and response, to set
  345.  * up the one buffer which will hold the encoded message.
  346.  */
  347. static int
  348. encode_common(struct PINT_encoded_msg *target_msg, int maxsize)
  349. {
  350.     int ret = 0;
  351.     void *buf = NULL;
  352.  
  353.     gossip_debug(GOSSIP_ENDECODE_DEBUG,"encode_common\n");
  354.     /* this encoder always uses just one buffer */
  355.     BF_ENCODE_TARGET_MSG_INIT(target_msg);
  356.  
  357.     gossip_debug(GOSSIP_ENDECODE_DEBUG,"\tmaxsize:%d\tinitializing_sizes:%d\n"
  358.                                       ,maxsize,initializing_sizes);
  359.  
  360.     /* allocate the max size buffer to avoid the work of calculating it */
  361.     buf = (initializing_sizes ? malloc(maxsize) :
  362.            BMI_memalloc(target_msg->dest, maxsize, BMI_SEND));
  363.     if (!buf)
  364.     {
  365.         gossip_err("Error: failed to BMI_malloc memory for response.\n");
  366.         gossip_err("Error: is BMI address %llu still valid?\n", llu(target_msg->dest));
  367.     ret = -PVFS_ENOMEM;
  368.     goto out;
  369.     }
  370.  
  371.     target_msg->buffer_list[0] = buf;
  372.     target_msg->alloc_size_list[0] = maxsize;
  373.     target_msg->ptr_current = buf;
  374.  
  375.     /* generic header */
  376.     memcpy(target_msg->ptr_current, le_bytefield_table.generic_header,
  377.            PINT_ENC_GENERIC_HEADER_SIZE);
  378.     target_msg->ptr_current += PINT_ENC_GENERIC_HEADER_SIZE;
  379.  
  380.  out:
  381.     return ret;
  382. }
  383.  
  384. /* lebf_encode_req()
  385.  *
  386.  * encodes a request structure
  387.  *
  388.  * returns 0 on success, -errno on failure
  389.  */
  390. static int lebf_encode_req(
  391.     struct PVFS_server_req *req,
  392.     struct PINT_encoded_msg *target_msg)
  393. {
  394.     int ret = 0;
  395.     char **p;
  396.  
  397.     gossip_debug(GOSSIP_ENDECODE_DEBUG,"Executing lebf_encode_req...\n");
  398.     gossip_debug(GOSSIP_ENDECODE_DEBUG,"\treq->op:%d\n",req->op);
  399.  
  400.     ret = encode_common(target_msg, max_size_array[req->op].req);
  401.  
  402.     if (ret)
  403.     goto out;
  404.     gossip_debug(GOSSIP_ENDECODE_DEBUG,"lebf_encode_req\n");
  405.  
  406.     /* every request has these fields */
  407.     p = &target_msg->ptr_current;
  408.     encode_PVFS_server_req(p, req);
  409.  
  410. #define CASE(tag,var) \
  411.     case tag: encode_PVFS_servreq_##var(p,&req->u.var); break
  412.  
  413.     switch (req->op) {
  414.  
  415.     /* call standard function defined in headers */
  416.     CASE(PVFS_SERV_LOOKUP_PATH, lookup_path);
  417.     CASE(PVFS_SERV_CREATE, create);
  418.         CASE(PVFS_SERV_MIRROR, mirror);
  419.         CASE(PVFS_SERV_UNSTUFF, unstuff);
  420.     CASE(PVFS_SERV_BATCH_CREATE, batch_create);
  421.         CASE(PVFS_SERV_BATCH_REMOVE, batch_remove);
  422.     CASE(PVFS_SERV_REMOVE, remove);
  423.     CASE(PVFS_SERV_MGMT_REMOVE_OBJECT, mgmt_remove_object);
  424.     CASE(PVFS_SERV_MGMT_REMOVE_DIRENT, mgmt_remove_dirent);
  425.     CASE(PVFS_SERV_TREE_REMOVE, tree_remove);
  426.     CASE(PVFS_SERV_TREE_GET_FILE_SIZE, tree_get_file_size);
  427.     CASE(PVFS_SERV_MGMT_GET_DIRDATA_HANDLE, mgmt_get_dirdata_handle);
  428.     CASE(PVFS_SERV_IO, io);
  429.         CASE(PVFS_SERV_SMALL_IO, small_io);
  430.     CASE(PVFS_SERV_GETATTR, getattr);
  431.     CASE(PVFS_SERV_SETATTR, setattr);
  432.     CASE(PVFS_SERV_CRDIRENT, crdirent);
  433.     CASE(PVFS_SERV_RMDIRENT, rmdirent);
  434.     CASE(PVFS_SERV_CHDIRENT, chdirent);
  435.     CASE(PVFS_SERV_TRUNCATE, truncate);
  436.     CASE(PVFS_SERV_MKDIR, mkdir);
  437.     CASE(PVFS_SERV_READDIR, readdir);
  438.     CASE(PVFS_SERV_FLUSH, flush);
  439.     CASE(PVFS_SERV_STATFS, statfs);
  440.     CASE(PVFS_SERV_MGMT_SETPARAM, mgmt_setparam);
  441.     CASE(PVFS_SERV_MGMT_PERF_MON, mgmt_perf_mon);
  442.     CASE(PVFS_SERV_MGMT_ITERATE_HANDLES, mgmt_iterate_handles);
  443.     CASE(PVFS_SERV_MGMT_DSPACE_INFO_LIST, mgmt_dspace_info_list);
  444.     CASE(PVFS_SERV_MGMT_EVENT_MON, mgmt_event_mon);
  445.     CASE(PVFS_SERV_GETEATTR, geteattr);
  446.     CASE(PVFS_SERV_SETEATTR, seteattr);
  447.     CASE(PVFS_SERV_DELEATTR, deleattr);
  448.     CASE(PVFS_SERV_LISTEATTR, listeattr);
  449.         CASE(PVFS_SERV_LISTATTR,  listattr);
  450.  
  451.     case PVFS_SERV_GETCONFIG:
  452.         case PVFS_SERV_MGMT_NOOP:
  453.     case PVFS_SERV_PROTO_ERROR:
  454.         case PVFS_SERV_IMM_COPIES:
  455.         /* nothing else */
  456.         break;
  457.  
  458.     case PVFS_SERV_INVALID:
  459.         case PVFS_SERV_WRITE_COMPLETION:
  460.         case PVFS_SERV_PERF_UPDATE:
  461.         case PVFS_SERV_PRECREATE_POOL_REFILLER:
  462.         case PVFS_SERV_JOB_TIMER:
  463.         case PVFS_SERV_NUM_OPS:  /* sentinel */
  464.         gossip_err("%s: invalid operation %d\n", __func__, req->op);
  465.         ret = -PVFS_ENOSYS;
  466.         break;
  467.     }
  468.  
  469. #undef CASE
  470.  
  471.     /* although much more may have been allocated */
  472.     target_msg->total_size = target_msg->ptr_current
  473.       - (char *) target_msg->buffer_list[0];
  474.     target_msg->size_list[0] = target_msg->total_size;
  475.  
  476.     if (target_msg->total_size > max_size_array[req->op].req)
  477.     {
  478.     ret = -PVFS_ENOMEM;
  479.     gossip_err("%s: op %d needed %lld bytes but alloced only %d\n",
  480.       __func__, req->op, lld(target_msg->total_size),
  481.       max_size_array[req->op].req);
  482.     }
  483.  
  484.   out:
  485.     return ret;
  486. }
  487.  
  488.  
  489. /* lebf_encode_resp()
  490.  *
  491.  * encodes a response structure
  492.  *
  493.  * returns 0 on success, -errno on failure
  494.  */
  495. static int lebf_encode_resp(
  496.     struct PVFS_server_resp *resp,
  497.     struct PINT_encoded_msg *target_msg)
  498. {
  499.     int ret;
  500.     char **p;
  501.  
  502.     ret = encode_common(target_msg, max_size_array[resp->op].resp);
  503.     if (ret)
  504.     goto out;
  505.     gossip_debug(GOSSIP_ENDECODE_DEBUG,"lebf_encode_resp\n");
  506.  
  507.     /* every response has these fields */
  508.     p = &target_msg->ptr_current;
  509.     encode_PVFS_server_resp(p, resp);
  510.  
  511. #define CASE(tag,var) \
  512.     case tag: encode_PVFS_servresp_##var(p,&resp->u.var); break
  513.  
  514.  
  515.     /* we stand a good chance of segfaulting if we try to encode the response
  516.      * after something bad happened reading data from disk. */
  517.     if (resp->status == 0) 
  518.     {
  519.  
  520.         /* extra encoding rules for particular responses */
  521.         switch (resp->op) {
  522.  
  523.         /* call standard function defined in headers */
  524.         CASE(PVFS_SERV_GETCONFIG, getconfig);
  525.         CASE(PVFS_SERV_LOOKUP_PATH, lookup_path);
  526.         CASE(PVFS_SERV_CREATE, create);
  527.         CASE(PVFS_SERV_MIRROR, mirror);
  528.         CASE(PVFS_SERV_UNSTUFF, unstuff);
  529.         CASE(PVFS_SERV_BATCH_CREATE, batch_create);
  530.         CASE(PVFS_SERV_IO, io);
  531.         CASE(PVFS_SERV_SMALL_IO, small_io);
  532.         CASE(PVFS_SERV_GETATTR, getattr);
  533.         CASE(PVFS_SERV_RMDIRENT, rmdirent);
  534.         CASE(PVFS_SERV_CHDIRENT, chdirent);
  535.         CASE(PVFS_SERV_MKDIR, mkdir);
  536.         CASE(PVFS_SERV_READDIR, readdir);
  537.         CASE(PVFS_SERV_STATFS, statfs);
  538.         CASE(PVFS_SERV_MGMT_PERF_MON, mgmt_perf_mon);
  539.         CASE(PVFS_SERV_MGMT_ITERATE_HANDLES, mgmt_iterate_handles);
  540.         CASE(PVFS_SERV_MGMT_DSPACE_INFO_LIST, mgmt_dspace_info_list);
  541.         CASE(PVFS_SERV_MGMT_EVENT_MON, mgmt_event_mon);
  542.         CASE(PVFS_SERV_WRITE_COMPLETION, write_completion);
  543.         CASE(PVFS_SERV_MGMT_GET_DIRDATA_HANDLE, mgmt_get_dirdata_handle);
  544.         CASE(PVFS_SERV_GETEATTR, geteattr);
  545.         CASE(PVFS_SERV_LISTEATTR, listeattr);
  546.         CASE(PVFS_SERV_LISTATTR, listattr);
  547.         CASE(PVFS_SERV_TREE_GET_FILE_SIZE, tree_get_file_size);
  548.  
  549.         case PVFS_SERV_REMOVE:
  550.         case PVFS_SERV_MGMT_REMOVE_OBJECT:
  551.         case PVFS_SERV_MGMT_REMOVE_DIRENT:
  552.         case PVFS_SERV_TREE_REMOVE:
  553.         case PVFS_SERV_SETATTR:
  554.         case PVFS_SERV_SETEATTR:
  555.         case PVFS_SERV_DELEATTR:
  556.         case PVFS_SERV_CRDIRENT:
  557.         case PVFS_SERV_TRUNCATE:
  558.         case PVFS_SERV_FLUSH:
  559.         case PVFS_SERV_MGMT_NOOP:
  560.         case PVFS_SERV_BATCH_REMOVE:
  561.         case PVFS_SERV_PROTO_ERROR:
  562.         case PVFS_SERV_IMM_COPIES:
  563.         case PVFS_SERV_MGMT_SETPARAM:
  564.             /* nothing else */
  565.             break;
  566.  
  567.         case PVFS_SERV_INVALID:
  568.         case PVFS_SERV_PERF_UPDATE:
  569.         case PVFS_SERV_PRECREATE_POOL_REFILLER:
  570.         case PVFS_SERV_JOB_TIMER:
  571.         case PVFS_SERV_NUM_OPS:  /* sentinel */
  572.             gossip_err("%s: invalid operation %d\n", __func__, resp->op);
  573.             ret = -PVFS_ENOSYS;
  574.             break;
  575.         }
  576.     } 
  577.  
  578. #undef CASE
  579.  
  580.     /* although much more may have been allocated */
  581.     target_msg->total_size = target_msg->ptr_current
  582.       - (char *) target_msg->buffer_list[0];
  583.     target_msg->size_list[0] = target_msg->total_size;
  584.  
  585.     if (target_msg->total_size > max_size_array[resp->op].resp) {
  586.     ret = -PVFS_ENOMEM;
  587.     gossip_err("%s: op %d needed %lld bytes but alloced only %d\n",
  588.       __func__, resp->op, lld(target_msg->total_size),
  589.       max_size_array[resp->op].resp);
  590.     }
  591.  
  592.   out:
  593.     return ret;
  594. }
  595.  
  596. /* lebf_decode_req()
  597.  *
  598.  * decodes a request message
  599.  *
  600.  * input_buffer is a pointer past the generic header; it starts with
  601.  * PVFS_server_req->op.
  602.  *
  603.  * returns 0 on success, -errno on failure
  604.  */
  605. static int lebf_decode_req(
  606.     void *input_buffer,
  607.     int input_size,
  608.     struct PINT_decoded_msg *target_msg,
  609.     PVFS_BMI_addr_t target_addr)
  610. {
  611.     int ret = 0;
  612.     char *ptr = input_buffer;
  613.     char **p = &ptr;
  614.     struct PVFS_server_req *req = &target_msg->stub_dec.req;
  615.  
  616.     target_msg->buffer = req;
  617.  
  618.     /* decode generic part of request (enough to get op number) */
  619.     decode_PVFS_server_req(p, req);
  620.     gossip_debug(GOSSIP_ENDECODE_DEBUG,"lebf_decode_req\n");
  621.  
  622. #define CASE(tag,var) \
  623.     case tag: decode_PVFS_servreq_##var(p, &req->u.var); break
  624.  
  625.     switch (req->op) {
  626.  
  627.     /* call standard function defined in headers */
  628.     CASE(PVFS_SERV_LOOKUP_PATH, lookup_path);
  629.     CASE(PVFS_SERV_CREATE, create);
  630.         CASE(PVFS_SERV_MIRROR, mirror);
  631.         CASE(PVFS_SERV_UNSTUFF, unstuff);
  632.     CASE(PVFS_SERV_BATCH_CREATE, batch_create);
  633.         CASE(PVFS_SERV_BATCH_REMOVE, batch_remove);
  634.     CASE(PVFS_SERV_REMOVE, remove);
  635.     CASE(PVFS_SERV_MGMT_REMOVE_OBJECT, mgmt_remove_object);
  636.     CASE(PVFS_SERV_MGMT_REMOVE_DIRENT, mgmt_remove_dirent);
  637.     CASE(PVFS_SERV_TREE_REMOVE, tree_remove);
  638.     CASE(PVFS_SERV_TREE_GET_FILE_SIZE, tree_get_file_size);
  639.     CASE(PVFS_SERV_MGMT_GET_DIRDATA_HANDLE, mgmt_get_dirdata_handle);
  640.     CASE(PVFS_SERV_IO, io);
  641.         CASE(PVFS_SERV_SMALL_IO, small_io);
  642.     CASE(PVFS_SERV_GETATTR, getattr);
  643.     CASE(PVFS_SERV_SETATTR, setattr);
  644.     CASE(PVFS_SERV_CRDIRENT, crdirent);
  645.     CASE(PVFS_SERV_RMDIRENT, rmdirent);
  646.     CASE(PVFS_SERV_CHDIRENT, chdirent);
  647.     CASE(PVFS_SERV_TRUNCATE, truncate);
  648.     CASE(PVFS_SERV_MKDIR, mkdir);
  649.     CASE(PVFS_SERV_READDIR, readdir);
  650.     CASE(PVFS_SERV_FLUSH, flush);
  651.     CASE(PVFS_SERV_STATFS, statfs);
  652.     CASE(PVFS_SERV_MGMT_SETPARAM, mgmt_setparam);
  653.     CASE(PVFS_SERV_MGMT_PERF_MON, mgmt_perf_mon);
  654.     CASE(PVFS_SERV_MGMT_ITERATE_HANDLES, mgmt_iterate_handles);
  655.     CASE(PVFS_SERV_MGMT_DSPACE_INFO_LIST, mgmt_dspace_info_list);
  656.     CASE(PVFS_SERV_MGMT_EVENT_MON, mgmt_event_mon);
  657.     CASE(PVFS_SERV_GETEATTR, geteattr);
  658.     CASE(PVFS_SERV_SETEATTR, seteattr);
  659.     CASE(PVFS_SERV_DELEATTR, deleattr);
  660.         CASE(PVFS_SERV_LISTEATTR, listeattr);
  661.         CASE(PVFS_SERV_LISTATTR, listattr);
  662.  
  663.     case PVFS_SERV_GETCONFIG:
  664.         case PVFS_SERV_MGMT_NOOP:
  665.         case PVFS_SERV_IMM_COPIES:
  666.         /* nothing else */
  667.         break;
  668.  
  669.     case PVFS_SERV_INVALID:
  670.         case PVFS_SERV_WRITE_COMPLETION:
  671.         case PVFS_SERV_PERF_UPDATE:
  672.         case PVFS_SERV_PRECREATE_POOL_REFILLER:
  673.         case PVFS_SERV_JOB_TIMER:
  674.     case PVFS_SERV_PROTO_ERROR:
  675.         case PVFS_SERV_NUM_OPS:  /* sentinel */
  676.         gossip_lerr("%s: invalid operation %d.\n", __func__, req->op);
  677.         ret = -PVFS_EPROTO;
  678.         goto out;
  679.     }
  680.  
  681. #undef CASE
  682.  
  683.     if (ptr != (char *) input_buffer + input_size)
  684.     {
  685.     gossip_lerr("%s: op %d consumed %ld bytes, but message was %d bytes.\n",
  686.                     __func__, req->op, (long)(ptr - (char *) input_buffer), input_size);
  687.     ret = -PVFS_EPROTO;
  688.     }
  689.  
  690.   out:
  691.     return(ret);
  692. }
  693.  
  694. /* lebf_decode_resp()
  695.  *
  696.  * decodes a response structure
  697.  *
  698.  * returns 0 on success, -errno on failure
  699.  */
  700. static int lebf_decode_resp(
  701.     void *input_buffer,
  702.     int input_size,
  703.     struct PINT_decoded_msg *target_msg,
  704.     PVFS_BMI_addr_t target_addr)
  705. {
  706.     int ret = 0;
  707.     char *ptr = input_buffer;
  708.     char **p = &ptr;
  709.     struct PVFS_server_resp *resp = &target_msg->stub_dec.resp;
  710.  
  711.     target_msg->buffer = resp;
  712.  
  713.     /* decode generic part of response (including op number) */
  714.     decode_PVFS_server_resp(p, resp);
  715.     gossip_debug(GOSSIP_ENDECODE_DEBUG,"lebf_decode_resp\n");
  716.  
  717.     if (resp->status != 0) 
  718.         goto out;
  719.  
  720. #define CASE(tag,var) \
  721.     case tag: decode_PVFS_servresp_##var(p,&resp->u.var); break
  722.  
  723.     switch (resp->op) {
  724.  
  725.     /* call standard function defined in headers */
  726.     CASE(PVFS_SERV_GETCONFIG, getconfig);
  727.     CASE(PVFS_SERV_LOOKUP_PATH, lookup_path);
  728.     CASE(PVFS_SERV_CREATE, create);
  729.         CASE(PVFS_SERV_MIRROR, mirror);
  730.         CASE(PVFS_SERV_UNSTUFF, unstuff);
  731.     CASE(PVFS_SERV_BATCH_CREATE, batch_create);
  732.     CASE(PVFS_SERV_IO, io);
  733.         CASE(PVFS_SERV_SMALL_IO, small_io);
  734.     CASE(PVFS_SERV_GETATTR, getattr);
  735.     CASE(PVFS_SERV_RMDIRENT, rmdirent);
  736.     CASE(PVFS_SERV_CHDIRENT, chdirent);
  737.     CASE(PVFS_SERV_MKDIR, mkdir);
  738.     CASE(PVFS_SERV_READDIR, readdir);
  739.     CASE(PVFS_SERV_STATFS, statfs);
  740.     CASE(PVFS_SERV_MGMT_PERF_MON, mgmt_perf_mon);
  741.     CASE(PVFS_SERV_MGMT_ITERATE_HANDLES, mgmt_iterate_handles);
  742.     CASE(PVFS_SERV_MGMT_DSPACE_INFO_LIST, mgmt_dspace_info_list);
  743.     CASE(PVFS_SERV_MGMT_EVENT_MON, mgmt_event_mon);
  744.     CASE(PVFS_SERV_MGMT_GET_DIRDATA_HANDLE, mgmt_get_dirdata_handle);
  745.         CASE(PVFS_SERV_WRITE_COMPLETION, write_completion);
  746.     CASE(PVFS_SERV_GETEATTR, geteattr);
  747.         CASE(PVFS_SERV_LISTEATTR, listeattr);
  748.         CASE(PVFS_SERV_LISTATTR, listattr);
  749.         CASE(PVFS_SERV_TREE_GET_FILE_SIZE, tree_get_file_size);
  750.  
  751.         case PVFS_SERV_REMOVE:
  752.         case PVFS_SERV_BATCH_REMOVE:
  753.         case PVFS_SERV_MGMT_REMOVE_OBJECT:
  754.         case PVFS_SERV_MGMT_REMOVE_DIRENT:
  755.         case PVFS_SERV_TREE_REMOVE:
  756.         case PVFS_SERV_SETATTR:
  757.         case PVFS_SERV_SETEATTR:
  758.         case PVFS_SERV_DELEATTR:
  759.         case PVFS_SERV_CRDIRENT:
  760.         case PVFS_SERV_TRUNCATE:
  761.         case PVFS_SERV_FLUSH:
  762.         case PVFS_SERV_MGMT_NOOP:
  763.         case PVFS_SERV_PROTO_ERROR:
  764.         case PVFS_SERV_IMM_COPIES:
  765.         case PVFS_SERV_MGMT_SETPARAM:
  766.         /* nothing else */
  767.         break;
  768.  
  769.     case PVFS_SERV_INVALID:
  770.         case PVFS_SERV_PERF_UPDATE:
  771.         case PVFS_SERV_PRECREATE_POOL_REFILLER:
  772.         case PVFS_SERV_JOB_TIMER:
  773.         case PVFS_SERV_NUM_OPS:  /* sentinel */
  774.         gossip_lerr("%s: invalid operation %d.\n", __func__, resp->op);
  775.         ret = -PVFS_EPROTO;
  776.         goto out;
  777.     }
  778.  
  779. #undef CASE
  780.  
  781.     if (ptr != (char *) input_buffer + input_size) {
  782.     gossip_lerr("%s: op %d consumed %ld bytes, but message was %d bytes.\n",
  783.                     __func__, resp->op, (long)(ptr - (char *) input_buffer),
  784.                     input_size);
  785.     ret = -PVFS_EPROTO;
  786.     }
  787.  
  788.   out:
  789.     return(ret);
  790. }
  791.  
  792. /* lebf_encode_rel()
  793.  *
  794.  * releases resources consumed while encoding
  795.  *
  796.  * no return value 
  797.  */
  798. static void lebf_encode_rel(
  799.     struct PINT_encoded_msg *msg,
  800.     enum PINT_encode_msg_type input_type)
  801. {
  802.     gossip_debug(GOSSIP_ENDECODE_DEBUG,"lebf_encode_rel\n");
  803.     /* just a single buffer to free */
  804.     if (initializing_sizes)
  805.     {
  806.     free(msg->buffer_list[0]);
  807.     }
  808.     else
  809.     {
  810.     BMI_memfree(msg->dest, msg->buffer_list[0],
  811.                     msg->alloc_size_list[0], BMI_SEND);
  812.     }
  813. }
  814.  
  815. /* lebf_decode_rel()
  816.  *
  817.  * releases resources consumed while decoding
  818.  *
  819.  * no return value
  820.  */
  821. static void lebf_decode_rel(struct PINT_decoded_msg *msg,
  822.                             enum PINT_encode_msg_type input_type)
  823. {
  824.     gossip_debug(GOSSIP_ENDECODE_DEBUG,"lebf_decode_rel\n");
  825.     if (input_type == PINT_DECODE_REQ) {
  826.     struct PVFS_server_req *req = &msg->stub_dec.req;
  827.     switch (req->op) {
  828.         case PVFS_SERV_CREATE:
  829.         if (req->u.create.attr.mask & PVFS_ATTR_META_DIST)
  830.             decode_free(req->u.create.attr.u.meta.dist);
  831.                 if (req->u.create.layout.server_list.servers)
  832.                     decode_free(req->u.create.layout.server_list.servers);
  833.                 break;
  834.         case PVFS_SERV_BATCH_CREATE:
  835.         decode_free(
  836.                     req->u.batch_create.handle_extent_array.extent_array);
  837.         break;
  838.  
  839.         case PVFS_SERV_IO:
  840.         decode_free(req->u.io.io_dist);
  841.         decode_free(req->u.io.file_req);
  842.         break;
  843.  
  844.             case PVFS_SERV_SMALL_IO:
  845.                 decode_free(req->u.small_io.dist);
  846.                 decode_free(req->u.small_io.file_req);
  847.                 break;
  848.  
  849.             case PVFS_SERV_MIRROR:
  850.         decode_free(req->u.mirror.dist);
  851.                 decode_free(req->u.mirror.dst_handle);
  852.                 decode_free(req->u.mirror.wcIndex);
  853.         break;
  854.  
  855.         case PVFS_SERV_MKDIR:
  856.         decode_free(req->u.mkdir.handle_extent_array.extent_array);
  857.         if (req->u.mkdir.attr.mask & PVFS_ATTR_META_DIST)
  858.             decode_free(req->u.mkdir.attr.u.meta.dist);
  859.         if (req->u.mkdir.attr.mask & PVFS_ATTR_META_DFILES)
  860.             decode_free(req->u.mkdir.attr.u.meta.dfile_array);
  861.         break;
  862.  
  863.         case PVFS_SERV_MGMT_DSPACE_INFO_LIST:
  864.         decode_free(req->u.mgmt_dspace_info_list.handle_array);
  865.         break;
  866.  
  867.             case PVFS_SERV_SETATTR:
  868.         if (req->u.setattr.attr.mask & PVFS_ATTR_META_DIST)
  869.             decode_free(req->u.setattr.attr.u.meta.dist);
  870.         if (req->u.setattr.attr.mask & PVFS_ATTR_META_DFILES)
  871.             decode_free(req->u.setattr.attr.u.meta.dfile_array);
  872.         break;
  873.  
  874.         case PVFS_SERV_TREE_REMOVE:
  875.         decode_free(req->u.tree_remove.handle_array);
  876.         break;
  877.  
  878.         case PVFS_SERV_TREE_GET_FILE_SIZE:
  879.         decode_free(req->u.tree_get_file_size.handle_array);
  880.         break;
  881.  
  882.             case PVFS_SERV_LISTATTR:
  883.                 if (req->u.listattr.handles)
  884.                     decode_free(req->u.listattr.handles);
  885.                 break;
  886.  
  887.         case PVFS_SERV_SETEATTR:
  888.                 decode_free(req->u.seteattr.key);
  889.                 decode_free(req->u.seteattr.val);
  890.                 break;
  891.  
  892.         case PVFS_SERV_GETEATTR:
  893.                 decode_free(req->u.geteattr.key);
  894.                 decode_free(req->u.geteattr.valsz);
  895.                 break;
  896.  
  897.         case PVFS_SERV_GETCONFIG:
  898.         case PVFS_SERV_LOOKUP_PATH:
  899.         case PVFS_SERV_REMOVE:
  900.         case PVFS_SERV_MGMT_REMOVE_OBJECT:
  901.         case PVFS_SERV_MGMT_REMOVE_DIRENT:
  902.         case PVFS_SERV_MGMT_GET_DIRDATA_HANDLE:
  903.         case PVFS_SERV_GETATTR:
  904.         case PVFS_SERV_CRDIRENT:
  905.         case PVFS_SERV_RMDIRENT:
  906.         case PVFS_SERV_CHDIRENT:
  907.         case PVFS_SERV_TRUNCATE:
  908.         case PVFS_SERV_READDIR:
  909.         case PVFS_SERV_FLUSH:
  910.         case PVFS_SERV_MGMT_SETPARAM:
  911.         case PVFS_SERV_MGMT_NOOP:
  912.         case PVFS_SERV_STATFS:
  913.         case PVFS_SERV_MGMT_ITERATE_HANDLES:
  914.         case PVFS_SERV_MGMT_PERF_MON:
  915.         case PVFS_SERV_MGMT_EVENT_MON:
  916.  
  917.         case PVFS_SERV_DELEATTR:
  918.             case PVFS_SERV_LISTEATTR:
  919.             case PVFS_SERV_BATCH_REMOVE:
  920.             case PVFS_SERV_UNSTUFF:
  921.             case PVFS_SERV_IMM_COPIES:
  922.               /*nothing to free*/
  923.                   break;
  924.         case PVFS_SERV_INVALID:
  925.         case PVFS_SERV_WRITE_COMPLETION:
  926.         case PVFS_SERV_PERF_UPDATE:
  927.         case PVFS_SERV_PRECREATE_POOL_REFILLER:
  928.         case PVFS_SERV_JOB_TIMER:
  929.         case PVFS_SERV_PROTO_ERROR:
  930.             case PVFS_SERV_NUM_OPS:  /* sentinel */
  931.         gossip_lerr("%s: invalid request operation %d.\n",
  932.           __func__, req->op);
  933.                 break;
  934.     }
  935.     } else if (input_type == PINT_DECODE_RESP) {
  936.     struct PVFS_server_resp *resp = &msg->stub_dec.resp;
  937.  
  938.         if(resp->status == 0)
  939.         {
  940.             switch (resp->op)
  941.             {
  942.                 case PVFS_SERV_LOOKUP_PATH:
  943.                     {
  944.                         struct PVFS_servresp_lookup_path *lookup =
  945.                             &resp->u.lookup_path;
  946.                         decode_free(lookup->handle_array);
  947.                         decode_free(lookup->attr_array);
  948.                         break;
  949.                     }
  950.  
  951.                 case PVFS_SERV_READDIR:
  952.                     decode_free(resp->u.readdir.dirent_array);
  953.                     break;
  954.  
  955.                 case PVFS_SERV_MGMT_PERF_MON:
  956.                     decode_free(resp->u.mgmt_perf_mon.perf_array);
  957.                     break;
  958.  
  959.                 case PVFS_SERV_MGMT_ITERATE_HANDLES:
  960.                     decode_free(resp->u.mgmt_iterate_handles.handle_array);
  961.                     break;
  962.                 
  963.                 case PVFS_SERV_BATCH_CREATE:
  964.                     decode_free(resp->u.batch_create.handle_array);
  965.                     break;
  966.                 
  967.                 case PVFS_SERV_CREATE:
  968.                     decode_free(resp->u.create.datafile_handles);
  969.                     break;
  970.  
  971.                 case PVFS_SERV_MGMT_DSPACE_INFO_LIST:
  972.                     decode_free(resp->u.mgmt_dspace_info_list.dspace_info_array);
  973.                     break;
  974.  
  975.                 case PVFS_SERV_GETATTR:
  976.                     if (resp->u.getattr.attr.mask & PVFS_ATTR_META_DIST)
  977.                         decode_free(resp->u.getattr.attr.u.meta.dist);
  978.                     if (resp->u.getattr.attr.mask & PVFS_ATTR_META_DFILES)
  979.                        decode_free(resp->u.getattr.attr.u.meta.dfile_array);
  980.                     if (   resp->u.getattr.attr.mask 
  981.                          & PVFS_ATTR_META_MIRROR_DFILES ) 
  982.                        decode_free
  983.                         (resp->u.getattr.attr.u.meta.mirror_dfile_array);
  984.                     break;
  985.  
  986.                 case PVFS_SERV_UNSTUFF:
  987.                     if (resp->u.unstuff.attr.mask & PVFS_ATTR_META_DIST)
  988.                         decode_free(resp->u.unstuff.attr.u.meta.dist);
  989.                     if (resp->u.unstuff.attr.mask & PVFS_ATTR_META_DFILES)
  990.                     {
  991.                         decode_free(resp->u.unstuff.attr.u.meta.dfile_array);
  992.                     }
  993.                     if (   resp->u.unstuff.attr.mask 
  994.                          & PVFS_ATTR_META_MIRROR_DFILES ) 
  995.                        decode_free
  996.                         (resp->u.unstuff.attr.u.meta.mirror_dfile_array);
  997.                     break;
  998.  
  999.                 case PVFS_SERV_MGMT_EVENT_MON:
  1000.                     decode_free(resp->u.mgmt_event_mon.event_array);
  1001.                     break;
  1002.  
  1003.                 case PVFS_SERV_GETEATTR:
  1004.                     /* need a loop here?  WBL */
  1005.                     if (resp->u.geteattr.val)
  1006.                         decode_free(resp->u.geteattr.val);
  1007.                     break;
  1008.                 case PVFS_SERV_LISTEATTR:
  1009.                     if (resp->u.listeattr.key)
  1010.                         decode_free(resp->u.listeattr.key);
  1011.                     break;
  1012.                 case PVFS_SERV_LISTATTR:
  1013.                     {
  1014.                      int i;
  1015.                      if (resp->u.listattr.error)
  1016.                          decode_free(resp->u.listattr.error);
  1017.                      if (resp->u.listattr.attr) {
  1018.                          for (i = 0; i < resp->u.listattr.nhandles; i++) {
  1019.                           if (resp->u.listattr.attr[i].mask &
  1020.                                    PVFS_ATTR_META_DIST)
  1021.                            decode_free(resp->u.listattr.attr[i].u.meta.dist);
  1022.                           if (resp->u.listattr.attr[i].mask &
  1023.                                    PVFS_ATTR_META_DFILES)
  1024.                           {
  1025.                            decode_free(
  1026.                               resp->u.listattr.attr[i].u.meta.dfile_array);
  1027.                           }
  1028.                           if(
  1029.                               resp->u.listattr.attr[i].mask &
  1030.                               PVFS_ATTR_META_MIRROR_DFILES
  1031.                             )
  1032.                             decode_free(
  1033.                           resp->u.listattr.attr[i].u.meta.mirror_dfile_array);
  1034.                          }/*end for*/
  1035.                          decode_free(resp->u.listattr.attr);
  1036.                      }/*end if attr*/
  1037.                         break;
  1038.                     }/*end case*/
  1039.  
  1040.                 case PVFS_SERV_MIRROR:
  1041.                    {
  1042.                       decode_free(resp->u.mirror.bytes_written);
  1043.                       decode_free(resp->u.mirror.write_status_code);
  1044.                       break;
  1045.                    }
  1046.  
  1047.                 case PVFS_SERV_TREE_GET_FILE_SIZE:
  1048.                    {
  1049.                       decode_free(resp->u.tree_get_file_size.size);
  1050.                       decode_free(resp->u.tree_get_file_size.error);
  1051.                       break;
  1052.                    }
  1053.  
  1054.                 case PVFS_SERV_GETCONFIG:
  1055.                 case PVFS_SERV_REMOVE:
  1056.                 case PVFS_SERV_MGMT_REMOVE_OBJECT:
  1057.                 case PVFS_SERV_MGMT_REMOVE_DIRENT:
  1058.                 case PVFS_SERV_MGMT_GET_DIRDATA_HANDLE:
  1059.                 case PVFS_SERV_IO:
  1060.                 case PVFS_SERV_SMALL_IO:
  1061.                 case PVFS_SERV_SETATTR:
  1062.                 case PVFS_SERV_SETEATTR:
  1063.                 case PVFS_SERV_DELEATTR:
  1064.                 case PVFS_SERV_CRDIRENT:
  1065.                 case PVFS_SERV_RMDIRENT:
  1066.                 case PVFS_SERV_CHDIRENT:
  1067.                 case PVFS_SERV_TRUNCATE:
  1068.                 case PVFS_SERV_MKDIR:
  1069.                 case PVFS_SERV_FLUSH:
  1070.                 case PVFS_SERV_MGMT_SETPARAM:
  1071.                 case PVFS_SERV_MGMT_NOOP:
  1072.                 case PVFS_SERV_STATFS:
  1073.                 case PVFS_SERV_WRITE_COMPLETION:
  1074.                 case PVFS_SERV_PROTO_ERROR:
  1075.                 case PVFS_SERV_BATCH_REMOVE:
  1076.                 case PVFS_SERV_IMM_COPIES:
  1077.                 case PVFS_SERV_TREE_REMOVE:
  1078.                   /*nothing to free */
  1079.                    break;
  1080.                 case PVFS_SERV_INVALID:
  1081.                 case PVFS_SERV_PERF_UPDATE:
  1082.                 case PVFS_SERV_PRECREATE_POOL_REFILLER:
  1083.                 case PVFS_SERV_JOB_TIMER:
  1084.                 case PVFS_SERV_NUM_OPS:  /* sentinel */
  1085.                     gossip_lerr("%s: invalid response operation %d.\n",
  1086.                                 __func__, resp->op);
  1087.                     break;
  1088.             }
  1089.         }
  1090.     }
  1091. }
  1092.  
  1093. static int check_req_size(struct PVFS_server_req *req)
  1094. {
  1095.     struct PINT_encoded_msg msg;
  1096.     int size;
  1097.  
  1098.     gossip_debug(GOSSIP_ENDECODE_DEBUG,"check_req_size\n");
  1099.     lebf_encode_req(req, &msg);
  1100.     size = msg.total_size;
  1101.     lebf_encode_rel(&msg, 0);
  1102.     return size;
  1103. }
  1104.  
  1105. static int check_resp_size(struct PVFS_server_resp *resp)
  1106. {
  1107.     struct PINT_encoded_msg msg;
  1108.     int size;
  1109.  
  1110.     gossip_debug(GOSSIP_ENDECODE_DEBUG,"check_resp_size\n");
  1111.     lebf_encode_resp(resp, &msg);
  1112.     size = msg.total_size;
  1113.     lebf_encode_rel(&msg, 0);
  1114.     return size;
  1115. }
  1116.  
  1117. static PINT_encoding_functions lebf_functions = {
  1118.     lebf_encode_req,
  1119.     lebf_encode_resp,
  1120.     lebf_decode_req,
  1121.     lebf_decode_resp,
  1122.     lebf_encode_rel,
  1123.     lebf_decode_rel,
  1124.     lebf_encode_calc_max_size
  1125. };
  1126.  
  1127. PINT_encoding_table_values le_bytefield_table = {
  1128.     &lebf_functions,
  1129.     "little endian bytefield",
  1130.     lebf_initialize,
  1131.     lebf_finalize
  1132. };
  1133.  
  1134. /*
  1135.  * Local variables:
  1136.  *  c-indent-level: 4
  1137.  *  c-basic-offset: 4
  1138.  * End:
  1139.  *
  1140.  * vim: ts=8 sts=4 sw=4 expandtab
  1141.  */
  1142.