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 / set-eattr.sm < prev    next >
Text File  |  2011-02-25  |  20KB  |  696 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 "pvfs2-internal.h"
  14. #include "pvfs2-util.h"
  15. #include "pint-util.h"
  16. #include "pint-eattr.h"
  17. #include "pvfs2-mirror.h"
  18.  
  19. /*helper functions' prototypes*/
  20. static void init_keyval_structs(PINT_server_op *s_op, int free_val);
  21.  
  22. /*data structures*/
  23. enum {
  24.    PVFS2_MAKE_IMMUTABLE_COPIES = 200,
  25.    CREATE_IMM_COPIES = 300,
  26.    SKIP_UPDATE = 400
  27. };
  28.  
  29. %%
  30.  
  31. machine pvfs2_set_eattr_sm
  32. {
  33.     state prelude
  34.     {
  35.         jump pvfs2_prelude_sm;
  36.         success => verify_eattrib;
  37.         default => final_response;
  38.     }
  39.  
  40.     state verify_eattrib
  41.     {
  42.         run seteattr_verify_eattribs;
  43.         success => setobj_eattrib;
  44.         default => final_response;
  45.     }
  46.  
  47.     state setobj_eattrib
  48.     {
  49.         run seteattr_setobj_eattribs;
  50.         success => check_mirror_mode; 
  51.         default => final_response;
  52.     }
  53.  
  54.     state check_mirror_mode
  55.     {
  56.         run seteattr_get_metahint_flag;
  57.         SKIP_UPDATE => check_immutable;
  58.         default     => update_flag;
  59.     }
  60.  
  61.     state update_flag
  62.     {
  63.         run seteattr_set_metahint_flag;
  64.         success => check_immutable;
  65.         default => final_response;
  66.     }
  67.  
  68.     state check_immutable
  69.     {
  70.         run check_immutable;
  71.         PVFS2_MAKE_IMMUTABLE_COPIES => generate_copies;
  72.         default => final_response;
  73.     }
  74.  
  75.     state generate_copies
  76.     {
  77.         pjmp setup_create_immutable_copies
  78.         {
  79.            CREATE_IMM_COPIES => pvfs2_pjmp_create_immutable_copies_sm;
  80.         }
  81.         success => inspect_imm_copies;
  82.         default => final_response;
  83.     }
  84.  
  85.     state inspect_imm_copies
  86.     {
  87.          run inspect_imm_copies;
  88.          default => final_response;
  89.     }
  90.  
  91.     state final_response
  92.     {
  93.         jump pvfs2_final_response_sm;
  94.         default => cleanup;
  95.     }
  96.  
  97.     state cleanup
  98.     {
  99.         run seteattr_cleanup;
  100.         default => terminate;
  101.     }
  102. }
  103.  
  104. %%
  105.  
  106. /*
  107.  * This routine checks keys to confirm that the name spaces are valid.
  108.  */
  109. static int seteattr_verify_eattribs(
  110.         struct PINT_smcb *smcb, job_status_s *js_p)
  111. {
  112.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  113.     int i; 
  114.  
  115.     gossip_debug(GOSSIP_MIRROR_DEBUG,"Current Frame Pointer in set-eattr.sm "
  116.                                      "is %p.\n",s_op);       
  117.  
  118.     PVFS_object_attr *a_p = NULL;
  119.     a_p = &s_op->attr;
  120.  
  121.     js_p->error_code = 0;
  122.  
  123.     gossip_debug(GOSSIP_SETEATTR_DEBUG,
  124.                  "  ext attr list write to handle %llu refers to a %s\n\t"
  125.                  "[owner = %d, group = %d, perms = %o, type = %d]\n",
  126.                  llu(s_op->req->u.seteattr.handle),
  127.                  PINT_util_get_object_type(a_p->objtype),
  128.                  a_p->owner, a_p->group, a_p->perms, a_p->objtype);
  129.  
  130.     if( s_op->req->u.seteattr.nkey > PVFS_MAX_XATTR_LISTLEN  )
  131.     {
  132.         js_p->error_code = -PVFS_EINVAL;
  133.         return SM_ACTION_COMPLETE;
  134.     }
  135.  
  136.     for( i = 0; i < s_op->req->u.seteattr.nkey; i++ )
  137.     {
  138.         if( s_op->req->u.seteattr.key[i].buffer_sz > PVFS_MAX_XATTR_NAMELEN )
  139.         {
  140.             js_p->error_code = -PVFS_EINVAL;
  141.             return SM_ACTION_COMPLETE;
  142.         }
  143.  
  144.         if( s_op->req->u.seteattr.val[i].buffer_sz > PVFS_MAX_XATTR_VALUELEN )
  145.         {
  146.             js_p->error_code = -PVFS_EINVAL;
  147.             return SM_ACTION_COMPLETE;
  148.         }
  149.     }
  150.  
  151.     /* iterate through the keys that are being written */
  152.     int j = 0;
  153.     char *valBuf = NULL;
  154.     for (i = 0; i < s_op->req->u.seteattr.nkey; i++)
  155.     {
  156.         gossip_debug(GOSSIP_MIRROR_DEBUG
  157.                     ,"\tkey:%s\n"
  158.                     ,(char *)s_op->req->u.seteattr.key[i].buffer);
  159.         valBuf = (char *)s_op->req->u.seteattr.val[i].buffer;
  160.         for (j=0; j<s_op->req->u.seteattr.val[i].buffer_sz; j++)
  161.             gossip_debug(GOSSIP_MIRROR_DEBUG,"\tval[%d]=%#x\n"
  162.                                             ,j
  163.                                             ,(unsigned int)valBuf[j]);
  164.         js_p->error_code = PINT_eattr_namespace_verify(
  165.             &s_op->req->u.seteattr.key[i],
  166.             &s_op->req->u.seteattr.val[i]);
  167.  
  168.         if(js_p->error_code)
  169.         {
  170.             return SM_ACTION_COMPLETE;
  171.         }
  172.  
  173.     } /*end for*/
  174.  
  175.  
  176.     return SM_ACTION_COMPLETE;
  177. }
  178.  
  179. /*
  180.  * This is where the actual extended attrib gets written.
  181.  * Not much to this, its pretty straight-forward.
  182.  * 
  183.  * NOTE: we need to check the value of s_op->req->u.seteattr.flags to determine
  184.  * the following:
  185.  *
  186.  * if (flags & PVFS_XATTR_CREATE)
  187.  *  we need to make sure that the attribute does not exist. (pure create)
  188.  * else if (flags & PVFS_XATTR_REPLACE)
  189.  *  we need to make sure that the attribute does exist. (pure replace)
  190.  * else it is default operation as before.
  191.  * We translate this to an internal trove flag 
  192.  *  (TROVE_NOOVERWRITE, TROVE_ONLYOVERWRITE)
  193.  */
  194. static int seteattr_setobj_eattribs(
  195.         struct PINT_smcb *smcb, job_status_s *js_p)
  196. {
  197.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  198.     int ret = 0;
  199.     PVFS_ds_flags trove_flags = 0;
  200.     job_id_t j_id;
  201.  
  202.     gossip_debug(
  203.         GOSSIP_SETEATTR_DEBUG,
  204.         "  writing keylist [%llu,%d,len %d flags %d]\n",
  205.         llu(s_op->req->u.seteattr.handle),
  206.         s_op->req->u.seteattr.fs_id,
  207.         s_op->req->u.seteattr.nkey, s_op->req->u.seteattr.flags);
  208.  
  209.     if (s_op->req->u.seteattr.flags & PVFS_XATTR_CREATE)
  210.     {
  211.         trove_flags = TROVE_NOOVERWRITE;
  212.     }
  213.     else if (s_op->req->u.seteattr.flags & PVFS_XATTR_REPLACE)
  214.     {
  215.         trove_flags = TROVE_ONLYOVERWRITE;
  216.     }
  217.     trove_flags |= TROVE_SYNC;
  218.  
  219.     ret = job_trove_keyval_write_list(
  220.         s_op->req->u.seteattr.fs_id,
  221.         s_op->req->u.seteattr.handle,
  222.         s_op->req->u.seteattr.key,
  223.         s_op->req->u.seteattr.val,
  224.         s_op->req->u.seteattr.nkey,
  225.         trove_flags,
  226.         NULL,
  227.         smcb,
  228.         0,
  229.         js_p,
  230.         &j_id,
  231.         server_job_context, s_op->req->hints);
  232.  
  233.     return ret;
  234. }
  235.  
  236. /*This function determines if the meta-hint flag should be updated and 
  237.  *retrieves it, if necessary.
  238. */
  239. static PINT_sm_action seteattr_get_metahint_flag(struct PINT_smcb *smcb
  240.                                                 ,job_status_s *js_p)
  241. {
  242.    gossip_debug(GOSSIP_MIRROR_DEBUG,"Executing %s ...\n",__func__);
  243.  
  244.    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  245.    struct PVFS_servreq_seteattr *seteattr = &(s_op->req->u.seteattr);
  246.    char mir_mode_key[] = USER_PVFS2_MIRROR_MODE;
  247.    char meta_hint_key[] = "user.pvfs2.meta_hint";
  248.    int ret = 0;
  249.    job_id_t j_id;
  250.    int i;
  251.  
  252.    for (i=0; i<seteattr->nkey; i++)
  253.    {
  254.     if (strncmp(mir_mode_key,seteattr->key[i].buffer,strlen(mir_mode_key)) == 0)
  255.     {
  256.        break;
  257.     }
  258.    }
  259.  
  260.    if (i == seteattr->nkey)
  261.    {
  262.        /*mirror.mode key not found, so we don't need to change meta-hint*/
  263.        js_p->error_code = SKIP_UPDATE;
  264.        return SM_ACTION_COMPLETE;
  265.    }
  266.  
  267.    /*setup call to retrieve meta-hint*/
  268.    init_keyval_structs(s_op,s_op->free_val);
  269.  
  270.    /*setup key for user.pvfs2.meta_hint*/
  271.    s_op->key.buffer = malloc(strlen(meta_hint_key) + 1);
  272.    if (!s_op->key.buffer)
  273.    {
  274.        gossip_lerr("Cannot allocation memory for key.buffer\n");
  275.        js_p->error_code = -PVFS_ENOMEM;
  276.        goto error_exit;
  277.    }
  278.    memset(s_op->key.buffer,0,strlen(meta_hint_key) + 1);
  279.    memcpy(s_op->key.buffer,meta_hint_key,strlen(meta_hint_key));
  280.    s_op->key.buffer_sz = strlen(meta_hint_key) + 1;
  281.  
  282.    /*assign space for key retrieval*/
  283.    s_op->val.buffer = &(s_op->attr.u.meta.hint.flags);
  284.    memset(s_op->val.buffer,0,sizeof(s_op->attr.u.meta.hint.flags));
  285.    s_op->val.buffer_sz = sizeof(s_op->attr.u.meta.hint.flags);
  286.    s_op->free_val = 0;
  287.  
  288.    /*retrieve meta-hint key/value pair*/
  289.    ret = job_trove_keyval_read(
  290.        seteattr->fs_id,
  291.        seteattr->handle,
  292.        &s_op->key,
  293.        &s_op->val,
  294.        TROVE_SYNC,
  295.        NULL,
  296.        smcb,
  297.        0,
  298.        js_p,
  299.        &j_id,
  300.        server_job_context,
  301.        s_op->req->hints);
  302.  
  303.    return ret;
  304.  
  305. error_exit:
  306.    init_keyval_structs(s_op,s_op->free_val);
  307.  
  308.    return SM_ACTION_COMPLETE;
  309. }/*end seteattr_get_metahint_flag*/
  310.  
  311.  
  312. /*This function updates the meta-hint flag, whenever the mirroring mode  
  313.  *changes.
  314. */
  315. static PINT_sm_action seteattr_set_metahint_flag(struct PINT_smcb *smcb
  316.                                                 ,job_status_s *js_p)
  317. {
  318.    gossip_debug(GOSSIP_MIRROR_DEBUG,"Executing %s ...\n",__func__);
  319.  
  320.    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  321.    struct PVFS_servreq_seteattr *seteattr = &(s_op->req->u.seteattr);
  322.    char mir_mode_key[] = USER_PVFS2_MIRROR_MODE;
  323.    char meta_hint_key[] = "user.pvfs2.meta_hint";
  324.    enum MIRROR_MODE_t mir_mode;
  325.    PVFS_flags *hint_flags = &(s_op->attr.u.meta.hint.flags);
  326.    PVFS_flags flags = 0;
  327.    int ret = 0;
  328.    job_id_t j_id;
  329.    int i;
  330.  
  331.    gossip_debug(GOSSIP_MIRROR_DEBUG,"\tCurrent value of hints:%0x\n"
  332.                                    ,(unsigned int)*hint_flags);
  333.    gossip_debug(GOSSIP_MIRROR_DEBUG,"\tAttribute object type:%d\n"
  334.                                    ,s_op->attr.objtype);
  335.    gossip_debug(GOSSIP_MIRROR_DEBUG,"\tAttribute mask:%x\n"
  336.                                    ,s_op->attr.mask);
  337.    /*check return code: if we have an error other than a not found condition,
  338.     *then return the error; otherwise, keep processing.
  339.    */
  340.    if (js_p->error_code < 0 && js_p->error_code != -TROVE_ENOENT)
  341.       return SM_ACTION_COMPLETE;
  342.  
  343.    for (i=0; i<seteattr->nkey; i++)
  344.    {
  345.     if (strncmp(mir_mode_key,seteattr->key[i].buffer,strlen(mir_mode_key)) == 0)
  346.     {
  347.        mir_mode = *(enum MIRROR_MODE_t *)seteattr->val[i].buffer;
  348.        gossip_debug(GOSSIP_MIRROR_DEBUG,"\tMirroring Mode is %d.\n"
  349.                                        ,mir_mode);
  350.        if (mir_mode == NO_MIRRORING)
  351.            /*turn off mirroring*/
  352.            flags = *hint_flags & ~PVFS_MIRROR_FL;
  353.        else
  354.            /*turn on mirroring*/
  355.            flags = *hint_flags | PVFS_MIRROR_FL;
  356.        break;
  357.     }
  358.    }
  359.  
  360.    gossip_debug(GOSSIP_MIRROR_DEBUG,"\tValue of flags:%0x\n"
  361.                                    ,(unsigned int)flags);
  362.  
  363.    /*setup job to modify user.pvfs2.meta-hints flag*/
  364.    init_keyval_structs(s_op,s_op->free_val);
  365.    s_op->keyval_count = 1;
  366.  
  367.    s_op->key_a = malloc(sizeof(PVFS_ds_keyval) * s_op->keyval_count);
  368.    s_op->val_a = malloc(sizeof(PVFS_ds_keyval) * s_op->keyval_count);
  369.    if (!(s_op->key_a && s_op->val_a))
  370.    {
  371.       gossip_lerr("Cannot allocate memory for key_a and/or val_a\n");
  372.       js_p->error_code = -PVFS_ENOMEM;
  373.       goto error_exit;
  374.    }
  375.  
  376.    i=0; /*setup key user.pvfs2.meta_hint*/
  377.    s_op->key_a[i].buffer = malloc(strlen(meta_hint_key) + 1);
  378.    if (!s_op->key_a[i].buffer)
  379.    {
  380.        gossip_lerr("Cannot allocation memory for key_a[%d].buffer\n",i);
  381.        js_p->error_code = -PVFS_ENOMEM;
  382.        goto error_exit;
  383.    }
  384.    memset(s_op->key_a[i].buffer,0,strlen(meta_hint_key) + 1);
  385.    memcpy(s_op->key_a[i].buffer,meta_hint_key,strlen(meta_hint_key));
  386.    s_op->key_a[i].buffer_sz = strlen(meta_hint_key) + 1;
  387.  
  388.    /*add/remove PVFS_MIRROR_FL from user.pvfs2.meta_hint*/
  389.    s_op->val_a[i].buffer = malloc(sizeof(PVFS_flags));
  390.    if (!s_op->val_a[i].buffer)
  391.    {
  392.       gossip_lerr("Cannot allocate memory for val_a[%d].buffer\n",i);
  393.       js_p->error_code = -PVFS_ENOMEM;
  394.       goto error_exit;
  395.    }
  396.    memset(s_op->val_a[i].buffer,0,sizeof(PVFS_flags));
  397.    memcpy(s_op->val_a[i].buffer,&flags,sizeof(PVFS_flags));
  398.    s_op->val_a[i].buffer_sz = sizeof(PVFS_flags);
  399.  
  400.    s_op->free_val = 1;
  401.  
  402.    /*make update to key/value pair*/
  403.    ret = job_trove_keyval_write_list(
  404.        seteattr->fs_id,
  405.        seteattr->handle,
  406.        s_op->key_a,
  407.        s_op->val_a,
  408.        s_op->keyval_count,
  409.        TROVE_SYNC,
  410.        NULL,
  411.        smcb,
  412.        0,
  413.        js_p,
  414.        &j_id,
  415.        server_job_context,
  416.        s_op->req->hints);
  417.    
  418.    return ret;
  419.  
  420. error_exit:
  421.    init_keyval_structs(s_op,s_op->free_val);
  422.    return SM_ACTION_COMPLETE;
  423. }/*end seteattr_set_metahint_flag*/
  424.  
  425.  
  426.  
  427.  
  428.  
  429. static PINT_sm_action setup_create_immutable_copies(struct PINT_smcb *smcb
  430.                                                    ,job_status_s *js_p)
  431. {
  432.     gossip_debug(GOSSIP_MIRROR_DEBUG,"Executing setup_create_immutable_copies.."
  433.                                      "\n");
  434.     struct PINT_server_op *s_op = PINT_sm_frame(smcb,PINT_FRAME_CURRENT);
  435.     int ret;
  436.   
  437.     js_p->error_code = 0;
  438.  
  439.     struct PINT_server_op *new_op = malloc(sizeof(struct PINT_server_op));
  440.     if (!new_op)
  441.     {
  442.         js_p->error_code = -PVFS_ENOMEM;
  443.         return SM_ACTION_COMPLETE;
  444.     }
  445.     memset(new_op,0,sizeof(struct PINT_server_op));
  446.  
  447.     PVFS_SERVOP_IMM_COPIES_FILL(new_op,s_op);
  448.     new_op->u.create_copies.expected_mirror_mode = MIRROR_ON_IMMUTABLE;
  449.  
  450.     ret = PINT_sm_push_frame(smcb,CREATE_IMM_COPIES,new_op);
  451.     if (ret != 0)
  452.     {
  453.        gossip_debug(GOSSIP_MIRROR_DEBUG,"\tseteattr: failed to setup "
  454.                                         "nested sm.\n");
  455.        js_p->error_code = ret;
  456.     }
  457.  
  458.     gossip_debug(GOSSIP_MIRROR_DEBUG,"\tseteattr:s_op:%p "
  459.                                      "\tnew_op:%p\n",s_op,new_op);
  460.     return SM_ACTION_COMPLETE;
  461. }/*end action setup_create_immutable_copies*/
  462.  
  463.  
  464. static PINT_sm_action inspect_imm_copies(struct PINT_smcb *smcb
  465.                                         ,job_status_s *js_p)
  466. {
  467.     gossip_debug(GOSSIP_MIRROR_DEBUG,"Executing inspect_imm_copies....\n");
  468.  
  469.     struct PINT_server_op *s_op   = PINT_sm_frame(smcb,PINT_FRAME_CURRENT)
  470.                          ,*imm_op = NULL;
  471.     int task_id, error_code, remaining;
  472.  
  473.     /*js_p->error_code will be zero upon entering this function*/
  474.  
  475.     /*error_code will have the value returned in js_p->error_code via the */
  476.     /*cleanup function in create-immutable-copies.sm                      */
  477.     imm_op = PINT_sm_pop_frame(smcb, &task_id, &error_code, &remaining);
  478.  
  479.     assert(imm_op->op == PVFS_SERV_IMM_COPIES);
  480.  
  481.     /*check error codes from mirror copies*/
  482.     gossip_debug(GOSSIP_MIRROR_DEBUG,"\tstatus of copies:%d\n",error_code);    
  483.  
  484.     if ( PVFS_get_errno_mapping(error_code) == EPERM )
  485.     {
  486.         /*If EPERM, then create-immutable-copies detected that the  */
  487.         /*mirror mode is NO_MIRRORING or the mode didn't exist.     */
  488.         js_p->error_code = 0;
  489.     } else {
  490.       /*set error_code based on return from copies.                   */
  491.       /*this error_code will then be passed to the caller of set-eattr*/
  492.       js_p->error_code = error_code;
  493.     }
  494.  
  495.     gossip_debug(GOSSIP_MIRROR_DEBUG,"\tfrom pop, imm_op:%p\n"
  496.                                     ,imm_op);
  497.  
  498.     gossip_debug(GOSSIP_MIRROR_DEBUG,"\tcurrent, s_op:%p\n",s_op);
  499.  
  500.     if (js_p->error_code)
  501.     {
  502.        gossip_debug(GOSSIP_MIRROR_DEBUG,"File NOT mirrored "
  503.                                         "successfully(%d)\n"
  504.                                        ,js_p->error_code);
  505.     }
  506.     else
  507.     {
  508.        gossip_debug(GOSSIP_MIRROR_DEBUG,"File successfully mirrored.\n");
  509.     }
  510.  
  511.     /*free memory from popped stack frame*/
  512.     free(imm_op);
  513.  
  514.     return SM_ACTION_COMPLETE;
  515. }/*end action inspect_imm_copies*/
  516.  
  517.  
  518.  
  519.  
  520. /*
  521.  * Function: check_immutable
  522.  *
  523.  * Params:   server_op *b, 
  524.  *           job_status_s *js_p
  525.  *
  526.  * Returns:  SM_action
  527.  *
  528.  * Synopsis: If the immutable flag is set, then make a mirror.
  529.  *           
  530.  */
  531. static PINT_sm_action check_immutable(struct PINT_smcb *smcb
  532.                                          ,job_status_s *js_p)
  533. {
  534.     gossip_debug(GOSSIP_MIRROR_DEBUG,"Executing check_immutable....\n");
  535.  
  536.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  537.     int i; 
  538.  
  539.     PVFS_flags         immutable_is_on = 0;
  540.     PVFS_metafile_hint hint;
  541.     PVFS_ds_keyval    *k=NULL, *v=NULL;
  542.  
  543.     js_p->error_code = 0;
  544.    
  545.     for (i = 0; i < s_op->req->u.seteattr.nkey; i++)
  546.     {
  547.         v = &s_op->req->u.seteattr.val[i];
  548.         k = &s_op->req->u.seteattr.key[i];
  549.  
  550.         /* Are we working with the correct namespace?  The immutable flag is */
  551.         /* a hint that can be set in the "user.pvfs2.meta_hint" namespace.   */
  552.         if (strcmp(k->buffer,"user.pvfs2.meta_hint") != 0){
  553.             continue;
  554.         }
  555.  
  556.         memset(&hint, 0, sizeof(hint));
  557.         memcpy(&hint, v->buffer, sizeof(v->buffer));
  558.  
  559.         gossip_debug(GOSSIP_MIRROR_DEBUG,"My converted buffer is %llu.\n"
  560.                                         ,llu(hint.flags));
  561.  
  562.         immutable_is_on = hint.flags & PVFS_IMMUTABLE_FL;
  563.  
  564.         gossip_debug(GOSSIP_MIRROR_DEBUG
  565.                      ,"My key is %s.  My key value is %llu"
  566.                       "\n"
  567.                       "PVFS_IMMUTABLE_FL is %llu.\n"
  568.                      ,(char *)k->buffer
  569.                      ,llu(hint.flags)
  570.                      ,llu(PVFS_IMMUTABLE_FL) );
  571.         gossip_debug(GOSSIP_MIRROR_DEBUG,"immutable_is_on is %llu.\n"
  572.                                         ,llu(immutable_is_on));
  573.         gossip_debug(GOSSIP_MIRROR_DEBUG,"IMMUTABLE is %s.\n",
  574.                                           immutable_is_on ? "ON" : "OFF");
  575.  
  576.         if (immutable_is_on){
  577.             js_p->error_code = PVFS2_MAKE_IMMUTABLE_COPIES;
  578.             break; 
  579.         }
  580.     } /*end for*/
  581.  
  582.     return SM_ACTION_COMPLETE;
  583. }/*end action check_immutable*/
  584.  
  585.  
  586.  
  587.  
  588. /*
  589.  * Function: setattr_cleanup
  590.  *
  591.  * Params:   server_op *b, 
  592.  *           job_status_s *js_p
  593.  *
  594.  * Returns:  int
  595.  *
  596.  * Synopsis: free memory and return
  597.  *           
  598.  */
  599. static int seteattr_cleanup(
  600.         struct PINT_smcb *smcb, job_status_s *js_p)
  601. {
  602.     PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  603.  
  604.     /*free key/val structs from the s_op*/
  605.     init_keyval_structs(s_op,s_op->free_val);
  606.  
  607.  
  608.     return(server_state_machine_complete(smcb));
  609. }
  610.  
  611. /*This function initializes the keyval structures. It also assumes that the key
  612.  *is always allocated, while the val may not be.  free_val is turned on, if
  613.  *the val must be deallocated; otherwise, val is not deallocated, just initial-
  614.  *ized.
  615. */
  616. static void init_keyval_structs(PINT_server_op *s_op, int free_val)
  617. {
  618.    int i;
  619.  
  620.    /*initialize val*/
  621.    if (free_val)
  622.    {
  623.       if (s_op->val.buffer)
  624.       {
  625.          free(s_op->val.buffer);
  626.          memset(&(s_op->val),0,sizeof(PVFS_ds_keyval));
  627.       }
  628.       memset(&(s_op->val),0,sizeof(PVFS_ds_keyval));
  629.       for (i=0; i<s_op->keyval_count; i++)
  630.       {
  631.           if (s_op->val_a && s_op->val_a[i].buffer)
  632.               free(s_op->val_a[i].buffer);
  633.       }
  634.       if (s_op->val_a)
  635.           free(s_op->val_a);
  636.       s_op->val_a = NULL;
  637.    } 
  638.    else
  639.    {
  640.       memset(&(s_op->val),0,sizeof(PVFS_ds_keyval));
  641.       if (s_op->val_a)
  642.           free(s_op->val_a);
  643.       s_op->val_a = NULL;
  644.    }
  645.  
  646.    /*initialize key*/
  647.    if (s_op->key.buffer)
  648.    {
  649.       free(s_op->key.buffer);
  650.       memset(&(s_op->key),0,sizeof(PVFS_ds_keyval));
  651.    }
  652.    for (i=0; i<s_op->keyval_count; i++)
  653.    {
  654.        if (s_op->key_a && s_op->key_a[i].buffer)
  655.            free(s_op->key_a[i].buffer);
  656.    }
  657.    if (s_op->key_a)
  658.    {
  659.        free(s_op->key_a);
  660.        s_op->key_a = NULL;
  661.    } 
  662.  
  663.    /*initialize the rest*/
  664.    if (s_op->error_a)
  665.        free(s_op->error_a);
  666.    s_op->error_a = NULL;
  667.    s_op->keyval_count = 0;
  668.    s_op->free_val = 0;
  669.  
  670.    return;
  671. }/*end init_keyval_structs*/
  672.  
  673.  
  674.  
  675. PINT_GET_OBJECT_REF_DEFINE(seteattr);
  676.  
  677. struct PINT_server_req_params pvfs2_set_eattr_params =
  678. {
  679.     .string_name = "set_eattr",
  680.     .perm = PINT_SERVER_CHECK_ATTR,
  681.     .access_type = PINT_server_req_modify,
  682.     .sched_policy = PINT_SERVER_REQ_SCHEDULE,
  683.     .get_object_ref = PINT_get_object_ref_seteattr,
  684.     .state_machine = &pvfs2_set_eattr_sm
  685. };
  686.  
  687. /*
  688.  * Local variables:
  689.  *  mode: c
  690.  *  c-indent-level: 4
  691.  *  c-basic-offset: 4
  692.  * End:
  693.  *
  694.  * vim: ft=c ts=8 sts=4 sw=4 expandtab
  695.  */
  696.