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-symlink.sm < prev    next >
Text File  |  2008-11-19  |  17KB  |  627 lines

  1. /*
  2.  * (C) 2003 Clemson University and The University of Chicago
  3.  *
  4.  * See COPYING in top-level directory.
  5.  */
  6.  
  7. /** \file
  8.  *  \ingroup sysint
  9.  *
  10.  *  PVFS2 system interface routines for creating symlinks.
  11.  */
  12.  
  13. #include <string.h>
  14. #include <assert.h>
  15.  
  16. #include "client-state-machine.h"
  17. #include "pvfs2-debug.h"
  18. #include "job.h"
  19. #include "gossip.h"
  20. #include "str-utils.h"
  21. #include "pint-cached-config.h"
  22. #include "PINT-reqproto-encode.h"
  23. #include "pint-util.h"
  24. #include "ncache.h"
  25. #include "pvfs2-internal.h"
  26.  
  27. extern job_context_id pint_client_sm_context;
  28.  
  29. enum
  30. {
  31.     SYMLINK_RETRY = 170
  32. };
  33.  
  34. static int symlink_create_comp_fn(
  35.     void *v_p, struct PVFS_server_resp *resp_p, int index);
  36. static int symlink_setattr_comp_fn(
  37.     void *v_p, struct PVFS_server_resp *resp_p, int index);
  38. static int symlink_crdirent_comp_fn(
  39.     void *v_p, struct PVFS_server_resp *resp_p, int index);
  40. static int symlink_delete_handle_comp_fn(
  41.     void *v_p, struct PVFS_server_resp *resp_p, int index);
  42.  
  43. %%
  44.  
  45. machine pvfs2_client_symlink_sm
  46. {
  47.     state init
  48.     {
  49.         run symlink_init;
  50.         default => symlink_parent_getattr;
  51.     }
  52.  
  53.     state symlink_parent_getattr
  54.     {
  55.         jump pvfs2_client_getattr_sm;
  56.         success => dspace_create_setup_msgpair;
  57.         default => cleanup;
  58.     }
  59.  
  60.     state dspace_create_setup_msgpair
  61.     {
  62.         run symlink_dspace_create_setup_msgpair;
  63.         success => dspace_create_xfer_msgpair;
  64.         default => dspace_create_failure;
  65.     }
  66.  
  67.     state dspace_create_xfer_msgpair
  68.     {
  69.         jump pvfs2_msgpairarray_sm;
  70.         success => symlink_setattr_setup_msgpair;
  71.         default => dspace_create_failure;
  72.     }
  73.  
  74.     state dspace_create_failure
  75.     {
  76.         run symlink_dspace_create_failure;
  77.         default => cleanup;
  78.     }
  79.  
  80.     state symlink_setattr_setup_msgpair
  81.     {
  82.         run symlink_setattr_setup_msgpair;
  83.         success => symlink_setattr_xfer_msgpair;
  84.         default => cleanup;
  85.     }
  86.  
  87.     state symlink_setattr_xfer_msgpair
  88.     {
  89.         jump pvfs2_msgpairarray_sm;
  90.         success => crdirent_setup_msgpair;
  91.         default => symlink_setattr_failure;
  92.     }
  93.  
  94.     state symlink_setattr_failure
  95.     {
  96.         run symlink_setattr_failure;
  97.         default => delete_handle_setup_msgpair;
  98.     }
  99.  
  100.     state crdirent_setup_msgpair
  101.     {
  102.         run symlink_crdirent_setup_msgpair;
  103.         success => crdirent_xfer_msgpair;
  104.         default => crdirent_failure;
  105.     }
  106.  
  107.     state crdirent_xfer_msgpair
  108.     {
  109.         jump pvfs2_msgpairarray_sm;
  110.         success => cleanup;
  111.         default => crdirent_failure;
  112.     }
  113.  
  114.     state crdirent_failure
  115.     {
  116.         run symlink_crdirent_failure;
  117.         default => delete_handle_setup_msgpair;
  118.     }
  119.  
  120.     state delete_handle_setup_msgpair
  121.     {
  122.         run symlink_delete_handle_setup_msgpair;
  123.         success => delete_handle_xfer_msgpair;
  124.         default => cleanup;
  125.     }
  126.  
  127.     state delete_handle_xfer_msgpair
  128.     {
  129.         jump pvfs2_msgpairarray_sm;
  130.         default => cleanup;
  131.     }
  132.  
  133.     state cleanup
  134.     {
  135.         run symlink_cleanup;
  136.         SYMLINK_RETRY => init;
  137.         default => terminate;
  138.     }
  139. }
  140.  
  141. %%
  142.  
  143. /** Initiate creation of a new symlink object on some server.
  144.  */
  145. PVFS_error PVFS_isys_symlink(
  146.     char *entry_name,
  147.     PVFS_object_ref parent_ref,
  148.     char *target,
  149.     PVFS_sys_attr attr,
  150.     const PVFS_credentials *credentials,
  151.     PVFS_sysresp_symlink *resp,
  152.     PVFS_sys_op_id *op_id,
  153.     PVFS_hint hints,
  154.     void *user_ptr)
  155. {
  156.     PVFS_error ret = -PVFS_EINVAL;
  157.     PINT_smcb *smcb = NULL;
  158.     PINT_client_sm *sm_p = NULL;
  159.  
  160.     gossip_debug(GOSSIP_CLIENT_DEBUG, "PVFS_isys_symlink entered\n");
  161.  
  162.     if ((parent_ref.handle == PVFS_HANDLE_NULL) ||
  163.         (parent_ref.fs_id == PVFS_FS_ID_NULL) ||
  164.         (entry_name == NULL) || (resp == NULL) || (target == NULL))
  165.     {
  166.         gossip_err("invalid (NULL) required argument\n");
  167.         return ret;
  168.     }
  169.  
  170.     if ((attr.mask & PVFS_ATTR_SYS_ALL_SETABLE) !=
  171.         PVFS_ATTR_SYS_ALL_SETABLE)
  172.     {
  173.         gossip_lerr("PVFS_isys_symlink() failure: invalid attributes "
  174.                     "specified\n");
  175.         return ret;
  176.     }
  177.  
  178.     if (((strlen(entry_name) + 1) > PVFS_REQ_LIMIT_SEGMENT_BYTES) ||
  179.         ((strlen(target) + 1) > PVFS_REQ_LIMIT_SEGMENT_BYTES))
  180.     {
  181.         return -PVFS_ENAMETOOLONG;
  182.     }
  183.  
  184.     PINT_smcb_alloc(&smcb, PVFS_SYS_SYMLINK,
  185.              sizeof(struct PINT_client_sm),
  186.              client_op_state_get_machine,
  187.              client_state_machine_terminate,
  188.              pint_client_sm_context);
  189.     if (smcb == NULL)
  190.     {
  191.         return -PVFS_ENOMEM;
  192.     }
  193.     sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  194.  
  195.     PINT_init_msgarray_params(sm_p, parent_ref.fs_id);
  196.     PINT_init_sysint_credentials(sm_p->cred_p, credentials);
  197.     sm_p->u.sym.link_name = entry_name;
  198.     sm_p->u.sym.link_target = target;
  199.     sm_p->u.sym.sym_resp = resp;
  200.     PVFS_util_copy_sys_attr(&sm_p->u.sym.sys_attr, &attr);
  201.     sm_p->u.sym.stored_error_code = 0;
  202.     sm_p->u.sym.retry_count = 0;
  203.     sm_p->object_ref = parent_ref;
  204.     PVFS_hint_copy(hints, &sm_p->hints);
  205.  
  206.     gossip_debug(
  207.         GOSSIP_CLIENT_DEBUG, "Symlinking %s under parent handle %llu "
  208.         "on fs %d to %s\n", entry_name, llu(parent_ref.handle),
  209.         parent_ref.fs_id, target);
  210.  
  211.     return PINT_client_state_machine_post(
  212.         smcb,  op_id, user_ptr);
  213. }
  214.  
  215. /** Create a new symlink object on some server.
  216.  */
  217. PVFS_error PVFS_sys_symlink(
  218.     char *entry_name,
  219.     PVFS_object_ref parent_ref,
  220.     char *target,
  221.     PVFS_sys_attr attr,
  222.     const PVFS_credentials *credentials,
  223.     PVFS_sysresp_symlink *resp,
  224.     PVFS_hint hints)
  225. {
  226.     PVFS_error ret = -PVFS_EINVAL, error = 0;
  227.     PVFS_sys_op_id op_id;
  228.  
  229.     gossip_debug(GOSSIP_CLIENT_DEBUG, "PVFS_sys_symlink entered\n");
  230.  
  231.     ret = PVFS_isys_symlink(entry_name, parent_ref, target, attr,
  232.                             credentials, resp, &op_id, hints, NULL);
  233.     if (ret)
  234.     {
  235.         PVFS_perror_gossip("PVFS_isys_symlink call", ret);
  236.         error = ret;
  237.     }
  238.     else
  239.     {
  240.         ret = PVFS_sys_wait(op_id, "symlink", &error);
  241.         if (ret)
  242.         {
  243.             PVFS_perror_gossip("PVFS_sys_wait call", ret);
  244.             error = ret;
  245.         }
  246.     }
  247.  
  248.     PINT_sys_release(op_id);
  249.     return error;
  250. }
  251.  
  252. /****************************************************************/
  253.  
  254. static PINT_sm_action symlink_init(
  255.     struct PINT_smcb *smcb, job_status_s *js_p)
  256. {
  257.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  258.     int ret = 1;
  259.     job_id_t tmp_id;
  260.  
  261.     assert((js_p->error_code == 0) ||
  262.            (js_p->error_code == SYMLINK_RETRY));
  263.  
  264.     if (js_p->error_code == SYMLINK_RETRY)
  265.     {
  266.         js_p->error_code = 0;
  267.  
  268.         ret = job_req_sched_post_timer(
  269.             sm_p->msgarray_op.params.retry_delay, smcb, 0, js_p, &tmp_id,
  270.             pint_client_sm_context);
  271.     }
  272.  
  273.     PINT_SM_GETATTR_STATE_FILL(
  274.         sm_p->getattr,
  275.         sm_p->object_ref,
  276.         PVFS_ATTR_COMMON_ALL,
  277.         PVFS_TYPE_DIRECTORY,
  278.         0);
  279.  
  280.     return ret;
  281. }
  282.  
  283. static int symlink_create_comp_fn(void *v_p,
  284.                                   struct PVFS_server_resp *resp_p,
  285.                                   int index)
  286. {
  287.     PINT_smcb *smcb = v_p;
  288.     PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_MSGPAIR_PARENT_SM);
  289.  
  290.     gossip_debug(GOSSIP_CLIENT_DEBUG, "symlink_create_comp_fn\n");
  291.  
  292.     assert(resp_p->op == PVFS_SERV_BATCH_CREATE);
  293.  
  294.     if (resp_p->status != 0)
  295.     {
  296.         return resp_p->status;
  297.     }
  298.  
  299.     /* otherwise, just store the newly symlink'd meta handle */
  300.  
  301.     if(resp_p->u.batch_create.handle_count != 1)
  302.     {
  303.         gossip_err("We requested one metafile handle for the symlink, "
  304.                    "but we got %d.\n",
  305.                    resp_p->u.batch_create.handle_count);
  306.         return -PVFS_EINVAL;
  307.     }
  308.  
  309.     sm_p->u.sym.symlink_handle = resp_p->u.batch_create.handle_array[0];
  310.  
  311.     gossip_debug(GOSSIP_CLIENT_DEBUG, "*** Got newly created symlink "
  312.                  "handle %llu\n", llu(sm_p->u.sym.symlink_handle));
  313.     return 0;
  314. }
  315.  
  316. static int symlink_setattr_comp_fn(void *v_p,
  317.                                   struct PVFS_server_resp *resp_p,
  318.                                   int index)
  319. {
  320.     PINT_smcb *smcb = v_p;
  321.     PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_MSGPAIR_PARENT_SM);
  322.     PVFS_object_attr attr;
  323.     PVFS_object_ref tmp_ref;
  324.  
  325.     tmp_ref.handle = sm_p->u.sym.symlink_handle;
  326.     tmp_ref.fs_id = sm_p->object_ref.fs_id;
  327.  
  328.     gossip_debug(GOSSIP_CLIENT_DEBUG, "symlink_setattr_comp_fn\n");
  329.  
  330.     if(resp_p->status == 0)
  331.     {
  332.         PINT_CONVERT_ATTR(&attr, &sm_p->u.sym.sys_attr, 0);
  333.         PINT_acache_update(tmp_ref, &attr, NULL);
  334.     }
  335.  
  336.     assert(resp_p->op == PVFS_SERV_SETATTR);
  337.     return resp_p->status;
  338. }
  339.  
  340. static int symlink_crdirent_comp_fn(void *v_p,
  341.                                    struct PVFS_server_resp *resp_p,
  342.                                    int index)
  343. {
  344.     gossip_debug(GOSSIP_CLIENT_DEBUG, "symlink_crdirent_comp_fn\n");
  345.  
  346.     assert(resp_p->op == PVFS_SERV_CRDIRENT);
  347.     return resp_p->status;
  348. }
  349.  
  350. static int symlink_delete_handle_comp_fn(void *v_p,
  351.                                          struct PVFS_server_resp *resp_p,
  352.                                          int index)
  353. {
  354.     gossip_debug(GOSSIP_CLIENT_DEBUG, "symlink_delete_handle_comp_fn\n");
  355.  
  356.     assert(resp_p->op == PVFS_SERV_REMOVE);
  357.     return resp_p->status;
  358. }
  359.  
  360. static PINT_sm_action symlink_dspace_create_setup_msgpair(
  361.     struct PINT_smcb *smcb, job_status_s *js_p)
  362. {
  363.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  364.     int ret = -PVFS_EINVAL;
  365.     PVFS_handle_extent_array meta_handle_extent_array;
  366.     PINT_sm_msgpair_state *msg_p = NULL;
  367.  
  368.     js_p->error_code = 0;
  369.  
  370.     gossip_debug(GOSSIP_CLIENT_DEBUG," create: posting create req\n");
  371.  
  372.     PINT_msgpair_init(&sm_p->msgarray_op);
  373.     msg_p = &sm_p->msgarray_op.msgpair;
  374.  
  375.     ret = PINT_cached_config_get_next_meta(
  376.         sm_p->object_ref.fs_id,
  377.         &msg_p->svr_addr, &meta_handle_extent_array);
  378.  
  379.     if (ret)
  380.     {
  381.         gossip_err("Failed to map meta server address\n");
  382.         js_p->error_code = ret;
  383.         return SM_ACTION_COMPLETE;
  384.     }
  385.  
  386.     PINT_SERVREQ_BATCH_CREATE_FILL(
  387.         msg_p->req,
  388.         *sm_p->cred_p,
  389.         sm_p->object_ref.fs_id,
  390.         PVFS_TYPE_SYMLINK,
  391.         1,
  392.         meta_handle_extent_array,
  393.         sm_p->hints);
  394.  
  395.     msg_p->fs_id = sm_p->object_ref.fs_id;
  396.     msg_p->handle = meta_handle_extent_array.extent_array[0].first;
  397.     msg_p->retry_flag = PVFS_MSGPAIR_NO_RETRY;
  398.     msg_p->comp_fn = symlink_create_comp_fn;
  399.  
  400.     PINT_sm_push_frame(smcb, 0, &sm_p->msgarray_op);
  401.     return SM_ACTION_COMPLETE;
  402. }
  403.  
  404. static PINT_sm_action symlink_dspace_create_failure(
  405.     struct PINT_smcb *smcb, job_status_s *js_p)
  406. {
  407.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  408.     sm_p->u.sym.stored_error_code = js_p->error_code;
  409.  
  410.     return SM_ACTION_COMPLETE;
  411. }
  412.  
  413. static PINT_sm_action symlink_crdirent_setup_msgpair(
  414.     struct PINT_smcb *smcb, job_status_s *js_p)
  415. {
  416.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  417.     int ret = -PVFS_EINVAL;
  418.     PINT_sm_msgpair_state *msg_p = NULL;
  419.  
  420.     js_p->error_code = 0;
  421.  
  422.     gossip_debug(GOSSIP_CLIENT_DEBUG," symlink: posting crdirent req\n");
  423.  
  424.     PINT_msgpair_init(&sm_p->msgarray_op);
  425.     msg_p = &sm_p->msgarray_op.msgpair;
  426.  
  427.     PINT_SERVREQ_CRDIRENT_FILL(
  428.         msg_p->req,
  429.         *sm_p->cred_p,
  430.         sm_p->u.sym.link_name,
  431.         sm_p->u.sym.symlink_handle,
  432.         sm_p->object_ref.handle,
  433.         sm_p->object_ref.fs_id,
  434.         sm_p->hints);
  435.  
  436.     msg_p->fs_id = sm_p->object_ref.fs_id;
  437.     msg_p->handle = sm_p->object_ref.handle;
  438.     msg_p->retry_flag = PVFS_MSGPAIR_NO_RETRY;
  439.     msg_p->comp_fn = symlink_crdirent_comp_fn;
  440.  
  441.     ret = PINT_cached_config_map_to_server(
  442.         &msg_p->svr_addr, sm_p->object_ref.handle,
  443.         sm_p->object_ref.fs_id);
  444.  
  445.     if (ret)
  446.     {
  447.         gossip_err("Failed to map meta server address\n");
  448.         js_p->error_code = ret;
  449.     }
  450.  
  451.     PINT_sm_push_frame(smcb, 0, &sm_p->msgarray_op);
  452.     return SM_ACTION_COMPLETE;
  453. }
  454.  
  455. static PINT_sm_action symlink_crdirent_failure(
  456.     struct PINT_smcb *smcb, job_status_s *js_p)
  457. {
  458.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  459.     sm_p->u.sym.stored_error_code = js_p->error_code;
  460.  
  461.     PVFS_perror_gossip("crdirent failure", js_p->error_code);
  462.     return SM_ACTION_COMPLETE;
  463. }
  464.  
  465. static PINT_sm_action symlink_setattr_setup_msgpair(
  466.     struct PINT_smcb *smcb, job_status_s *js_p)
  467. {
  468.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  469.     int ret = -PVFS_EINVAL;
  470.     PINT_sm_msgpair_state *msg_p = NULL;
  471.  
  472.     js_p->error_code = 0;
  473.  
  474.     gossip_debug(GOSSIP_CLIENT_DEBUG," symlink: posting setattr req\n");
  475.  
  476.     PINT_msgpair_init(&sm_p->msgarray_op);
  477.     msg_p = &sm_p->msgarray_op.msgpair;
  478.  
  479.     /* force permissions to 777 for symbolic links */
  480.     sm_p->u.sym.sys_attr.perms = 0777;
  481.  
  482.     PINT_SERVREQ_SETATTR_FILL(
  483.         msg_p->req,
  484.         *sm_p->cred_p,
  485.         sm_p->object_ref.fs_id,
  486.         sm_p->u.sym.symlink_handle,
  487.         PVFS_TYPE_SYMLINK,
  488.         sm_p->u.sym.sys_attr,
  489.         PVFS_ATTR_SYMLNK_ALL,
  490.         sm_p->hints);
  491.  
  492.     /* fill in symlink specific attributes */
  493.     msg_p->req.u.setattr.attr.u.sym.target_path =
  494.         sm_p->u.sym.link_target;
  495.  
  496.     /* NOTE: path len always includes null terminator */
  497.     msg_p->req.u.setattr.attr.u.sym.target_path_len =
  498.         strlen(sm_p->u.sym.link_target) + 1;
  499.  
  500.     msg_p->fs_id = sm_p->object_ref.fs_id;
  501.     msg_p->handle = sm_p->u.sym.symlink_handle;
  502.     msg_p->retry_flag = PVFS_MSGPAIR_NO_RETRY;
  503.     msg_p->comp_fn = symlink_setattr_comp_fn;
  504.  
  505.     ret = PINT_cached_config_map_to_server(
  506.         &msg_p->svr_addr, msg_p->handle, msg_p->fs_id);
  507.  
  508.     if (ret)
  509.     {
  510.         gossip_err("Failed to map meta server address\n");
  511.         js_p->error_code = ret;
  512.     }
  513.  
  514.     PINT_sm_push_frame(smcb, 0, &sm_p->msgarray_op);
  515.     return SM_ACTION_COMPLETE;
  516. }
  517.  
  518. static PINT_sm_action symlink_setattr_failure(
  519.     struct PINT_smcb *smcb, job_status_s *js_p)
  520. {
  521.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  522.     sm_p->u.sym.stored_error_code = js_p->error_code;
  523.  
  524.     return SM_ACTION_COMPLETE;
  525. }
  526.  
  527. static PINT_sm_action symlink_delete_handle_setup_msgpair(
  528.     struct PINT_smcb *smcb, job_status_s *js_p)
  529. {
  530.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  531.     int ret = -PVFS_EINVAL;
  532.     PINT_sm_msgpair_state *msg_p = NULL;
  533.  
  534.     js_p->error_code = 0;
  535.  
  536.     PINT_msgpair_init(&sm_p->msgarray_op);
  537.     msg_p = &sm_p->msgarray_op.msgpair;
  538.  
  539.     PINT_SERVREQ_REMOVE_FILL(
  540.         msg_p->req,
  541.         *sm_p->cred_p,
  542.         sm_p->object_ref.fs_id,
  543.         sm_p->u.sym.symlink_handle,
  544.         sm_p->hints);
  545.  
  546.     msg_p->fs_id = sm_p->object_ref.fs_id;
  547.     msg_p->handle = sm_p->u.sym.symlink_handle;
  548.     msg_p->retry_flag = PVFS_MSGPAIR_NO_RETRY;
  549.     msg_p->comp_fn = symlink_delete_handle_comp_fn;
  550.  
  551.     gossip_debug(GOSSIP_CLIENT_DEBUG, " Preparing to remove "
  552.                  "metafile handle %llu\n", llu(msg_p->handle));
  553.  
  554.     ret = PINT_cached_config_map_to_server(
  555.         &msg_p->svr_addr, sm_p->u.sym.symlink_handle,
  556.         sm_p->object_ref.fs_id);
  557.  
  558.     if (ret)
  559.     {
  560.         gossip_err("Failed to map meta server address\n");
  561.         js_p->error_code = ret;
  562.     }
  563.  
  564.     PINT_sm_push_frame(smcb, 0, &sm_p->msgarray_op);
  565.     return SM_ACTION_COMPLETE;
  566. }
  567.  
  568. static PINT_sm_action symlink_cleanup(
  569.     struct PINT_smcb *smcb, job_status_s *js_p)
  570. {
  571.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  572.     PVFS_object_ref symlink_ref;
  573.  
  574.     memset(&symlink_ref, 0, sizeof(symlink_ref));
  575.  
  576.     PVFS_util_release_sys_attr(&sm_p->u.sym.sys_attr);
  577.  
  578.     sm_p->error_code = (sm_p->u.sym.stored_error_code ?
  579.                         sm_p->u.sym.stored_error_code :
  580.                         js_p->error_code);
  581.  
  582.     if (sm_p->error_code == 0)
  583.     {
  584.         symlink_ref.handle = sm_p->u.sym.symlink_handle;
  585.         symlink_ref.fs_id = sm_p->object_ref.fs_id;
  586.  
  587.         /* fill in outgoing response fields */
  588.         sm_p->u.sym.sym_resp->ref = symlink_ref;
  589.  
  590.         /* insert newly created symlink into the ncache */
  591.         PINT_ncache_update((const char*) sm_p->u.sym.link_name,
  592.                            (const PVFS_object_ref*) &symlink_ref,
  593.                            (const PVFS_object_ref*) &(sm_p->object_ref));
  594.     }
  595.     else if ((PVFS_ERROR_CLASS(-sm_p->error_code) == PVFS_ERROR_BMI) &&
  596.              (sm_p->u.sym.retry_count < sm_p->msgarray_op.params.retry_limit))
  597.     {
  598.         sm_p->u.sym.stored_error_code = 0;
  599.         sm_p->u.sym.retry_count++;
  600.  
  601.         gossip_debug(GOSSIP_CLIENT_DEBUG, "Retrying symlink operation "
  602.                      "(attempt number %d)\n", sm_p->u.sym.retry_count);
  603.  
  604.         js_p->error_code = SYMLINK_RETRY;
  605.         return SM_ACTION_COMPLETE;
  606.     }
  607.     else
  608.     {
  609.         PINT_acache_invalidate(sm_p->object_ref);
  610.     }
  611.  
  612.     PINT_msgpairarray_destroy(&sm_p->msgarray_op);
  613.  
  614.     PINT_SET_OP_COMPLETE;
  615.     return SM_ACTION_TERMINATE;
  616. }
  617.  
  618. /*
  619.  * Local variables:
  620.  *  mode: c
  621.  *  c-indent-level: 4
  622.  *  c-basic-offset: 4
  623.  * End:
  624.  *
  625.  * vim: ft=c ts=8 sts=4 sw=4 expandtab
  626.  */
  627.