"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