"SfR Fresh" - the SfR Freeware/Shareware Archive

Member "pvfs-2.7.1/src/client/sysint/sys-mkdir.c" of archive pvfs-2.7.1.tar.gz:


As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
    1 /* WARNING: THIS FILE IS AUTOMATICALLY GENERATED FROM A .SM FILE.
    2  * Changes made here will certainly be overwritten.
    3  */
    4 
    5 /*
    6  * (C) 2003 Clemson University and The University of Chicago
    7  *
    8  * Changes by Acxiom Corporation to add setgid support
    9  * Copyright © Acxiom Corporation, 2005.
   10  *
   11  * See COPYING in top-level directory.
   12  */
   13 
   14 /** \file
   15  *  \ingroup sysint
   16  *
   17  *  PVFS2 system interface routines for creating a new directory.
   18  */
   19 
   20 #include <string.h>
   21 #include <assert.h>
   22 
   23 #include "client-state-machine.h"
   24 #include "pvfs2-debug.h"
   25 #include "job.h"
   26 #include "gossip.h"
   27 #include "str-utils.h"
   28 #include "pint-cached-config.h"
   29 #include "PINT-reqproto-encode.h"
   30 #include "pint-util.h"
   31 #include "ncache.h"
   32 #include "pvfs2-internal.h"
   33 
   34 extern job_context_id pint_client_sm_context;
   35 
   36 enum
   37 {
   38     MKDIR_RETRY = 180,
   39     MKDIR_SKIP_EATTR = 181
   40 };
   41 
   42 static int mkdir_msg_comp_fn(
   43     void *v_p, struct PVFS_server_resp *resp_p, int index);
   44 static int mkdir_crdirent_comp_fn(
   45     void *v_p, struct PVFS_server_resp *resp_p, int index);
   46 static int mkdir_delete_handle_comp_fn(
   47     void *v_p, struct PVFS_server_resp *resp_p, int index);
   48 
   49 
   50 static PINT_sm_action mkdir_init(
   51 	struct PINT_smcb *smcb, job_status_s *js_p);
   52 
   53 static struct PINT_state_s ST_init;
   54 static struct PINT_pjmp_tbl_s ST_init_pjtbl[];
   55 static struct PINT_tran_tbl_s ST_init_trtbl[];
   56 static struct PINT_state_s ST_parent_getattr;
   57 static struct PINT_pjmp_tbl_s ST_parent_getattr_pjtbl[];
   58 static struct PINT_tran_tbl_s ST_parent_getattr_trtbl[];
   59 
   60 static PINT_sm_action mkdir_parent_getattr_inspect(
   61 	struct PINT_smcb *smcb, job_status_s *js_p);
   62 
   63 static struct PINT_state_s ST_parent_getattr_inspect;
   64 static struct PINT_pjmp_tbl_s ST_parent_getattr_inspect_pjtbl[];
   65 static struct PINT_tran_tbl_s ST_parent_getattr_inspect_trtbl[];
   66 
   67 static PINT_sm_action mkdir_msg_setup_msgpair(
   68 	struct PINT_smcb *smcb, job_status_s *js_p);
   69 
   70 static struct PINT_state_s ST_mkdir_msg_setup_msgpair;
   71 static struct PINT_pjmp_tbl_s ST_mkdir_msg_setup_msgpair_pjtbl[];
   72 static struct PINT_tran_tbl_s ST_mkdir_msg_setup_msgpair_trtbl[];
   73 static struct PINT_state_s ST_mkdir_msg_xfer_msgpair;
   74 static struct PINT_pjmp_tbl_s ST_mkdir_msg_xfer_msgpair_pjtbl[];
   75 static struct PINT_tran_tbl_s ST_mkdir_msg_xfer_msgpair_trtbl[];
   76 
   77 static PINT_sm_action mkdir_msg_failure(
   78 	struct PINT_smcb *smcb, job_status_s *js_p);
   79 
   80 static struct PINT_state_s ST_mkdir_msg_failure;
   81 static struct PINT_pjmp_tbl_s ST_mkdir_msg_failure_pjtbl[];
   82 static struct PINT_tran_tbl_s ST_mkdir_msg_failure_trtbl[];
   83 
   84 static PINT_sm_action mkdir_seteattr_setup_msgpair(
   85 	struct PINT_smcb *smcb, job_status_s *js_p);
   86 
   87 static struct PINT_state_s ST_mkdir_seteattr_setup_msgpair;
   88 static struct PINT_pjmp_tbl_s ST_mkdir_seteattr_setup_msgpair_pjtbl[];
   89 static struct PINT_tran_tbl_s ST_mkdir_seteattr_setup_msgpair_trtbl[];
   90 static struct PINT_state_s ST_mkdir_seteattr_xfer_msgpair;
   91 static struct PINT_pjmp_tbl_s ST_mkdir_seteattr_xfer_msgpair_pjtbl[];
   92 static struct PINT_tran_tbl_s ST_mkdir_seteattr_xfer_msgpair_trtbl[];
   93 
   94 static PINT_sm_action mkdir_seteattr_failure(
   95 	struct PINT_smcb *smcb, job_status_s *js_p);
   96 
   97 static struct PINT_state_s ST_mkdir_seteattr_failure;
   98 static struct PINT_pjmp_tbl_s ST_mkdir_seteattr_failure_pjtbl[];
   99 static struct PINT_tran_tbl_s ST_mkdir_seteattr_failure_trtbl[];
  100 
  101 static PINT_sm_action mkdir_crdirent_setup_msgpair(
  102 	struct PINT_smcb *smcb, job_status_s *js_p);
  103 
  104 static struct PINT_state_s ST_mkdir_crdirent_setup_msgpair;
  105 static struct PINT_pjmp_tbl_s ST_mkdir_crdirent_setup_msgpair_pjtbl[];
  106 static struct PINT_tran_tbl_s ST_mkdir_crdirent_setup_msgpair_trtbl[];
  107 static struct PINT_state_s ST_mkdir_crdirent_xfer_msgpair;
  108 static struct PINT_pjmp_tbl_s ST_mkdir_crdirent_xfer_msgpair_pjtbl[];
  109 static struct PINT_tran_tbl_s ST_mkdir_crdirent_xfer_msgpair_trtbl[];
  110 
  111 static PINT_sm_action mkdir_crdirent_failure(
  112 	struct PINT_smcb *smcb, job_status_s *js_p);
  113 
  114 static struct PINT_state_s ST_mkdir_crdirent_failure;
  115 static struct PINT_pjmp_tbl_s ST_mkdir_crdirent_failure_pjtbl[];
  116 static struct PINT_tran_tbl_s ST_mkdir_crdirent_failure_trtbl[];
  117 
  118 static PINT_sm_action mkdir_delete_handle_setup_msgpair(
  119 	struct PINT_smcb *smcb, job_status_s *js_p);
  120 
  121 static struct PINT_state_s ST_delete_handle_setup_msgpair;
  122 static struct PINT_pjmp_tbl_s ST_delete_handle_setup_msgpair_pjtbl[];
  123 static struct PINT_tran_tbl_s ST_delete_handle_setup_msgpair_trtbl[];
  124 static struct PINT_state_s ST_delete_handle_xfer_msgpair;
  125 static struct PINT_pjmp_tbl_s ST_delete_handle_xfer_msgpair_pjtbl[];
  126 static struct PINT_tran_tbl_s ST_delete_handle_xfer_msgpair_trtbl[];
  127 
  128 static PINT_sm_action mkdir_cleanup(
  129 	struct PINT_smcb *smcb, job_status_s *js_p);
  130 
  131 static struct PINT_state_s ST_cleanup;
  132 static struct PINT_pjmp_tbl_s ST_cleanup_pjtbl[];
  133 static struct PINT_tran_tbl_s ST_cleanup_trtbl[];
  134 
  135 struct PINT_state_machine_s pvfs2_client_mkdir_sm = {
  136 	.name = "pvfs2_client_mkdir_sm",
  137 	.first_state = &ST_init
  138 };
  139 
  140 static struct PINT_state_s ST_init = {
  141 	 .state_name = "init" ,
  142 	 .parent_machine = &pvfs2_client_mkdir_sm ,
  143 	 .flag = SM_RUN ,
  144 	 .action.func = mkdir_init ,
  145 	 .pjtbl = NULL ,
  146 	 .trtbl = ST_init_trtbl
  147 };
  148 
  149 static struct PINT_tran_tbl_s ST_init_trtbl[] = {
  150 	{ .return_value = -1 ,
  151 	 .next_state = &ST_parent_getattr }
  152 };
  153 
  154 static struct PINT_state_s ST_parent_getattr = {
  155 	 .state_name = "parent_getattr" ,
  156 	 .parent_machine = &pvfs2_client_mkdir_sm ,
  157 	 .flag = SM_JUMP ,
  158 	 .action.nested = &pvfs2_client_getattr_sm ,
  159 	 .pjtbl = NULL ,
  160 	 .trtbl = ST_parent_getattr_trtbl
  161 };
  162 
  163 static struct PINT_tran_tbl_s ST_parent_getattr_trtbl[] = {
  164 	{ .return_value = 0 ,
  165 	 .next_state = &ST_parent_getattr_inspect },
  166 	{ .return_value = -1 ,
  167 	 .next_state = &ST_cleanup }
  168 };
  169 
  170 static struct PINT_state_s ST_parent_getattr_inspect = {
  171 	 .state_name = "parent_getattr_inspect" ,
  172 	 .parent_machine = &pvfs2_client_mkdir_sm ,
  173 	 .flag = SM_RUN ,
  174 	 .action.func = mkdir_parent_getattr_inspect ,
  175 	 .pjtbl = NULL ,
  176 	 .trtbl = ST_parent_getattr_inspect_trtbl
  177 };
  178 
  179 static struct PINT_tran_tbl_s ST_parent_getattr_inspect_trtbl[] = {
  180 	{ .return_value = 0 ,
  181 	 .next_state = &ST_mkdir_msg_setup_msgpair },
  182 	{ .return_value = -1 ,
  183 	 .next_state = &ST_cleanup }
  184 };
  185 
  186 static struct PINT_state_s ST_mkdir_msg_setup_msgpair = {
  187 	 .state_name = "mkdir_msg_setup_msgpair" ,
  188 	 .parent_machine = &pvfs2_client_mkdir_sm ,
  189 	 .flag = SM_RUN ,
  190 	 .action.func = mkdir_msg_setup_msgpair ,
  191 	 .pjtbl = NULL ,
  192 	 .trtbl = ST_mkdir_msg_setup_msgpair_trtbl
  193 };
  194 
  195 static struct PINT_tran_tbl_s ST_mkdir_msg_setup_msgpair_trtbl[] = {
  196 	{ .return_value = 0 ,
  197 	 .next_state = &ST_mkdir_msg_xfer_msgpair },
  198 	{ .return_value = -1 ,
  199 	 .next_state = &ST_mkdir_msg_failure }
  200 };
  201 
  202 static struct PINT_state_s ST_mkdir_msg_xfer_msgpair = {
  203 	 .state_name = "mkdir_msg_xfer_msgpair" ,
  204 	 .parent_machine = &pvfs2_client_mkdir_sm ,
  205 	 .flag = SM_JUMP ,
  206 	 .action.nested = &pvfs2_msgpairarray_sm ,
  207 	 .pjtbl = NULL ,
  208 	 .trtbl = ST_mkdir_msg_xfer_msgpair_trtbl
  209 };
  210 
  211 static struct PINT_tran_tbl_s ST_mkdir_msg_xfer_msgpair_trtbl[] = {
  212 	{ .return_value = 0 ,
  213 	 .next_state = &ST_mkdir_seteattr_setup_msgpair },
  214 	{ .return_value = -1 ,
  215 	 .next_state = &ST_mkdir_msg_failure }
  216 };
  217 
  218 static struct PINT_state_s ST_mkdir_msg_failure = {
  219 	 .state_name = "mkdir_msg_failure" ,
  220 	 .parent_machine = &pvfs2_client_mkdir_sm ,
  221 	 .flag = SM_RUN ,
  222 	 .action.func = mkdir_msg_failure ,
  223 	 .pjtbl = NULL ,
  224 	 .trtbl = ST_mkdir_msg_failure_trtbl
  225 };
  226 
  227 static struct PINT_tran_tbl_s ST_mkdir_msg_failure_trtbl[] = {
  228 	{ .return_value = -1 ,
  229 	 .next_state = &ST_cleanup }
  230 };
  231 
  232 static struct PINT_state_s ST_mkdir_seteattr_setup_msgpair = {
  233 	 .state_name = "mkdir_seteattr_setup_msgpair" ,
  234 	 .parent_machine = &pvfs2_client_mkdir_sm ,
  235 	 .flag = SM_RUN ,
  236 	 .action.func = mkdir_seteattr_setup_msgpair ,
  237 	 .pjtbl = NULL ,
  238 	 .trtbl = ST_mkdir_seteattr_setup_msgpair_trtbl
  239 };
  240 
  241 static struct PINT_tran_tbl_s ST_mkdir_seteattr_setup_msgpair_trtbl[] = {
  242 	{ .return_value = MKDIR_SKIP_EATTR ,
  243 	 .next_state = &ST_mkdir_crdirent_setup_msgpair },
  244 	{ .return_value = 0 ,
  245 	 .next_state = &ST_mkdir_seteattr_xfer_msgpair },
  246 	{ .return_value = -1 ,
  247 	 .next_state = &ST_mkdir_seteattr_failure }
  248 };
  249 
  250 static struct PINT_state_s ST_mkdir_seteattr_xfer_msgpair = {
  251 	 .state_name = "mkdir_seteattr_xfer_msgpair" ,
  252 	 .parent_machine = &pvfs2_client_mkdir_sm ,
  253 	 .flag = SM_JUMP ,
  254 	 .action.nested = &pvfs2_msgpairarray_sm ,
  255 	 .pjtbl = NULL ,
  256 	 .trtbl = ST_mkdir_seteattr_xfer_msgpair_trtbl
  257 };
  258 
  259 static struct PINT_tran_tbl_s ST_mkdir_seteattr_xfer_msgpair_trtbl[] = {
  260 	{ .return_value = 0 ,
  261 	 .next_state = &ST_mkdir_crdirent_setup_msgpair },
  262 	{ .return_value = -1 ,
  263 	 .next_state = &ST_mkdir_seteattr_failure }
  264 };
  265 
  266 static struct PINT_state_s ST_mkdir_seteattr_failure = {
  267 	 .state_name = "mkdir_seteattr_failure" ,
  268 	 .parent_machine = &pvfs2_client_mkdir_sm ,
  269 	 .flag = SM_RUN ,
  270 	 .action.func = mkdir_seteattr_failure ,
  271 	 .pjtbl = NULL ,
  272 	 .trtbl = ST_mkdir_seteattr_failure_trtbl
  273 };
  274 
  275 static struct PINT_tran_tbl_s ST_mkdir_seteattr_failure_trtbl[] = {
  276 	{ .return_value = -1 ,
  277 	 .next_state = &ST_delete_handle_setup_msgpair }
  278 };
  279 
  280 static struct PINT_state_s ST_mkdir_crdirent_setup_msgpair = {
  281 	 .state_name = "mkdir_crdirent_setup_msgpair" ,
  282 	 .parent_machine = &pvfs2_client_mkdir_sm ,
  283 	 .flag = SM_RUN ,
  284 	 .action.func = mkdir_crdirent_setup_msgpair ,
  285 	 .pjtbl = NULL ,
  286 	 .trtbl = ST_mkdir_crdirent_setup_msgpair_trtbl
  287 };
  288 
  289 static struct PINT_tran_tbl_s ST_mkdir_crdirent_setup_msgpair_trtbl[] = {
  290 	{ .return_value = 0 ,
  291 	 .next_state = &ST_mkdir_crdirent_xfer_msgpair },
  292 	{ .return_value = -1 ,
  293 	 .next_state = &ST_mkdir_crdirent_failure }
  294 };
  295 
  296 static struct PINT_state_s ST_mkdir_crdirent_xfer_msgpair = {
  297 	 .state_name = "mkdir_crdirent_xfer_msgpair" ,
  298 	 .parent_machine = &pvfs2_client_mkdir_sm ,
  299 	 .flag = SM_JUMP ,
  300 	 .action.nested = &pvfs2_msgpairarray_sm ,
  301 	 .pjtbl = NULL ,
  302 	 .trtbl = ST_mkdir_crdirent_xfer_msgpair_trtbl
  303 };
  304 
  305 static struct PINT_tran_tbl_s ST_mkdir_crdirent_xfer_msgpair_trtbl[] = {
  306 	{ .return_value = 0 ,
  307 	 .next_state = &ST_cleanup },
  308 	{ .return_value = -1 ,
  309 	 .next_state = &ST_mkdir_crdirent_failure }
  310 };
  311 
  312 static struct PINT_state_s ST_mkdir_crdirent_failure = {
  313 	 .state_name = "mkdir_crdirent_failure" ,
  314 	 .parent_machine = &pvfs2_client_mkdir_sm ,
  315 	 .flag = SM_RUN ,
  316 	 .action.func = mkdir_crdirent_failure ,
  317 	 .pjtbl = NULL ,
  318 	 .trtbl = ST_mkdir_crdirent_failure_trtbl
  319 };
  320 
  321 static struct PINT_tran_tbl_s ST_mkdir_crdirent_failure_trtbl[] = {
  322 	{ .return_value = -1 ,
  323 	 .next_state = &ST_delete_handle_setup_msgpair }
  324 };
  325 
  326 static struct PINT_state_s ST_delete_handle_setup_msgpair = {
  327 	 .state_name = "delete_handle_setup_msgpair" ,
  328 	 .parent_machine = &pvfs2_client_mkdir_sm ,
  329 	 .flag = SM_RUN ,
  330 	 .action.func = mkdir_delete_handle_setup_msgpair ,
  331 	 .pjtbl = NULL ,
  332 	 .trtbl = ST_delete_handle_setup_msgpair_trtbl
  333 };
  334 
  335 static struct PINT_tran_tbl_s ST_delete_handle_setup_msgpair_trtbl[] = {
  336 	{ .return_value = 0 ,
  337 	 .next_state = &ST_delete_handle_xfer_msgpair },
  338 	{ .return_value = -1 ,
  339 	 .next_state = &ST_cleanup }
  340 };
  341 
  342 static struct PINT_state_s ST_delete_handle_xfer_msgpair = {
  343 	 .state_name = "delete_handle_xfer_msgpair" ,
  344 	 .parent_machine = &pvfs2_client_mkdir_sm ,
  345 	 .flag = SM_JUMP ,
  346 	 .action.nested = &pvfs2_msgpairarray_sm ,
  347 	 .pjtbl = NULL ,
  348 	 .trtbl = ST_delete_handle_xfer_msgpair_trtbl
  349 };
  350 
  351 static struct PINT_tran_tbl_s ST_delete_handle_xfer_msgpair_trtbl[] = {
  352 	{ .return_value = -1 ,
  353 	 .next_state = &ST_cleanup }
  354 };
  355 
  356 static struct PINT_state_s ST_cleanup = {
  357 	 .state_name = "cleanup" ,
  358 	 .parent_machine = &pvfs2_client_mkdir_sm ,
  359 	 .flag = SM_RUN ,
  360 	 .action.func = mkdir_cleanup ,
  361 	 .pjtbl = NULL ,
  362 	 .trtbl = ST_cleanup_trtbl
  363 };
  364 
  365 static struct PINT_tran_tbl_s ST_cleanup_trtbl[] = {
  366 	{ .return_value = MKDIR_RETRY ,
  367 	 .next_state = &ST_init },
  368 	{ .return_value = -1 ,
  369 
  370 	 .flag = SM_TERM }
  371 };
  372 
  373 # 151 "src/client/sysint/sys-mkdir.sm"
  374 
  375 
  376 /** Initiate creation of a new directory.
  377  */
  378 PVFS_error PVFS_isys_mkdir(
  379     char *object_name,
  380     PVFS_object_ref parent_ref,
  381     PVFS_sys_attr attr,
  382     const PVFS_credentials *credentials,
  383     PVFS_sysresp_mkdir *resp,
  384     PVFS_sys_op_id *op_id,
  385     void *user_ptr)
  386 {
  387     PVFS_error ret = -PVFS_EINVAL;
  388     PINT_smcb *smcb = NULL;
  389     PINT_client_sm *sm_p = NULL;
  390 
  391     gossip_debug(GOSSIP_CLIENT_DEBUG, "PVFS_isys_mkdir entered\n");
  392 
  393     if ((parent_ref.handle == PVFS_HANDLE_NULL) ||
  394         (parent_ref.fs_id == PVFS_FS_ID_NULL) ||
  395         (object_name == NULL) || (resp == NULL))
  396     {
  397         gossip_err("invalid (NULL) required argument\n");
  398         return ret;
  399     }
  400 
  401     if ((attr.mask & PVFS_ATTR_SYS_ALL_SETABLE) !=
  402         PVFS_ATTR_SYS_ALL_SETABLE)
  403     {
  404         gossip_lerr("PVFS_isys_mkdir() failure: invalid attributes "
  405                     "specified\n");
  406         return ret;
  407     }
  408 
  409     if ((strlen(object_name) + 1) > PVFS_REQ_LIMIT_SEGMENT_BYTES)
  410     {
  411         return -PVFS_ENAMETOOLONG;
  412     }
  413 
  414     PINT_smcb_alloc(&smcb, PVFS_SYS_MKDIR,
  415              sizeof(struct PINT_client_sm),
  416              client_op_state_get_machine,
  417              client_state_machine_terminate,
  418              pint_client_sm_context);
  419     if (smcb == NULL)
  420     {
  421         return -PVFS_ENOMEM;
  422     }
  423     sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  424 
  425     PINT_init_msgarray_params(&sm_p->msgarray_params, parent_ref.fs_id);
  426     PINT_init_sysint_credentials(sm_p->cred_p, credentials);
  427     sm_p->u.mkdir.object_name = object_name;
  428     PVFS_util_copy_sys_attr(&sm_p->u.mkdir.sys_attr, &attr);
  429     sm_p->u.mkdir.mkdir_resp = resp;
  430     sm_p->u.mkdir.stored_error_code = 0;
  431     sm_p->object_ref = parent_ref;
  432 
  433     gossip_debug(GOSSIP_CLIENT_DEBUG, "Creating directory named %s "
  434                  "under parent handle %llu on fs %d\n", object_name,
  435                  llu(parent_ref.handle), parent_ref.fs_id);
  436 
  437     return PINT_client_state_machine_post(
  438         smcb,  op_id, user_ptr);
  439 }
  440 
  441 /** Create a new directory.
  442  */
  443 PVFS_error PVFS_sys_mkdir(
  444     char *object_name,
  445     PVFS_object_ref parent_ref,
  446     PVFS_sys_attr attr,
  447     const PVFS_credentials *credentials,
  448     PVFS_sysresp_mkdir *resp)
  449 {
  450     PVFS_error ret = -PVFS_EINVAL, error = 0;
  451     PVFS_sys_op_id op_id;
  452 
  453     gossip_debug(GOSSIP_CLIENT_DEBUG, "PVFS_sys_mkdir entered\n");
  454 
  455     ret = PVFS_isys_mkdir(object_name, parent_ref, attr,
  456                           credentials, resp, &op_id, NULL);
  457     if (ret)
  458     {
  459         PVFS_perror_gossip("PVFS_isys_mkdir call", ret);
  460         error = ret;
  461     }
  462     else
  463     {
  464         ret = PVFS_sys_wait(op_id, "mkdir", &error);
  465         if (ret)
  466         {
  467             PVFS_perror_gossip("PVFS_sys_wait call", ret);
  468             error = ret;
  469         }
  470     }
  471 
  472     PINT_sys_release(op_id);
  473     return error;
  474 }
  475 
  476 /****************************************************************/
  477 
  478 static PINT_sm_action mkdir_init(
  479         struct PINT_smcb *smcb, job_status_s *js_p)
  480 {
  481     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  482     job_id_t tmp_id;
  483 
  484     gossip_debug(GOSSIP_CLIENT_DEBUG, "mkdir state: init\n");
  485 
  486     assert((js_p->error_code == 0) ||
  487            (js_p->error_code == MKDIR_RETRY));
  488 
  489     if (js_p->error_code == MKDIR_RETRY)
  490     {
  491         js_p->error_code = 0;
  492 
  493         return job_req_sched_post_timer(
  494             sm_p->msgarray_params.retry_delay, smcb, 0, js_p, &tmp_id,
  495             pint_client_sm_context);
  496     }
  497 
  498     PINT_SM_GETATTR_STATE_FILL(
  499         sm_p->getattr,
  500         sm_p->object_ref,
  501         (PVFS_ATTR_COMMON_ALL|PVFS_ATTR_DIR_HINT),
  502         PVFS_TYPE_DIRECTORY,
  503         0);
  504 
  505     return SM_ACTION_COMPLETE;
  506 }
  507 
  508 static int mkdir_msg_comp_fn(void *v_p,
  509                              struct PVFS_server_resp *resp_p,
  510                              int index)
  511 {
  512     PINT_smcb *smcb = v_p;
  513     PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  514     PVFS_object_attr attr;
  515 
  516     gossip_debug(GOSSIP_CLIENT_DEBUG, "mkdir_msg_comp_fn\n");
  517 
  518     assert(resp_p->op == PVFS_SERV_MKDIR);
  519 
  520     if (resp_p->status != 0)
  521     {
  522 	return resp_p->status;
  523     }
  524 
  525     /* otherwise, just stash the newly created meta handle */
  526     sm_p->u.mkdir.metafile_handle = resp_p->u.mkdir.handle;
  527 
  528     /* also insert entry into attr cache */
  529     PINT_CONVERT_ATTR(&attr, &sm_p->u.mkdir.sys_attr, 0);
  530     PINT_acache_update(sm_p->object_ref, &attr, NULL);
  531 
  532     gossip_debug(
  533         GOSSIP_CLIENT_DEBUG, "*** Got newly created dir handle %llu\n",
  534         llu(sm_p->u.mkdir.metafile_handle));
  535 
  536     return 0;
  537 }
  538 
  539 static int mkdir_crdirent_comp_fn(void *v_p,
  540                                   struct PVFS_server_resp *resp_p,
  541                                   int index)
  542 {
  543     gossip_debug(GOSSIP_CLIENT_DEBUG, "mkdir_crdirent_comp_fn\n");
  544 
  545     assert(resp_p->op == PVFS_SERV_CRDIRENT);
  546     return resp_p->status;
  547 }
  548 
  549 static int mkdir_delete_handle_comp_fn(void *v_p,
  550                                        struct PVFS_server_resp *resp_p,
  551                                        int index)
  552 {
  553     gossip_debug(GOSSIP_CLIENT_DEBUG, "mkdir_delete_handle_comp_fn\n");
  554 
  555     assert(resp_p->op == PVFS_SERV_REMOVE);
  556     return resp_p->status;
  557 }
  558 
  559 static PINT_sm_action mkdir_msg_setup_msgpair(
  560         struct PINT_smcb *smcb, job_status_s *js_p)
  561 {
  562     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  563     int ret = -PVFS_EINVAL;
  564     PVFS_handle_extent_array meta_handle_extent_array;
  565     PINT_sm_msgpair_state *msg_p = NULL;
  566     struct server_configuration_s *server_config = NULL;
  567 
  568     gossip_debug(GOSSIP_CLIENT_DEBUG,
  569                  "mkdir state: mkdir_msg_setup_msgpair\n");
  570 
  571     js_p->error_code = 0;
  572 
  573     gossip_debug(GOSSIP_CLIENT_DEBUG," mkdir: posting mkdir req\n");
  574 
  575     PINT_init_msgpair(sm_p, msg_p);
  576 
  577     server_config = PINT_get_server_config_struct(
  578         sm_p->object_ref.fs_id);
  579 
  580     ret = PINT_cached_config_get_next_meta(
  581         server_config, sm_p->object_ref.fs_id,
  582         &msg_p->svr_addr, &meta_handle_extent_array);
  583 
  584     PINT_put_server_config_struct(server_config);
  585 
  586     if (ret)
  587     {
  588         gossip_err("Failed to map meta server address\n");
  589         js_p->error_code = ret;
  590         return SM_ACTION_COMPLETE;
  591     }
  592 
  593     PINT_SERVREQ_MKDIR_FILL(
  594         msg_p->req,
  595         *sm_p->cred_p,
  596         sm_p->object_ref.fs_id,
  597         meta_handle_extent_array,
  598         sm_p->u.mkdir.sys_attr);
  599 
  600     msg_p->fs_id = sm_p->object_ref.fs_id;
  601     msg_p->handle = meta_handle_extent_array.extent_array[0].first;
  602     msg_p->retry_flag = PVFS_MSGPAIR_NO_RETRY;
  603     msg_p->comp_fn = mkdir_msg_comp_fn;
  604 
  605     return SM_ACTION_COMPLETE;
  606 }
  607 
  608 static PINT_sm_action mkdir_msg_failure(
  609         struct PINT_smcb *smcb, job_status_s *js_p)
  610 {
  611     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  612     sm_p->u.mkdir.stored_error_code = js_p->error_code;
  613 
  614     gossip_debug(GOSSIP_CLIENT_DEBUG, "mkdir state: mkdir_msg_failure\n");
  615     return SM_ACTION_COMPLETE;
  616 }
  617 
  618 static PINT_sm_action mkdir_crdirent_setup_msgpair(
  619         struct PINT_smcb *smcb, job_status_s *js_p)
  620 {
  621     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  622     int ret = -PVFS_EINVAL;
  623     PINT_sm_msgpair_state *msg_p = NULL;
  624 
  625     gossip_debug(GOSSIP_CLIENT_DEBUG,
  626                  "mkdir state: crdirent_setup_msgpair\n");
  627 
  628     js_p->error_code = 0;
  629 
  630     gossip_debug(GOSSIP_CLIENT_DEBUG," mkdir: posting crdirent req\n");
  631 
  632     gossip_debug(GOSSIP_CLIENT_DEBUG, "hooking dirent %s (%llu) under "
  633                  "parent handle %llu\n", sm_p->u.mkdir.object_name,
  634                  llu(sm_p->u.mkdir.metafile_handle),
  635                  llu(sm_p->object_ref.handle));
  636 
  637     PINT_init_msgpair(sm_p, msg_p);
  638 
  639     PINT_SERVREQ_CRDIRENT_FILL(
  640         msg_p->req,
  641         *sm_p->cred_p,
  642         sm_p->u.mkdir.object_name,
  643         sm_p->u.mkdir.metafile_handle,
  644         sm_p->object_ref.handle,
  645         sm_p->object_ref.fs_id);
  646 
  647     msg_p->fs_id = sm_p->object_ref.fs_id;
  648     msg_p->handle = sm_p->object_ref.handle;
  649     msg_p->retry_flag = PVFS_MSGPAIR_NO_RETRY;
  650     msg_p->comp_fn = mkdir_crdirent_comp_fn;
  651 
  652     ret = PINT_cached_config_map_to_server(
  653         &msg_p->svr_addr, sm_p->object_ref.handle,
  654         sm_p->object_ref.fs_id);
  655 
  656     if (ret)
  657     {
  658         gossip_err("Failed to map meta server address\n");
  659         js_p->error_code = ret;
  660     }
  661     return SM_ACTION_COMPLETE;
  662 }
  663 
  664 static PINT_sm_action mkdir_crdirent_failure(
  665         struct PINT_smcb *smcb, job_status_s *js_p)
  666 {
  667     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  668     sm_p->u.mkdir.stored_error_code = js_p->error_code;
  669 
  670     gossip_debug(GOSSIP_CLIENT_DEBUG, "mkdir state: crdirent_failure\n");
  671 
  672     PVFS_perror_gossip("mkdir crdirent failed", js_p->error_code);
  673     return SM_ACTION_COMPLETE;
  674 }
  675 
  676 static PINT_sm_action mkdir_delete_handle_setup_msgpair(
  677         struct PINT_smcb *smcb, job_status_s *js_p)
  678 {
  679     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  680     int ret = -PVFS_EINVAL;
  681     PVFS_BMI_addr_t metafile_server_addr;
  682     PINT_sm_msgpair_state *msg_p = NULL;
  683 
  684     gossip_debug(GOSSIP_CLIENT_DEBUG, "mkdir state: "
  685                  "delete_handle_setup_msgpair_array\n");
  686 
  687     js_p->error_code = 0;
  688 
  689     PINT_init_msgpair(sm_p, msg_p);
  690 
  691     ret = PINT_cached_config_map_to_server(
  692         &metafile_server_addr, sm_p->u.mkdir.metafile_handle,
  693         sm_p->object_ref.fs_id);
  694 
  695     if (ret)
  696     {
  697         gossip_err("Failed to map meta server address\n");
  698         js_p->error_code = ret;
  699         return SM_ACTION_COMPLETE;
  700     }
  701 
  702     PINT_SERVREQ_REMOVE_FILL(
  703         msg_p->req,
  704         *sm_p->cred_p,
  705         sm_p->object_ref.fs_id,
  706         sm_p->u.mkdir.metafile_handle);
  707 
  708     msg_p->fs_id = sm_p->object_ref.fs_id;
  709     msg_p->handle = sm_p->u.mkdir.metafile_handle;
  710     msg_p->retry_flag = PVFS_MSGPAIR_NO_RETRY;
  711     msg_p->comp_fn = mkdir_delete_handle_comp_fn;
  712     msg_p->svr_addr = metafile_server_addr;
  713 
  714     gossip_debug(GOSSIP_CLIENT_DEBUG, " Preparing to remove "
  715                  "directory handle %llu\n", llu(msg_p->handle));
  716     return SM_ACTION_COMPLETE;
  717 }
  718 
  719 static PINT_sm_action mkdir_cleanup(
  720         struct PINT_smcb *smcb, job_status_s *js_p)
  721 {
  722     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  723     gossip_debug(GOSSIP_CLIENT_DEBUG, "mkdir state: cleanup\n");
  724 
  725     if(sm_p->u.mkdir.val_array)
  726     {
  727         if((sm_p->getattr.attr.mask & PVFS_ATTR_DIR_HINT) &&
  728             (sm_p->getattr.attr.u.dir.hint.dfile_count > 0))
  729         {
  730             free(sm_p->u.mkdir.val_array[0].buffer);
  731         }
  732         free(sm_p->u.mkdir.val_array);
  733     }
  734     if(sm_p->u.mkdir.key_array)
  735     {
  736         free(sm_p->u.mkdir.key_array);
  737     }
  738 
  739     PVFS_util_release_sys_attr(&sm_p->u.mkdir.sys_attr);
  740 
  741     PINT_SM_GETATTR_STATE_CLEAR(sm_p->getattr);
  742 
  743     sm_p->error_code = (sm_p->u.mkdir.stored_error_code ?
  744                         sm_p->u.mkdir.stored_error_code :
  745                         js_p->error_code);
  746 
  747     if (sm_p->error_code == 0)
  748     {
  749         PVFS_object_ref directory_ref;
  750 
  751         directory_ref.handle = sm_p->u.mkdir.metafile_handle;
  752         directory_ref.fs_id = sm_p->object_ref.fs_id;
  753 
  754         sm_p->u.mkdir.mkdir_resp->ref.handle = directory_ref.handle;
  755         sm_p->u.mkdir.mkdir_resp->ref.fs_id = directory_ref.fs_id;
  756 
  757         /* insert newly created directory handle into the ncache */
  758         PINT_ncache_update((const char*) sm_p->u.mkdir.object_name,
  759                            (const PVFS_object_ref*) &directory_ref,
  760                            (const PVFS_object_ref*) &(sm_p->object_ref));
  761     }
  762     else if ((PVFS_ERROR_CLASS(-sm_p->error_code) == PVFS_ERROR_BMI) &&
  763              (sm_p->u.mkdir.retry_count < sm_p->msgarray_params.retry_limit))
  764     {
  765         sm_p->u.mkdir.stored_error_code = 0;
  766         sm_p->u.mkdir.retry_count++;
  767 
  768         gossip_debug(GOSSIP_CLIENT_DEBUG, "Retrying mkdir operation "
  769                      "(attempt number %d)\n", sm_p->u.mkdir.retry_count);
  770 
  771         js_p->error_code = MKDIR_RETRY;
  772         return SM_ACTION_COMPLETE;
  773     }
  774     else
  775     {
  776         PINT_acache_invalidate(sm_p->object_ref);
  777         PVFS_perror_gossip("mkdir failed with error", sm_p->error_code);
  778     }
  779 
  780     PINT_SET_OP_COMPLETE;
  781     return SM_ACTION_TERMINATE;
  782 }
  783 
  784 /** looks at the attributes of the parent directory and decides if it impacts
  785  *  the mkdir in any way
  786  */
  787 static PINT_sm_action mkdir_parent_getattr_inspect(
  788         struct PINT_smcb *smcb, job_status_s *js_p)
  789 {
  790     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  791     PVFS_object_attr *attr = NULL;
  792 
  793     gossip_debug(GOSSIP_CLIENT_DEBUG, "mkdir state: parent_getattr_inspect\n");
  794 
  795     attr = &sm_p->getattr.attr;
  796     assert(attr);
  797 
  798     gossip_debug(GOSSIP_CLIENT_DEBUG, "parent owner: %d, group: %d, perms: %d\n",
  799         (int)attr->owner, (int)attr->group, (int)attr->perms);
  800 
  801     /* do we have a setgid bit? */
  802     if(attr->perms & PVFS_G_SGID)
  803     {
  804         gossip_debug(GOSSIP_CLIENT_DEBUG, "parent has setgid bit set.\n");
  805         gossip_debug(GOSSIP_CLIENT_DEBUG, " - modifying requested attr for new file.\n");
  806         sm_p->u.mkdir.sys_attr.group = attr->group;
  807         sm_p->u.mkdir.sys_attr.perms |= PVFS_G_SGID;
  808         /* note that permission checking is left to server even in this case */
  809     }
  810 
  811     return SM_ACTION_COMPLETE;
  812 }
  813 
  814 static PINT_sm_action mkdir_seteattr_setup_msgpair(
  815         struct PINT_smcb *smcb, job_status_s *js_p)
  816 {
  817     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  818     int eattr_count = 0;
  819     int cur_index = 0;
  820     PINT_sm_msgpair_state *msg_p = NULL;
  821     int ret = -PVFS_EINVAL;
  822 
  823     /* NOTE: any memory allocated here will be free'd in the cleanup function */
  824 
  825     gossip_debug(GOSSIP_CLIENT_DEBUG, "mkdir state: seteattr_setup_msgpair\n");
  826 
  827     /* don't set any hint attributes if the parent doesn't have them */
  828     if(!(sm_p->getattr.attr.mask & PVFS_ATTR_DIR_HINT))
  829     {
  830         gossip_debug(GOSSIP_CLIENT_DEBUG, "mkdir state: skipping seteattr\n");
  831         js_p->error_code = MKDIR_SKIP_EATTR;
  832         return SM_ACTION_COMPLETE;
  833     }
  834 
  835     /* count how many hints we acquired */
  836     if(sm_p->getattr.attr.u.dir.hint.dfile_count > 0)
  837         eattr_count++;
  838     if(sm_p->getattr.attr.u.dir.hint.dist_name != NULL)
  839         eattr_count++;
  840     if(sm_p->getattr.attr.u.dir.hint.dist_params != NULL)
  841         eattr_count++;
  842 
  843     if(eattr_count == 0)
  844     {
  845         /* nothing to inherit */
  846         js_p->error_code = MKDIR_SKIP_EATTR;
  847         return SM_ACTION_COMPLETE;
  848     }
  849 
  850     sm_p->u.mkdir.key_array = (PVFS_ds_keyval*)calloc(eattr_count,
  851         sizeof(PVFS_ds_keyval));
  852     if(!sm_p->u.mkdir.key_array)
  853     {
  854         js_p->error_code = -PVFS_ENOMEM;
  855         return SM_ACTION_COMPLETE;
  856     }
  857 
  858     sm_p->u.mkdir.val_array = (PVFS_ds_keyval*)calloc(eattr_count,
  859         sizeof(PVFS_ds_keyval));
  860     if(!sm_p->u.mkdir.val_array)
  861     {
  862         js_p->error_code = -PVFS_ENOMEM;
  863         return SM_ACTION_COMPLETE;
  864     }
  865 
  866     if(sm_p->getattr.attr.u.dir.hint.dfile_count > 0)
  867     {
  868         gossip_debug(GOSSIP_CLIENT_DEBUG, "mkdir: setting num_dfiles\n");
  869         sm_p->u.mkdir.key_array[cur_index].buffer = "user.pvfs2.num_dfiles";
  870         sm_p->u.mkdir.key_array[cur_index].buffer_sz =
  871             strlen("user.pvfs2.num_dfiles") + 1;
  872 
  873         sm_p->u.mkdir.val_array[cur_index].buffer = calloc(1, 16);
  874         if(!sm_p->u.mkdir.val_array[cur_index].buffer)
  875         {
  876             js_p->error_code = -PVFS_ENOMEM;
  877             return SM_ACTION_COMPLETE;
  878         }
  879         snprintf((char*)sm_p->u.mkdir.val_array[cur_index].buffer,
  880             16, "%d", sm_p->getattr.attr.u.dir.hint.dfile_count);
  881         sm_p->u.mkdir.val_array[cur_index].buffer_sz =
  882             strlen((char*)sm_p->u.mkdir.val_array[cur_index].buffer) + 1;
  883 
  884         cur_index++;
  885     }
  886     if(sm_p->getattr.attr.u.dir.hint.dist_name != NULL)
  887     {
  888         gossip_debug(GOSSIP_CLIENT_DEBUG, "mkdir: setting dist_name\n");
  889         sm_p->u.mkdir.key_array[cur_index].buffer = "user.pvfs2.dist_name";
  890         sm_p->u.mkdir.key_array[cur_index].buffer_sz =
  891             strlen("user.pvfs2.dist_name") + 1;
  892         sm_p->u.mkdir.val_array[cur_index].buffer =
  893             sm_p->getattr.attr.u.dir.hint.dist_name;
  894         sm_p->u.mkdir.val_array[cur_index].buffer_sz =
  895             sm_p->getattr.attr.u.dir.hint.dist_name_len;
  896 
  897         cur_index++;
  898     }
  899     if(sm_p->getattr.attr.u.dir.hint.dist_params != NULL)
  900     {
  901         gossip_debug(GOSSIP_CLIENT_DEBUG, "mkdir: setting dist_params\n");
  902         sm_p->u.mkdir.key_array[cur_index].buffer = "user.pvfs2.dist_params";
  903         sm_p->u.mkdir.key_array[cur_index].buffer_sz =
  904             strlen("user.pvfs2.dist_params") + 1;
  905 
  906         sm_p->u.mkdir.val_array[cur_index].buffer =
  907             sm_p->getattr.attr.u.dir