2 static char sfs_3_opsSid[] = "@(#)sfs_3_ops.c 2.1 97/10/23";
6 * Copyright (c) 1992-1997,2001 by Standard Performance Evaluation Corporation
8 * Standard Performance Evaluation Corporation (SPEC)
9 * 6585 Merchant Place, Suite 100
12 * This product contains benchmarks acquired from several sources who
13 * understand and agree with SPEC's goal of creating fair and objective
14 * benchmarks to measure computer performance.
16 * This copyright notice is placed here only to protect SPEC in the
17 * event the source is misused in any manner that is contrary to the
18 * spirit, the goals and the intent of SPEC.
20 * The source code is provided to the user or company under the license
21 * agreement for the SPEC Benchmark Suite for this product.
24 /*****************************************************************
26 * Copyright 1991,1992 Legato Systems, Inc. *
27 * Copyright 1991,1992 Auspex Systems, Inc. *
28 * Copyright 1991,1992 Data General Corporation *
29 * Copyright 1991,1992 Digital Equipment Corporation *
30 * Copyright 1991,1992 Interphase Corporation *
31 * Copyright 1991,1992 Sun Microsystems, Inc. *
33 *****************************************************************/
36 * ---------------------- sfs_3_ops.c ---------------------
38 * RPC routines to implement the NFS protocol.
42 * int op_getattr(void)
46 * int op_readlink(void)
48 * int op_write(int, int, stable_how)
51 * int op_symlink(void);
53 * int op_remove(void);
55 * int op_rename(void);
57 * int op_readdir(void);
58 * int op_readdirplus(void);
59 * int op_fsstat(void);
60 * int op_fsinfo(void);
61 * int op_pathconf(void);
62 * int op_commit(void);
65 * 30-Jun-94 ChakChung Ng Created.
70 * ------------------------- Include Files -------------------------
81 #include <sys/types.h>
86 #include "sfs_c_def.h"
89 * -------------------- Local NFS ops function --------------------
91 static int op_null(void);
92 static int op_getattr(void);
93 static int op_setattr(int);
94 static int op_lookup(void);
95 static int op_access(void);
96 static int op_readlink(void);
97 static int op_read(int);
98 static int op_write(int, int, stable_how);
99 static int op_create(void);
100 static int op_mkdir(void);
101 static int op_symlink(void);
102 static int op_mknod(void);
103 static int op_remove(void);
104 static int op_rmdir(void);
105 static int op_rename(void);
106 static int op_link(void);
107 static int op_readdir(void);
108 static int op_readdirplus(void);
109 static int op_fsstat(void);
110 static int op_fsinfo(void);
111 static int op_pathconf(void);
112 static int op_commit(void);
113 static int op_nosys(void);
114 static char *nfs3_strerror(int);
118 * -------------------- NFS ops vector --------------------
121 * per operation information
123 static sfs_op_type nfsv3_Ops[] = {
125 /* name mix function op call no req req req results */
126 /* pcnt class targ call pcnt cnt targ */
128 { "null", 0, op_null, Lookup, 0, 0, 0.0, 0, 0, { 0, }},
129 { "getattr", 11, op_getattr, Lookup, 0, 0, 0.0, 0, 0, { 0, }},
130 { "setattr", 1, op_setattr, Write, 0, 0, 0.0, 0, 0, { 0, }},
131 { "root", 0, op_nosys, Lookup, 0, 0, 0.0, 0, 0, { 0, }},
132 { "lookup", 27, op_lookup, Lookup, 0, 0, 0.0, 0, 0, { 0, }},
133 { "readlink", 7, op_readlink, Lookup, 0, 0, 0.0, 0, 0, { 0, }},
134 { "read", 18, op_read, Read, 0, 0, 0.0, 0, 0, { 0, }},
135 { "wrcache", 0, op_nosys, Lookup, 0, 0, 0.0, 0, 0, { 0, }},
136 { "write", 9, op_write, Write, 0, 0, 0.0, 0, 0, { 0, }},
137 { "create", 1, op_create, Write, 0, 0, 0.0, 0, 0, { 0, }},
138 { "remove", 1, op_remove, Write, 0, 0, 0.0, 0, 0, { 0, }},
139 { "rename", 0, op_rename, Write, 0, 0, 0.0, 0, 0, { 0, }},
140 { "link", 0, op_link, Write, 0, 0, 0.0, 0, 0, { 0, }},
141 { "symlink", 0, op_symlink, Write, 0, 0, 0.0, 0, 0, { 0, }},
142 { "mkdir", 0, op_mkdir, Write, 0, 0, 0.0, 0, 0, { 0, }},
143 { "rmdir", 0, op_rmdir, Write, 0, 0, 0.0, 0, 0, { 0, }},
144 { "readdir", 2, op_readdir, Read, 0, 0, 0.0, 0, 0, { 0, }},
145 { "fsstat", 1, op_fsstat, Lookup, 0, 0, 0.0, 0, 0, { 0, }},
146 { "access", 7, op_access, Lookup, 0, 0, 0.0, 0, 0, { 0, }},
147 { "commit", 5, op_commit, Write, 0, 0, 0.0, 0, 0, { 0, }},
148 { "fsinfo", 1, op_fsinfo, Lookup, 0, 0, 0.0, 0, 0, { 0, }},
149 { "mknod", 0, op_mknod, Write, 0, 0, 0.0, 0, 0, { 0, }},
150 { "pathconf", 0, op_pathconf, Lookup, 0, 0, 0.0, 0, 0, { 0, }},
151 { "readdirplus", 9, op_readdirplus, Read, 0, 0, 0.0, 0, 0, { 0, }},
152 { "TOTAL", 100, 0, Lookup, 0, 0, 0.0, 0, 0, { 0, }}
158 * -------------------- RPC routines for NFS protocol --------------------
165 nfs_version = NFS_V3;
169 * The routines below attempt to do over-the-wire operations.
170 * Each op tries to cause one or more of a particular
171 * NFS operation to go over the wire. OPs return the success
172 * of their NFS call(s). Each OP records how many calls it
173 * actually made in global data.
175 * An array of file information is kept for files existing in
176 * the test directory. File handles, attributes, names, etc
177 * are stored in this array.
182 * Generic catch all for operations not covered by this protocol.
187 RFS_ASSERT (dep_tab[i].flag == TO_BE_SENT);
188 dep_tab[i].flag = DONE;
189 Ops[TOTAL].results.bad_calls++;
195 static struct biod_req *
196 get_biod_reqp (int dep_tab_index)
198 static int index = 0;
201 for (i=0; i<max_biod_reqs; i++, index = (index+1)%max_biod_reqs) {
202 if (biod_reqp[index].in_use == FALSE) {
203 biod_reqp[index].in_use = TRUE;
204 dep_tab[dep_tab_index].biod_index = index;
205 biod_req[index].dep_tab_index = dep_tab_index;
206 return (biod_reqp+index);
214 sfs_op_type *op_ptr; /* per operation info */
215 enum clnt_stat rpc_stat; /* result from RPC call */
216 struct ladtime start;
218 int ret; /* ret val == call success */
220 struct biod_req * reqp;
221 struct ladtime call_timeout;
223 if (dep_tab[i].flag == SENT)
226 op_ptr = &Ops[NULLCALL];
227 reqp = get_biod_reqp(i);
229 call_timeout.sec = Nfs_timers[op_ptr->call_class].tv_sec;
230 call_timeout.usec = Nfs_timers[op_ptr->call_class].tv_usec;
235 sfs_gettime(&reqp->start);
236 reqp->xid = boid_clnt_call(NFS_client, NFS3PROC_NULL, xdr_void, (char *)0);
237 if (reqp->xid != 0) {
238 reqp->timeout = reqp->start;
239 ADDTIME (reqp->timeout, call_timeout);
241 dep_tab[i].flag = SENT;
248 rpc_stat = clnt_call(NFS_client, NFSPROC3_NULL,
249 xdr_void, (char *)0, xdr_void, (char *)0,
250 (Current_test_phase < Warmup_phase)
252 : Nfs_timers[op_ptr->call_class]);
256 if (rpc_stat == RPC_SUCCESS) {
257 sfs_elapsedtime(op_ptr, &start, &stop);
258 op_ptr->results.good_calls++;
259 Ops[TOTAL].results.good_calls++;
262 if (DEBUG_CHILD_ERROR) {
263 (void) fprintf(stderr, "%s: null_op call RPC error %d\n",
264 sfs_Myname, rpc_stat);
266 op_ptr->results.bad_calls++;
267 Ops[TOTAL].results.bad_calls++;
277 sfs_op_type *op_ptr; /* per operation info */
278 GETATTR3args args; /* fh to do op on */
279 GETATTR3res reply; /* the reply */
280 enum clnt_stat rpc_stat; /* result from RPC call */
281 struct ladtime start;
283 int ret; /* ret val == call success */
285 op_ptr = &Ops[GETATTR];
288 /* set up the arguments */
289 (void) memmove((char *) &args.object, (char *) &Cur_file_ptr->fh3,
294 rpc_stat = clnt_call(NFS_client, NFSPROC3_GETATTR,
295 xdr_GETATTR3args, (char *) &args,
296 xdr_GETATTR3res, (char *) &reply,
297 (Current_test_phase < Warmup_phase)
299 : Nfs_timers[op_ptr->call_class]);
303 if (rpc_stat == RPC_SUCCESS) {
304 if (reply.status == NFS3_OK) {
305 (void) memmove((char *) &Cur_file_ptr->attributes3,
306 (char *) &reply.resok.obj_attributes,
307 sizeof (Cur_file_ptr->attributes3));
308 Cur_file_ptr->size = fh_size(Cur_file_ptr);
310 if (DEBUG_CHILD_ERROR) {
311 (void) fprintf(stderr,
312 "%s: getattr call NFS error %s on file %d\n",
313 sfs_Myname, nfs3_strerror(reply.status),
314 Cur_file_ptr->unique_num);
317 sfs_elapsedtime(op_ptr, &start, &stop);
318 op_ptr->results.good_calls++;
319 Ops[TOTAL].results.good_calls++;
322 if (DEBUG_CHILD_ERROR) {
323 (void) fprintf(stderr,
324 "%s: getattr call RPC error %d on file %d\n",
325 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
327 op_ptr->results.bad_calls++;
328 Ops[TOTAL].results.bad_calls++;
336 * perform an RPC setattr operation. If 'truncate_size' is non-negative,
337 * truncate the file to that size.
343 sfs_op_type *op_ptr; /* per operation info */
345 SETATTR3res reply; /* the reply */
346 enum clnt_stat rpc_stat; /* result from RPC call */
347 struct ladtime start;
349 int ret; /* ret val == call success */
351 op_ptr = &Ops[SETATTR];
354 /* set up the arguments */
355 (void) memmove((char *) &args.object, (char *) &Cur_file_ptr->fh3,
357 args.new_attributes.mode.set_it = TRUE;
358 args.new_attributes.mode.mode = (uint32_t) 0666;
359 args.new_attributes.uid.set_it = FALSE;
360 args.new_attributes.uid.uid = (uint32_t) -1;
361 args.new_attributes.gid.set_it = FALSE;
362 args.new_attributes.gid.gid = (uint32_t) -1;
363 args.new_attributes.size.set_it = FALSE;
364 args.new_attributes.size.size._p._u = (uint32_t) ~0;
365 args.new_attributes.size.size._p._l = (uint32_t) -1;
366 args.new_attributes.atime.set_it = TRUE;
367 args.new_attributes.atime.atime.seconds = Cur_time.esec;
368 args.new_attributes.atime.atime.nseconds = Cur_time.usec * 1000;
369 args.new_attributes.mtime.set_it = TRUE;
370 args.new_attributes.mtime.mtime.seconds = Cur_time.esec;
371 args.new_attributes.mtime.mtime.nseconds = Cur_time.usec * 1000;
372 args.guard.check = FALSE;
374 /* handle file truncations */
375 if (truncate_size >= 0) {
376 args.new_attributes.size.set_it = TRUE;
377 args.new_attributes.size.size._p._u = (uint32_t) 0;
378 if (truncate_size > Cur_file_ptr->attributes3.size._p._l)
379 args.new_attributes.size.size._p._l = (uint32_t) 0;
381 args.new_attributes.size.size._p._l =
382 (uint32_t) Cur_file_ptr->attributes3.size._p._l -
388 rpc_stat = clnt_call(NFS_client, NFSPROC3_SETATTR,
389 xdr_SETATTR3args, (char *) &args,
390 xdr_SETATTR3res, (char *) &reply,
391 (Current_test_phase < Warmup_phase)
393 : Nfs_timers[op_ptr->call_class]);
398 if (rpc_stat == RPC_SUCCESS) {
399 if (reply.status == NFS3_OK) {
400 (void) memmove((char *) &Cur_file_ptr->attributes3,
401 (char *) &reply.resok.obj_wcc.after.attr,
402 sizeof (Cur_file_ptr->attributes3));
403 Cur_file_ptr->size = fh_size(Cur_file_ptr);
405 if (DEBUG_CHILD_ERROR) {
406 (void) fprintf(stderr,
407 "%s: setattr call NFS error %s on file %d\n",
408 sfs_Myname, nfs3_strerror(reply.status),
409 Cur_file_ptr->unique_num);
412 sfs_elapsedtime(op_ptr, &start, &stop);
413 op_ptr->results.good_calls++;
414 Ops[TOTAL].results.good_calls++;
417 if (DEBUG_CHILD_ERROR) {
418 (void) fprintf(stderr,
419 "%s: setattr call RPC error %d on file %d\n",
420 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
422 op_ptr->results.bad_calls++;
423 Ops[TOTAL].results.bad_calls++;
433 sfs_op_type *op_ptr; /* per operation info */
435 LOOKUP3res reply; /* the reply */
436 enum clnt_stat rpc_stat; /* result from RPC call */
437 struct ladtime start;
439 int ret; /* ret val == call success */
441 op_ptr = &Ops[LOOKUP];
444 /* set up the arguments */
445 (void) memmove((char *) &args.what.dir, (char *) &Cur_file_ptr->dir->fh3,
447 args.what.name = Cur_filename;
448 (void) memset((char *) &reply.resok.object, '\0', sizeof (nfs_fh3));
452 rpc_stat = clnt_call(NFS_client, NFSPROC3_LOOKUP,
453 xdr_LOOKUP3args, (char *) &args,
454 xdr_LOOKUP3res, (char *) &reply,
455 (Current_test_phase < Warmup_phase)
457 : Nfs_timers[op_ptr->call_class]);
461 if (rpc_stat == RPC_SUCCESS) {
462 if (reply.status == NFS3_OK) {
463 Cur_file_ptr->state = Exists;
464 (void) memmove((char *) &Cur_file_ptr->fh3,
465 (char *) &reply.resok.object,
467 (void) strcpy(Cur_file_ptr->file_name, Cur_filename);
468 (void) memmove((char *) &Cur_file_ptr->attributes3,
469 (char *) &reply.resok.obj_attributes.attr,
470 sizeof (Cur_file_ptr->attributes3));
471 Cur_file_ptr->size = fh_size(Cur_file_ptr);
473 /* We do lookup Nonexistent and this is not an error */
474 if (reply.status != NFS3ERR_NOENT ||
475 Cur_file_ptr->state != Nonexistent) {
476 if (DEBUG_CHILD_ERROR) {
477 (void) fprintf(stderr,
478 "%s: lookup call NFS error %s on file %d\n",
479 sfs_Myname, nfs3_strerror(reply.status),
480 Cur_file_ptr->unique_num);
484 sfs_elapsedtime(op_ptr, &start, &stop);
485 op_ptr->results.good_calls++;
486 Ops[TOTAL].results.good_calls++;
489 if (DEBUG_CHILD_ERROR) {
490 (void) fprintf(stderr, "%s: lookup call RPC error %d on file %d\n",
491 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
493 op_ptr->results.bad_calls++;
494 Ops[TOTAL].results.bad_calls++;
504 sfs_op_type *op_ptr; /* per operation info */
506 ACCESS3res reply; /* the reply */
507 enum clnt_stat rpc_stat; /* result from RPC call */
508 struct ladtime start;
510 int ret; /* ret val == call success */
512 op_ptr = &Ops[ACCESS];
515 /* set up the arguments */
516 (void) memmove((char *) &args.object, (char *) &Cur_file_ptr->dir->fh3,
518 args.access = ACCESS3_MODIFY;
522 rpc_stat = clnt_call(NFS_client, NFSPROC3_ACCESS,
523 xdr_ACCESS3args, (char *) &args,
524 xdr_ACCESS3res, (char *) &reply,
525 (Current_test_phase < Warmup_phase)
527 : Nfs_timers[op_ptr->call_class]);
531 if (rpc_stat == RPC_SUCCESS) {
532 if (reply.status == NFS3_OK) {
533 Cur_file_ptr->state = Exists;
534 (void) memmove((char *) &Cur_file_ptr->attributes3,
535 (char *) &reply.resok.obj_attributes.attr,
536 sizeof (Cur_file_ptr->attributes3));
537 Cur_file_ptr->size = fh_size(Cur_file_ptr);
539 if (DEBUG_CHILD_ERROR) {
540 (void) fprintf(stderr,
541 "%s: access call NFS error %s on file %d\n",
542 sfs_Myname, nfs3_strerror(reply.status),
543 Cur_file_ptr->unique_num);
546 sfs_elapsedtime(op_ptr, &start, &stop);
547 op_ptr->results.good_calls++;
548 Ops[TOTAL].results.good_calls++;
551 if (DEBUG_CHILD_ERROR) {
552 (void) fprintf(stderr, "%s: access call RPC error %d on file %d\n",
553 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
555 op_ptr->results.bad_calls++;
556 Ops[TOTAL].results.bad_calls++;
566 sfs_op_type *op_ptr; /* per operation info */
567 READLINK3args args; /* the args */
568 READLINK3res reply; /* the reply */
569 char sym_data[NFS_MAXPATHLEN];
570 enum clnt_stat rpc_stat; /* result from RPC call */
571 struct ladtime start;
573 int ret; /* ret val == call success */
575 op_ptr = &Ops[READLINK];
578 /* set up the arguments */
580 * Note: this symlink may be bogus because SYMLINK does
581 * not return a symlink ... only a status. So unless we have
582 * done a LOOKUP on this guy, the symlink will probably be bad.
583 * If it is bad it shows up as a symlink error in the results.
585 (void) memmove((char *) &args.symlink,
586 (char *) &Cur_file_ptr->fh3,
589 /* Have lower layers fill in the data directly. */
590 reply.resok.data = sym_data;
592 /* make the call now */
594 rpc_stat = clnt_call(NFS_client, NFSPROC3_READLINK,
595 xdr_READLINK3args, (char *) &args,
596 xdr_READLINK3res, (char *) &reply,
597 (Current_test_phase < Warmup_phase)
599 : Nfs_timers[op_ptr->call_class]);
603 if (rpc_stat == RPC_SUCCESS) {
604 if (reply.status == NFS3_OK) {
605 if (DEBUG_CHILD_RPC) {
606 (void) fprintf(stderr, "%s: READLINK on %s returned %s\n",
607 sfs_Myname, Cur_filename, sym_data);
608 (void) fflush(stderr);
611 if (DEBUG_CHILD_ERROR) {
612 (void) fprintf(stderr,
613 "%s: readlink call NFS error %s on file %d\n",
614 sfs_Myname, nfs3_strerror(reply.status),
615 Cur_file_ptr->unique_num);
618 sfs_elapsedtime(op_ptr, &start, &stop);
619 op_ptr->results.good_calls++;
620 Ops[TOTAL].results.good_calls++;
623 if (DEBUG_CHILD_ERROR) {
624 (void) fprintf(stderr,
625 "%s: readlink call RPC error %d on file %d\n",
626 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
628 op_ptr->results.bad_calls++;
629 Ops[TOTAL].results.bad_calls++;
637 * perform an RPC read operation of length 'xfer_size'
643 sfs_op_type *op_ptr; /* per operation info */
645 int max_cnt; /* packet ctrs */
646 char buf[DEFAULT_MAX_BUFSIZE];/* data buffer */
648 READ3res reply; /* the reply */
649 enum clnt_stat rpc_stat; /* result from RPC call */
650 struct ladtime start;
654 int ret; /* ret val == call success */
659 /* set up the arguments */
660 (void) memmove((char *) &args.file,
661 (char *) &Cur_file_ptr->fh3,
665 * Don't allow a read of less than one block size
667 if (xfer_size < Bytes_per_block)
668 xfer_size = Bytes_per_block;
671 * randomly choose an offset that is a multiple of the block size
672 * and constrained by making the transfer fit within the file
674 args.offset._p._u = 0;
675 if (Cur_file_ptr->attributes3.size._p._l > xfer_size)
676 args.offset._p._l = Bytes_per_block * (sfs_random() %
677 (((Cur_file_ptr->attributes3.size._p._l - xfer_size)
678 / Bytes_per_block) + 1));
680 args.offset._p._l = 0;
682 /* Have lower layers fill in the data directly. */
683 reply.resok.data.data_len = 0;
684 reply.resok.data.data_val = buf;
686 /* first read the whole buffers, then the fragment */
687 for (j = 0; j < 2; j++) {
690 size = Bytes_per_block;
691 max_cnt = xfer_size / Bytes_per_block;
693 /* 1KB - (Kb_per_block -1) KB fragment */
694 size = xfer_size % Bytes_per_block;
700 /* check our stats to see if this would overflow */
702 if (op_ptr->target_calls > 0) {
703 if ((op_ptr->results.good_calls + max_cnt)
704 > op_ptr->target_calls) {
705 max_cnt = op_ptr->target_calls - op_ptr->results.good_calls;
712 if (DEBUG_CHILD_RPC) {
713 (void) fprintf(stderr, "read: %d buffers\n", max_cnt);
714 (void) fflush(stderr);
717 /* make the call(s) now */
718 for (cur_cnt = 0; cur_cnt < max_cnt; cur_cnt++) {
720 /* capture length for possible dump */
721 Dump_length = fh_size(Cur_file_ptr);
724 rpc_stat = clnt_call(NFS_client, NFSPROC3_READ,
725 xdr_READ3args, (char *) &args,
726 xdr_READ3res, (char *) &reply,
727 (Current_test_phase < Warmup_phase)
729 : Nfs_timers[op_ptr->call_class]);
733 /* capture count and offset for possible dump */
734 Dump_count = (rpc_stat == RPC_SUCCESS && reply.status == NFS3_OK)
735 ? reply.resok.data.data_len : 0;
736 Dump_offset = args.offset._p._l;
738 if (rpc_stat == RPC_SUCCESS) {
739 if (reply.status == NFS3_OK) {
740 Cur_file_ptr->state = Exists;
741 (void) memmove((char *) &Cur_file_ptr->attributes3,
742 (char *) &reply.resok.file_attributes.attr,
743 sizeof (Cur_file_ptr->attributes3));
744 Cur_file_ptr->size = fh_size(Cur_file_ptr);
745 size = reply.resok.data.data_len;
747 if (DEBUG_CHILD_RPC) {
748 (void) fprintf(stderr, "%s: READ %s %d bytes\n",
749 sfs_Myname, Cur_filename, size);
750 (void) fflush(stderr);
752 args.offset._p._l += size;
754 if (DEBUG_CHILD_ERROR) {
755 (void) fprintf(stderr,
756 "%s: read call NFS error %s on file %d\n",
758 nfs3_strerror(reply.status),
759 Cur_file_ptr->unique_num);
762 sfs_elapsedtime(op_ptr, &start, &stop);
763 op_ptr->results.good_calls++;
764 Ops[TOTAL].results.good_calls++;
767 if (DEBUG_CHILD_ERROR) {
768 (void) fprintf(stderr,
769 "%s: read call RPC error %d on file %d\n",
770 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
772 op_ptr->results.bad_calls++;
773 Ops[TOTAL].results.bad_calls++;
775 } /* for reading max_cnt packets */
776 } /* for buffers and fragments */
786 static uint32_t write_buf[DEFAULT_MAX_BUFSIZE / sizeof(uint32_t)];
787 uint32_t *be = write_buf + (sizeof(write_buf) /
790 if (write_buf[0] != (uint32_t)0xdeadbeef) {
791 for (bp = write_buf; bp < be; bp++)
792 *bp = (uint32_t)0xdeadbeef;
794 return (char *)write_buf;
799 * Perform and RPC write operation of length 'xfer_size'. If 'append_flag'
800 * is true, then write the data to the end of the file.
802 * If the stab_flag is set to UNSTABLE we issue the requests and then
803 * issue a op_commit to sync the data.
809 stable_how stab_flag)
811 sfs_op_type *op_ptr; /* per operation info */
812 static char *buf = NULL; /* the data buffer */
813 unsigned int size; /* size of data write */
814 int cur_cnt; /* controls # NFS calls */
817 WRITE3res reply; /* the reply */
818 enum clnt_stat rpc_stat; /* result from RPC call */
819 struct ladtime start;
822 int ret; /* ret val == call success */
825 * For now we treat DATA_SYNC to be the same as FILE_SYNC.
827 if (stab_flag == DATA_SYNC)
828 stab_flag = FILE_SYNC;
831 * Initialize write buffer to known value
834 buf = init_write_buffer();
837 op_ptr = &Ops[WRITE];
840 /* set up the arguments */
841 (void) memmove((char *) &args.file, (char *) &Cur_file_ptr->fh3,
843 args.offset._p._u = 0;
844 if (append_flag == 1) {
845 args.offset._p._l = Cur_file_ptr->attributes3.size._p._l;
848 * randomly choose an offset that is a multiple of the block size
849 * and constrained by making the transfer fit within the file
851 if (Cur_file_ptr->attributes3.size._p._l > xfer_size) {
852 args.offset._p._l = Bytes_per_block * (sfs_random() %
853 (((Cur_file_ptr->attributes3.size._p._l - xfer_size)
854 / Bytes_per_block) + 1));
856 args.offset._p._l = 0;
859 /* stab_flag has to be set in op() in sfs_3_chd.c */
860 args.stable = stab_flag;
862 /* first write the whole buffers, then the fragment */
863 for (j = 0; j < 2; j++) {
866 size = Bytes_per_block;
867 max_cnt = xfer_size / Bytes_per_block;
869 /* 1KB - (Kb_per_block - 1) KB fragment */
870 size = xfer_size % Bytes_per_block;
877 args.data.data_len = size;
878 args.data.data_val = buf;
880 /* check our stats to see if this would overflow */
882 if (op_ptr->target_calls > 0) {
883 if ((op_ptr->results.good_calls + max_cnt)
884 > op_ptr->target_calls) {
885 max_cnt = op_ptr->target_calls - op_ptr->results.good_calls;
890 if (DEBUG_CHILD_RPC) {
891 (void) fprintf(stderr, "write: %d buffers\n", max_cnt);
892 (void) fflush(stderr);
895 /* make the call(s) now */
896 for (cur_cnt = 0; cur_cnt < max_cnt; cur_cnt++) {
898 if (DEBUG_CHILD_RPC) {
899 (void) fprintf(stderr, "%s: WRITE %s offset %u count %lu stable %d\n",
900 sfs_Myname, Cur_filename, args.offset._p._l, args.count, args.stable);
901 (void) fflush(stderr);
904 /* capture length for possible dump */
905 Dump_length = fh_size(Cur_file_ptr);
908 rpc_stat = clnt_call(NFS_client, NFSPROC3_WRITE,
909 xdr_WRITE3args, (char *) &args,
910 xdr_WRITE3res, (char *) &reply,
911 (Current_test_phase < Warmup_phase)
913 : Nfs_timers[op_ptr->call_class]);
917 /* capture count and offset for possible dump */
918 Dump_count = args.data.data_len;
919 Dump_offset = args.offset._p._l;
921 if (rpc_stat == RPC_SUCCESS) {
922 if (reply.status == NFS3_OK) {
923 Cur_file_ptr->state = Exists;
924 (void) memmove((char *) &Cur_file_ptr->attributes3,
925 (char *) &reply.resok.file_wcc.after.attr,
926 sizeof (Cur_file_ptr->attributes3));
927 Cur_file_ptr->size = fh_size(Cur_file_ptr);
928 args.offset._p._l += size;
930 if (DEBUG_CHILD_RPC) {
931 (void) fprintf(stderr, "%s: WRITE %s %d bytes\n",
932 sfs_Myname, Cur_filename, size);
933 (void) fflush(stderr);
936 if (DEBUG_CHILD_ERROR) {
937 (void) fprintf(stderr,
938 "%s: write call NFS error %s on file %d\n",
939 sfs_Myname, nfs3_strerror(reply.status),
940 Cur_file_ptr->unique_num);
943 sfs_elapsedtime(op_ptr, &start, &stop);
944 op_ptr->results.good_calls++;
945 Ops[TOTAL].results.good_calls++;
948 if (DEBUG_CHILD_ERROR) {
949 (void) fprintf(stderr,
950 "%s: write call RPC error %d on file %d\n",
951 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
953 op_ptr->results.bad_calls++;
954 Ops[TOTAL].results.bad_calls++;
956 } /* for writing max_cnt packets */
957 } /* for buffers and fragments */
960 * If we have not gotten an error and we were asked for an async write
961 * send a commit operation.
963 if (ret && stab_flag != FILE_SYNC)
974 sfs_op_type *op_ptr; /* per operation info */
976 CREATE3res reply; /* the reply */
977 enum clnt_stat rpc_stat; /* result from RPC call */
978 struct ladtime start;
980 int ret; /* ret val == call success */
982 op_ptr = &Ops[CREATE];
985 /* set up the arguments */
986 (void) memmove((char *) &args.where.dir, (char *) &Cur_file_ptr->dir->fh3,
988 args.where.name = Cur_filename;
989 args.how.mode = UNCHECKED;
990 args.how.createhow3_u.obj_attributes.mode.set_it = TRUE;
991 args.how.createhow3_u.obj_attributes.mode.mode = (NFSMODE_REG | 0666);
992 args.how.createhow3_u.obj_attributes.uid.set_it = TRUE;
993 args.how.createhow3_u.obj_attributes.uid.uid = Cur_uid;
994 args.how.createhow3_u.obj_attributes.gid.set_it = TRUE;
995 args.how.createhow3_u.obj_attributes.gid.gid = Cur_gid;
996 args.how.createhow3_u.obj_attributes.atime.set_it = TRUE;
997 args.how.createhow3_u.obj_attributes.atime.atime.seconds = Cur_time.esec;
998 args.how.createhow3_u.obj_attributes.atime.atime.nseconds =
999 Cur_time.usec * 1000;
1000 args.how.createhow3_u.obj_attributes.mtime.set_it = TRUE;
1001 args.how.createhow3_u.obj_attributes.mtime.mtime.seconds = Cur_time.esec;
1002 args.how.createhow3_u.obj_attributes.mtime.mtime.nseconds =
1003 Cur_time.usec * 1000;
1004 args.how.createhow3_u.obj_attributes.size.set_it = TRUE;
1005 args.how.createhow3_u.obj_attributes.size.size._p._u = (uint32_t) 0;
1006 args.how.createhow3_u.obj_attributes.size.size._p._l = (uint32_t) 0;
1008 /* make the call now */
1009 sfs_gettime(&start);
1010 rpc_stat = clnt_call(NFS_client, NFSPROC3_CREATE,
1011 xdr_CREATE3args, (char *) &args,
1012 xdr_CREATE3res, (char *) &reply,
1013 (Current_test_phase < Warmup_phase)
1015 : Nfs_timers[op_ptr->call_class]);
1019 if (rpc_stat == RPC_SUCCESS) {
1020 if (reply.status == NFS3_OK) {
1021 Cur_file_ptr->state = Exists;
1022 (void) memmove((char *) &Cur_file_ptr->fh3,
1023 (char *) &reply.resok.obj.handle,
1025 (void) strcpy(Cur_file_ptr->file_name, Cur_filename);
1026 (void) memmove((char *) &Cur_file_ptr->attributes3,
1027 (char *) &reply.resok.obj_attributes.attr,
1028 sizeof(Cur_file_ptr->attributes3));
1029 Cur_file_ptr->size = fh_size(Cur_file_ptr);
1031 if (DEBUG_CHILD_ERROR) {
1032 (void) fprintf(stderr,
1033 "%s: create call NFS error %s on file %d\n",
1034 sfs_Myname, nfs3_strerror(reply.status),
1035 Cur_file_ptr->unique_num);
1038 sfs_elapsedtime(op_ptr, &start, &stop);
1039 op_ptr->results.good_calls++;
1040 Ops[TOTAL].results.good_calls++;
1043 if (DEBUG_CHILD_ERROR) {
1044 (void) fprintf(stderr, "%s: create call RPC error %d on file %d\n",
1045 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1047 op_ptr->results.bad_calls++;
1048 Ops[TOTAL].results.bad_calls++;
1058 sfs_op_type *op_ptr; /* per operation info */
1060 MKDIR3res reply; /* the reply */
1061 enum clnt_stat rpc_stat; /* result from RPC call */
1062 struct ladtime start;
1063 struct ladtime stop;
1064 int ret; /* ret val == call success */
1066 op_ptr = &Ops[MKDIR];
1069 /* set up the arguments */
1070 (void) memmove((char *) &args.where.dir, (char *) &Cur_file_ptr->dir->fh3,
1072 args.where.name = Cur_filename;
1073 args.attributes.mode.set_it = TRUE;
1074 args.attributes.mode.mode = (NFSMODE_DIR | 0777);
1075 args.attributes.uid.set_it = TRUE;
1076 args.attributes.uid.uid = Cur_uid;
1077 args.attributes.gid.set_it = TRUE;
1078 args.attributes.gid.gid = Cur_gid;
1079 args.attributes.size.set_it = TRUE;
1080 args.attributes.size.size._p._u = 0;
1081 args.attributes.size.size._p._l = 512;
1082 args.attributes.atime.set_it = TRUE;
1083 args.attributes.atime.atime.seconds = Cur_time.esec;
1084 args.attributes.atime.atime.nseconds = Cur_time.usec * 1000;
1085 args.attributes.mtime.set_it = TRUE;
1086 args.attributes.mtime.mtime.seconds = Cur_time.esec;
1087 args.attributes.mtime.mtime.nseconds = Cur_time.usec * 1000;
1089 /* make the call now */
1090 sfs_gettime(&start);
1091 rpc_stat = clnt_call(NFS_client, NFSPROC3_MKDIR,
1092 xdr_MKDIR3args, (char *) &args,
1093 xdr_MKDIR3res, (char *) &reply,
1094 (Current_test_phase < Warmup_phase)
1096 : Nfs_timers[op_ptr->call_class]);
1100 if (rpc_stat == RPC_SUCCESS) {
1101 if (reply.status == NFS3_OK) {
1102 Cur_file_ptr->state = Empty_dir;
1103 (void) memmove((char *) &Cur_file_ptr->fh3,
1104 (char *) &reply.resok.obj.handle,
1106 (void) strcpy(Cur_file_ptr->file_name, Cur_filename);
1107 (void) memmove((char *) &Cur_file_ptr->attributes3,
1108 (char *) &reply.resok.obj_attributes.attr,
1109 sizeof(Cur_file_ptr->attributes3));
1110 Cur_file_ptr->size = fh_size(Cur_file_ptr);
1112 if (DEBUG_CHILD_ERROR) {
1113 (void) fprintf(stderr,
1114 "%s: mkdir call NFS error %s on file %d\n",
1115 sfs_Myname, nfs3_strerror(reply.status),
1116 Cur_file_ptr->unique_num);
1119 sfs_elapsedtime(op_ptr, &start, &stop);
1120 op_ptr->results.good_calls++;
1121 Ops[TOTAL].results.good_calls++;
1124 if (DEBUG_CHILD_ERROR) {
1125 (void) fprintf(stderr, "%s: mkdir call RPC error %d on file %d\n",
1126 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1128 op_ptr->results.bad_calls++;
1129 Ops[TOTAL].results.bad_calls++;
1139 sfs_op_type *op_ptr; /* per operation info */
1140 sfs_fh_type *target_fileinfo_ptr; /* target file */
1142 SYMLINK3res reply; /* the reply */
1143 char sym_data[NFS_MAXPATHLEN]; /* symlink data */
1144 enum clnt_stat rpc_stat; /* result from RPC call */
1145 struct ladtime start;
1146 struct ladtime stop;
1147 int ret; /* ret val == call success */
1149 op_ptr = &Ops[SYMLINK];
1152 /* set up the arguments */
1153 target_fileinfo_ptr = randfh(SYMLINK, 0, 0, Exists, Sfs_non_io_file);
1154 (void) memmove((char *) &args.where.dir, (char *) &Cur_file_ptr->dir->fh3,
1156 args.where.name = Cur_filename;
1158 (void) strcpy(sym_data, "./");
1159 (void) strcat(sym_data, target_fileinfo_ptr->file_name);
1160 args.symlink.symlink_attributes.size.set_it = TRUE;
1161 args.symlink.symlink_attributes.size.size._p._u = (uint32_t) 0;
1162 args.symlink.symlink_attributes.size.size._p._l = strlen(sym_data);
1163 args.symlink.symlink_data = sym_data;
1165 args.symlink.symlink_attributes.mode.set_it = TRUE;
1166 args.symlink.symlink_attributes.mode.mode = (NFSMODE_LNK | 0777);
1167 args.symlink.symlink_attributes.uid.set_it = TRUE;
1168 args.symlink.symlink_attributes.uid.uid = Cur_uid;
1169 args.symlink.symlink_attributes.gid.set_it = TRUE;
1170 args.symlink.symlink_attributes.gid.gid = Cur_gid;
1171 args.symlink.symlink_attributes.atime.set_it = TRUE;
1172 args.symlink.symlink_attributes.atime.atime.seconds = Cur_time.esec;
1173 args.symlink.symlink_attributes.atime.atime.nseconds =
1174 Cur_time.usec * 1000;
1175 args.symlink.symlink_attributes.mtime.set_it = TRUE;
1176 args.symlink.symlink_attributes.mtime.mtime.seconds = Cur_time.esec;
1177 args.symlink.symlink_attributes.mtime.mtime.nseconds =
1178 Cur_time.usec * 1000;
1180 /* make the call now */
1181 sfs_gettime(&start);
1182 rpc_stat = clnt_call(NFS_client, NFSPROC3_SYMLINK,
1183 xdr_SYMLINK3args, (char *) &args,
1184 xdr_SYMLINK3res, (char *) &reply,
1185 ((int)Current_test_phase < (int)Warmup_phase)
1187 : Nfs_timers[op_ptr->call_class]);
1191 if (rpc_stat == RPC_SUCCESS) {
1192 if (reply.status == NFS3_OK) {
1194 * SYMLINK doesn't return a fh. If we try to access this symlink
1195 * (eg, remove(), readlink()) before we do a lookup, we won't have
1196 * a fh to use. So, we do a lookup call here. If it fails, we fill
1199 Cur_file_ptr->state = Exists;
1200 if (op_lookup() == 0) {
1201 (void) strcpy(Cur_file_ptr->file_name, Cur_filename);
1202 Cur_file_ptr->attributes3.type = NF3LNK;
1203 Cur_file_ptr->attributes3.mode = (NFSMODE_LNK|0777);
1204 Cur_file_ptr->attributes3.uid = Cur_uid;
1205 Cur_file_ptr->attributes3.gid = Cur_gid;
1206 Cur_file_ptr->attributes3.atime.seconds = Cur_time.esec;
1207 Cur_file_ptr->attributes3.atime.nseconds =
1208 Cur_time.usec * 1000;
1209 Cur_file_ptr->attributes3.mtime =
1210 Cur_file_ptr->attributes3.atime;
1214 if (DEBUG_CHILD_ERROR) {
1215 (void) fprintf(stderr,
1216 "%s: symlink call NFS error %s on file %d\n",
1217 sfs_Myname, nfs3_strerror(reply.status),
1218 Cur_file_ptr->unique_num);
1221 sfs_elapsedtime(op_ptr, &start, &stop);
1222 op_ptr->results.good_calls++;
1223 Ops[TOTAL].results.good_calls++;
1226 if (DEBUG_CHILD_ERROR) {
1227 (void) fprintf(stderr,
1228 "%s: symlink call RPC error %d on file %d\n",
1229 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1231 op_ptr->results.bad_calls++;
1232 Ops[TOTAL].results.bad_calls++;
1242 sfs_op_type *op_ptr; /* per operation info */
1245 enum clnt_stat rpc_stat; /* result from RPC call */
1246 struct ladtime start;
1247 struct ladtime stop;
1248 int ret; /* ret val == call success */
1250 op_ptr = &Ops[MKNOD];
1253 /* set up the arguments */
1254 (void) memmove((char *) &args.where.dir, (char *) &Cur_file_ptr->dir->fh3,
1256 args.where.name = Cur_filename;
1257 args.what.type = NF3FIFO;
1258 args.what.mknoddata3_u.pipe_attributes.mode.set_it = TRUE;
1259 args.what.mknoddata3_u.pipe_attributes.mode.mode = (NFSMODE_FIFO | 0777);
1260 args.what.mknoddata3_u.pipe_attributes.uid.set_it = TRUE;
1261 args.what.mknoddata3_u.pipe_attributes.uid.uid = Cur_uid;
1262 args.what.mknoddata3_u.pipe_attributes.gid.set_it = TRUE;
1263 args.what.mknoddata3_u.pipe_attributes.gid.gid = Cur_gid;
1264 args.what.mknoddata3_u.pipe_attributes.size.set_it = TRUE;
1265 args.what.mknoddata3_u.pipe_attributes.size.size._p._u = (uint32_t) 0;
1266 args.what.mknoddata3_u.pipe_attributes.size.size._p._l =
1268 args.what.mknoddata3_u.pipe_attributes.atime.set_it = TRUE;
1269 args.what.mknoddata3_u.pipe_attributes.atime.atime.seconds =
1271 args.what.mknoddata3_u.pipe_attributes.atime.atime.nseconds =
1272 Cur_time.usec * 1000;
1273 args.what.mknoddata3_u.pipe_attributes.atime.set_it = TRUE;
1274 args.what.mknoddata3_u.pipe_attributes.mtime.mtime.seconds =
1276 args.what.mknoddata3_u.pipe_attributes.mtime.mtime.nseconds =
1277 Cur_time.usec * 1000;
1279 /* make the call now */
1280 sfs_gettime(&start);
1281 rpc_stat = clnt_call(NFS_client, NFSPROC3_MKNOD,
1282 xdr_MKNOD3args, (char *) &args,
1283 xdr_MKNOD3res, (char *) &reply,
1284 (Current_test_phase < Warmup_phase)
1286 : Nfs_timers[op_ptr->call_class]);
1290 if (rpc_stat == RPC_SUCCESS) {
1291 if (reply.status == NFS3_OK) {
1292 Cur_file_ptr->state = Exists;
1293 (void) memmove((char *) &Cur_file_ptr->fh3,
1294 (char *) &reply.resok.obj.handle,
1296 (void) strcpy(Cur_file_ptr->file_name, Cur_filename);
1297 (void) memmove((char *) &Cur_file_ptr->attributes3,
1298 (char *) &reply.resok.obj_attributes.attr,
1299 sizeof(Cur_file_ptr->attributes3));
1300 Cur_file_ptr->size = fh_size(Cur_file_ptr);
1302 if (DEBUG_CHILD_ERROR) {
1303 (void) fprintf(stderr,
1304 "%s: mknod call NFS error %s on file %d\n",
1305 sfs_Myname, nfs3_strerror(reply.status),
1306 Cur_file_ptr->unique_num);
1309 sfs_elapsedtime(op_ptr, &start, &stop);
1310 op_ptr->results.good_calls++;
1311 Ops[TOTAL].results.good_calls++;
1314 if (DEBUG_CHILD_ERROR) {
1315 (void) fprintf(stderr, "%s: mknod call RPC error %d on file %d\n",
1316 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1318 op_ptr->results.bad_calls++;
1319 Ops[TOTAL].results.bad_calls++;
1329 sfs_op_type *op_ptr; /* per operation info */
1331 REMOVE3res reply; /* the reply */
1332 enum clnt_stat rpc_stat; /* result from RPC call */
1333 struct ladtime start;
1334 struct ladtime stop;
1335 int ret; /* ret val == call success */
1337 op_ptr = &Ops[REMOVE];
1340 /* set up the arguments */
1341 args.object.name = Cur_filename;
1342 (void) memmove((char *) &args.object.dir,(char *) &Cur_file_ptr->dir->fh3,
1345 /* make the call now */
1346 sfs_gettime(&start);
1347 rpc_stat = clnt_call(NFS_client, NFSPROC3_REMOVE,
1348 xdr_REMOVE3args, (char *) &args,
1349 xdr_REMOVE3res, (char *) &reply,
1350 (Current_test_phase < Warmup_phase)
1352 : Nfs_timers[op_ptr->call_class]);
1356 if (rpc_stat == RPC_SUCCESS) {
1357 if (reply.status == NFS3_OK) {
1358 Cur_file_ptr->state = Nonexistent;
1360 if (DEBUG_CHILD_ERROR) {
1361 (void) fprintf(stderr,
1362 "%s: remove call NFS error %s on file %d\n",
1363 sfs_Myname, nfs3_strerror(reply.status),
1364 Cur_file_ptr->unique_num);
1367 sfs_elapsedtime(op_ptr, &start, &stop);
1368 op_ptr->results.good_calls++;
1369 Ops[TOTAL].results.good_calls++;
1372 if (DEBUG_CHILD_ERROR) {
1373 (void) fprintf(stderr, "%s: remove call RPC error %d on file %d\n",
1374 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1376 op_ptr->results.bad_calls++;
1377 Ops[TOTAL].results.bad_calls++;
1387 sfs_op_type *op_ptr; /* per operation info */
1389 RMDIR3res reply; /* the reply */
1390 enum clnt_stat rpc_stat; /* result from RPC call */
1391 struct ladtime start;
1392 struct ladtime stop;
1393 int ret; /* ret val == call success */
1395 op_ptr = &Ops[RMDIR];
1398 /* set up the arguments */
1399 (void) memmove((char *) &args.object.dir, (char *) &Cur_file_ptr->dir->fh3,
1401 args.object.name = Cur_file_ptr->file_name;
1403 /* make the call now */
1404 sfs_gettime(&start);
1405 rpc_stat = clnt_call(NFS_client, NFSPROC3_RMDIR,
1406 xdr_RMDIR3args, (char *) &args,
1407 xdr_RMDIR3res, (char *) &reply,
1408 (Current_test_phase < Warmup_phase)
1410 : Nfs_timers[op_ptr->call_class]);
1414 if (rpc_stat == RPC_SUCCESS) {
1415 if (reply.status == NFS3_OK) {
1416 Cur_file_ptr->state = Nonexistent;
1418 if (DEBUG_CHILD_ERROR) {
1419 (void) fprintf(stderr,
1420 "%s: rmdir call NFS error %s on file %d\n",
1421 sfs_Myname, nfs3_strerror(reply.status),
1422 Cur_file_ptr->unique_num);
1425 sfs_elapsedtime(op_ptr, &start, &stop);
1426 op_ptr->results.good_calls++;
1427 Ops[TOTAL].results.good_calls++;
1430 if (DEBUG_CHILD_ERROR) {
1431 (void) fprintf(stderr, "%s: rmdir call RPC error %d on file %d\n",
1432 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1434 op_ptr->results.bad_calls++;
1435 Ops[TOTAL].results.bad_calls++;
1445 sfs_op_type *op_ptr; /* per operation info */
1446 sfs_fh_type *target_fileinfo_ptr; /* target name */
1448 RENAME3res reply; /* the reply */
1449 enum clnt_stat rpc_stat; /* result from RPC call */
1450 struct ladtime start;
1451 struct ladtime stop;
1452 int ret; /* ret val == call success */
1454 op_ptr = &Ops[RENAME];
1457 /* set up the arguments */
1458 (void) memmove((char *) &args.from.dir, (char *) &Cur_file_ptr->dir->fh3,
1460 (void) memmove((char *) &args.to.dir, (char *) &Cur_file_ptr->dir->fh3,
1463 target_fileinfo_ptr = randfh(RENAME, 0, 0, Nonexistent,
1466 args.from.name = Cur_file_ptr->file_name;
1467 (void) sprintf(target_fileinfo_ptr->file_name, Filespec,
1468 target_fileinfo_ptr->unique_num);
1469 args.to.name = target_fileinfo_ptr->file_name;
1471 /* make the call now */
1472 sfs_gettime(&start);
1473 rpc_stat = clnt_call(NFS_client, NFSPROC3_RENAME,
1474 xdr_RENAME3args, (char *) &args,
1475 xdr_RENAME3res, (char *) &reply,
1476 (Current_test_phase < Warmup_phase)
1478 : Nfs_timers[op_ptr->call_class]);
1482 if (rpc_stat == RPC_SUCCESS) {
1483 if (reply.status == NFS3_OK) {
1484 target_fileinfo_ptr->state = Exists;
1485 (void) memmove((char *) &target_fileinfo_ptr->fh3,
1486 (char *) &Cur_file_ptr->fh3,
1488 target_fileinfo_ptr->attributes3 = Cur_file_ptr->attributes3;
1489 target_fileinfo_ptr->size = fh_size(Cur_file_ptr);
1490 Cur_file_ptr->state = Nonexistent;
1492 if (DEBUG_CHILD_ERROR) {
1493 (void) fprintf(stderr,
1494 "%s: rename call NFS error %s on file %d\n",
1495 sfs_Myname, nfs3_strerror(reply.status),
1496 Cur_file_ptr->unique_num);
1499 sfs_elapsedtime(op_ptr, &start, &stop);
1500 op_ptr->results.good_calls++;
1501 Ops[TOTAL].results.good_calls++;
1504 if (DEBUG_CHILD_ERROR) {
1505 (void) fprintf(stderr, "%s: rename call RPC error %d on file %d\n",
1506 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1508 op_ptr->results.bad_calls++;
1509 Ops[TOTAL].results.bad_calls++;
1519 sfs_op_type *op_ptr; /* per operation info */
1520 sfs_fh_type *target_fileinfo_ptr; /* target */
1522 LINK3res reply; /* the reply */
1523 enum clnt_stat rpc_stat; /* result from RPC call */
1524 struct ladtime start;
1525 struct ladtime stop;
1526 int ret; /* ret val == call success */
1528 op_ptr = &Ops[LINK];
1531 /* set up the arguments */
1532 target_fileinfo_ptr = randfh(LINK, 0, 0, Exists, Sfs_non_io_file);
1533 (void) memmove((char *) &args.file, (char *) &target_fileinfo_ptr->fh3,
1535 (void) memmove((char *) &args.link.dir, (char *) &Cur_file_ptr->dir->fh3,
1537 args.link.name = Cur_filename;
1539 /* make the call now */
1540 sfs_gettime(&start);
1541 rpc_stat = clnt_call(NFS_client, NFSPROC3_LINK,
1542 xdr_LINK3args, (char *) &args,
1543 xdr_LINK3res, (char *) &reply,
1544 (Current_test_phase < Warmup_phase)
1546 : Nfs_timers[op_ptr->call_class]);
1550 if (rpc_stat == RPC_SUCCESS) {
1551 if (reply.status == NFS3_OK) {
1552 Cur_file_ptr->state = Exists;
1553 (void) memmove((char *) &Cur_file_ptr->fh3,
1554 (char *) &target_fileinfo_ptr->fh3,
1556 (void) strcpy(Cur_file_ptr->file_name, Cur_filename);
1557 target_fileinfo_ptr->attributes3.nlink++;
1558 Cur_file_ptr->attributes3 = target_fileinfo_ptr->attributes3;
1559 Cur_file_ptr->size = fh_size(Cur_file_ptr);
1561 if (DEBUG_CHILD_ERROR) {
1562 (void) fprintf(stderr,
1563 "%s: link call NFS error %s on file %d\n",
1564 sfs_Myname, nfs3_strerror(reply.status),
1565 Cur_file_ptr->unique_num);
1568 sfs_elapsedtime(op_ptr, &start, &stop);
1569 op_ptr->results.good_calls++;
1570 Ops[TOTAL].results.good_calls++;
1573 if (DEBUG_CHILD_ERROR) {
1574 (void) fprintf(stderr, "%s: link call RPC error %d on file %d\n",
1575 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1577 op_ptr->results.bad_calls++;
1578 Ops[TOTAL].results.bad_calls++;
1588 sfs_op_type *op_ptr; /* per operation info */
1590 READDIR3res reply; /* the reply */
1591 enum clnt_stat rpc_stat; /* result from RPC call */
1593 struct ladtime start;
1594 struct ladtime stop;
1595 int ret; /* ret val == call success */
1597 /* array of entries */
1598 entry3 entry_stream[SFS_MAXDIRENTS];
1599 entry3 *entries; /* ptr to the dir entry */
1601 op_ptr = &Ops[READDIR];
1604 /* set up the arguments */
1605 (void) memmove((char *) &args.dir, (char *) &Cur_file_ptr->dir->fh3,
1607 args.cookie._p._l = args.cookie._p._u = (uint32_t) 0;
1608 (void) memset((char *) args.cookieverf, '\0', NFS3_COOKIEVERFSIZE);
1609 args.count = DEFAULT_MAX_BUFSIZE;
1611 /* Have lower layers fill in the data directly. */
1612 (void) memset((char *) &reply, '\0', sizeof (reply));
1613 (void) memset((char *) entry_stream, '\0',
1614 sizeof (entry3) * SFS_MAXDIRENTS);
1615 reply.resok.count = SFS_MAXDIRENTS;
1616 reply.resok.reply.entries = entry_stream;
1618 /* make the call now */
1619 sfs_gettime(&start);
1620 rpc_stat = clnt_call(NFS_client, NFSPROC3_READDIR,
1621 xdr_READDIR3args, (char *) &args,
1622 xdr_READDIR3res, (char *) &reply,
1623 (Current_test_phase < Warmup_phase)
1625 : Nfs_timers[op_ptr->call_class]);
1629 if (rpc_stat == RPC_SUCCESS) {
1630 if (reply.status == NFS3_OK) {
1632 if (DEBUG_CHILD_RPC) {
1633 hit_eof = reply.resok.reply.eof;
1634 entries = reply.resok.reply.entries;
1635 for (i = 0; i < reply.resok.count; i++) {
1636 (void) fprintf(stderr, "%s:READDIR (eof=%d) entry %s\n",
1637 sfs_Myname, hit_eof, entries[i].name);
1639 (void) fflush(stderr);
1642 if (DEBUG_CHILD_ERROR) {
1643 (void) fprintf(stderr,
1644 "%s: readdir call NFS error %s on file %d\n",
1645 sfs_Myname, nfs3_strerror(reply.status),
1646 Cur_file_ptr->unique_num);
1649 sfs_elapsedtime(op_ptr, &start, &stop);
1650 op_ptr->results.good_calls++;
1651 Ops[TOTAL].results.good_calls++;
1654 if (DEBUG_CHILD_ERROR) {
1655 (void) fprintf(stderr,
1656 "%s: readdir call RPC error %d on file %d\n",
1657 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1659 op_ptr->results.bad_calls++;
1660 Ops[TOTAL].results.bad_calls++;
1668 op_readdirplus(void)
1670 sfs_op_type *op_ptr; /* per operation info */
1671 READDIRPLUS3args args;
1672 READDIRPLUS3res reply; /* the reply */
1673 enum clnt_stat rpc_stat; /* result from RPC call */
1675 struct ladtime start;
1676 struct ladtime stop;
1677 int ret; /* ret val == call success */
1679 /* array of entries */
1680 entryplus3 entry_stream[SFS_MAXDIRENTS];
1681 entryplus3 *entries;
1683 op_ptr = &Ops[READDIRPLUS];
1686 /* set up the arguments */
1687 (void) memmove((char *) &args.dir, (char *) &Cur_file_ptr->dir->fh3,
1689 args.cookie._p._l = args.cookie._p._u = (uint32_t) 0;
1690 (void) memset((char *) args.cookieverf, '\0', NFS3_COOKIEVERFSIZE);
1691 (void) memset((char *) entry_stream, '\0',
1692 sizeof (entryplus3) * SFS_MAXDIRENTS);
1693 args.dircount = DEFAULT_MAX_BUFSIZE;
1694 args.maxcount = DEFAULT_MAX_BUFSIZE;
1696 /* Have lower layers fill in the data directly. */
1697 reply.resok.count = SFS_MAXDIRENTS;
1698 reply.resok.reply.entries = entry_stream;
1700 /* make the call now */
1701 sfs_gettime(&start);
1702 rpc_stat = clnt_call(NFS_client, NFSPROC3_READDIRPLUS,
1703 xdr_READDIRPLUS3args, (char *) &args,
1704 xdr_READDIRPLUS3res, (char *) &reply,
1705 (Current_test_phase < Warmup_phase)
1707 : Nfs_timers[op_ptr->call_class]);
1711 if (rpc_stat == RPC_SUCCESS) {
1712 if (reply.status == NFS3_OK) {
1714 if (DEBUG_CHILD_RPC) {
1715 hit_eof = reply.resok.reply.eof;
1716 entries = reply.resok.reply.entries;
1717 for (i = 0; i < reply.resok.count; i++) {
1718 (void) fprintf(stderr, "%s:READDIR (eof=%d) entry %s\n",
1719 sfs_Myname, hit_eof, entries[i].name);
1721 (void) fflush(stderr);
1724 if (DEBUG_CHILD_ERROR) {
1725 (void) fprintf(stderr,
1726 "%s: readdir call NFS error %s on file %d\n",
1727 sfs_Myname, nfs3_strerror(reply.status),
1728 Cur_file_ptr->unique_num);
1731 sfs_elapsedtime(op_ptr, &start, &stop);
1732 op_ptr->results.good_calls++;
1733 Ops[TOTAL].results.good_calls++;
1736 if (DEBUG_CHILD_ERROR) {
1737 (void) fprintf(stderr,
1738 "%s: readdir call RPC error %d on file %d\n",
1739 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1741 op_ptr->results.bad_calls++;
1742 Ops[TOTAL].results.bad_calls++;
1746 } /* op_readdirplus */
1752 sfs_op_type *op_ptr; /* per operation info */
1754 FSSTAT3res reply; /* the reply */
1755 enum clnt_stat rpc_stat; /* result from RPC call */
1756 struct ladtime start;
1757 struct ladtime stop;
1758 int ret; /* ret val == call success */
1760 op_ptr = &Ops[FSSTAT];
1763 /* set up the arguments */
1764 (void) memmove((char *) &args.fsroot, (char *) &Cur_file_ptr->dir->fh3,
1768 sfs_gettime(&start);
1769 rpc_stat = clnt_call(NFS_client, NFSPROC3_FSSTAT,
1770 xdr_FSSTAT3args, (char *) &args,
1771 xdr_FSSTAT3args, (char *) &reply,
1772 (Current_test_phase < Warmup_phase)
1774 : Nfs_timers[op_ptr->call_class]);
1778 if (rpc_stat == RPC_SUCCESS) {
1779 sfs_elapsedtime(op_ptr, &start, &stop);
1780 op_ptr->results.good_calls++;
1781 Ops[TOTAL].results.good_calls++;
1784 if (DEBUG_CHILD_ERROR) {
1785 (void) fprintf(stderr, "%s: fsstat call RPC error %d\n",
1786 sfs_Myname, rpc_stat);
1788 op_ptr->results.bad_calls++;
1789 Ops[TOTAL].results.bad_calls++;
1799 sfs_op_type *op_ptr; /* per operation info */
1801 FSINFO3res reply; /* the reply */
1802 enum clnt_stat rpc_stat; /* result from RPC call */
1803 struct ladtime start;
1804 struct ladtime stop;
1805 int ret; /* ret val == call success */
1807 op_ptr = &Ops[FSINFO];
1810 /* set up the arguments */
1811 (void) memmove((char *) &args.fsroot, (char *) &Cur_file_ptr->dir->fh3,
1815 sfs_gettime(&start);
1816 rpc_stat = clnt_call(NFS_client, NFSPROC3_FSINFO,
1817 xdr_FSINFO3args, (char *) &args,
1818 xdr_FSINFO3args, (char *) &reply,
1819 (Current_test_phase < Warmup_phase)
1821 : Nfs_timers[op_ptr->call_class]);
1825 if (rpc_stat == RPC_SUCCESS) {
1826 sfs_elapsedtime(op_ptr, &start, &stop);
1827 op_ptr->results.good_calls++;
1828 Ops[TOTAL].results.good_calls++;
1831 if (DEBUG_CHILD_ERROR) {
1832 (void) fprintf(stderr, "%s: fsinfo call RPC error %d\n",
1833 sfs_Myname, rpc_stat);
1835 op_ptr->results.bad_calls++;
1836 Ops[TOTAL].results.bad_calls++;
1846 sfs_op_type *op_ptr; /* per operation info */
1848 PATHCONF3res reply; /* the reply */
1849 enum clnt_stat rpc_stat; /* result from RPC call */
1850 struct ladtime start;
1851 struct ladtime stop;
1852 int ret; /* ret val == call success */
1854 op_ptr = &Ops[PATHCONF];
1857 /* set up the arguments */
1858 (void) memmove((char *) &args.object, (char *) &Cur_file_ptr->fh3,
1862 sfs_gettime(&start);
1863 rpc_stat = clnt_call(NFS_client, NFSPROC3_PATHCONF,
1864 xdr_PATHCONF3args, (char *) &args,
1865 xdr_PATHCONF3args, (char *) &reply,
1866 (Current_test_phase < Warmup_phase)
1868 : Nfs_timers[op_ptr->call_class]);
1872 if (rpc_stat == RPC_SUCCESS) {
1873 sfs_elapsedtime(op_ptr, &start, &stop);
1874 op_ptr->results.good_calls++;
1875 Ops[TOTAL].results.good_calls++;
1878 if (DEBUG_CHILD_ERROR) {
1879 (void) fprintf(stderr,
1880 "%s: pathconf call RPC error %d on file %d\n",
1881 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1883 op_ptr->results.bad_calls++;
1884 Ops[TOTAL].results.bad_calls++;
1894 sfs_op_type *op_ptr; /* per operation info */
1895 int32_t size; /* size of data write */
1897 COMMIT3res reply; /* the reply */
1898 enum clnt_stat rpc_stat; /* result from RPC call */
1899 struct ladtime start;
1900 struct ladtime stop;
1901 int ret; /* ret val == call success */
1903 op_ptr = &Ops[COMMIT];
1906 /* set up the arguments */
1907 (void) memmove((char *) &args.file, (char *) &Cur_file_ptr->fh3,
1909 args.offset._p._u = args.offset._p._l = (uint32_t) 0;
1910 args.count = Cur_file_ptr->attributes3.size._p._l;
1913 sfs_gettime(&start);
1914 rpc_stat = clnt_call(NFS_client, NFSPROC3_COMMIT,
1915 xdr_COMMIT3args, (char *) &args,
1916 xdr_COMMIT3res, (char *) &reply,
1917 (Current_test_phase < Warmup_phase)
1919 : Nfs_timers[op_ptr->call_class]);
1923 if (rpc_stat == RPC_SUCCESS) {
1924 if (reply.status == NFS3_OK) {
1925 Cur_file_ptr->state = Exists;
1926 (void) memmove((char *) &Cur_file_ptr->attributes3,
1927 (char *) &reply.resok.file_wcc.after.attr,
1928 sizeof(Cur_file_ptr->attributes3));
1929 Cur_file_ptr->size = fh_size(Cur_file_ptr);
1931 if (DEBUG_CHILD_RPC) {
1932 (void) fprintf(stderr, "%s: WRITE %s %ld bytes\n",
1933 sfs_Myname, Cur_filename, size);
1934 (void) fflush(stderr);
1937 if (DEBUG_CHILD_ERROR) {
1938 (void) fprintf(stderr,
1939 "%s: write call NFS error %s on file %d\n",
1940 sfs_Myname, nfs3_strerror(reply.status),
1941 Cur_file_ptr->unique_num);
1944 sfs_elapsedtime(op_ptr, &start, &stop);
1945 op_ptr->results.good_calls++;
1946 Ops[TOTAL].results.good_calls++;
1949 if (DEBUG_CHILD_ERROR) {
1950 (void) fprintf(stderr, "%s: write call RPC error %d on file %d\n",
1951 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1953 op_ptr->results.bad_calls++;
1954 Ops[TOTAL].results.bad_calls++;
1962 #define LAD_RETRIABLE(stat) (((stat) == RPC_TIMEDOUT) || ((stat) == RPC_CANTDECODERES))
1965 * Reliably lookup a file in the current directory
1968 * 1 File doesn't exist
1972 lad_lookup(sfs_fh_type *file_ptr, char *name)
1975 LOOKUP3res reply; /* the reply */
1976 enum clnt_stat rpc_stat; /* result from RPC call */
1978 if (DEBUG_CHILD_RPC) {
1979 (void) fprintf(stderr, "%s:lad_lookup: %lx[%lx] %s\n", sfs_Myname,
1980 (int32_t) file_ptr, (int32_t) file_ptr->dir, name);
1981 (void) fflush(stderr);
1986 /* set up the arguments */
1987 (void) memmove((char *) &args.what.dir, (char *) &file_ptr->dir->fh3,
1989 args.what.name = name;
1990 (void) memset((char *) &reply.resok.object, '\0', sizeof (nfs_fh3));
1993 rpc_stat = clnt_call(NFS_client, NFSPROC3_LOOKUP,
1994 xdr_LOOKUP3args, (char *) &args,
1995 xdr_LOOKUP3res, (char *) &reply,
1998 if (rpc_stat == RPC_SUCCESS)
2000 if (rpc_stat != RPC_TIMEDOUT) {
2001 (void) fprintf(stderr, "lad_lookup(%s) RPC call failed : %s\n",
2002 name, clnt_sperrno(rpc_stat));
2004 if (!LAD_RETRIABLE(rpc_stat)) {
2009 if (reply.status == NFS3ERR_NOENT) {
2013 if (reply.status != NFS3_OK) {
2014 (void) fprintf(stderr, "lad_lookup(%s) NFS call failed : %s\n",
2015 name, nfs3_strerror(reply.status));
2019 file_ptr->state = Exists;
2020 (void) memmove((char *) &file_ptr->fh3,
2021 (char *) &reply.resok.object,
2023 (void) strcpy(file_ptr->file_name, name);
2024 (void) memmove((char *) &file_ptr->attributes3,
2025 (char *) &reply.resok.obj_attributes.attr,
2026 sizeof (file_ptr->attributes3));
2027 file_ptr->size = fh_size(file_ptr);
2032 * Reliably remove a file in the current directory
2035 lad_remove(sfs_fh_type *file_ptr, char *name)
2038 REMOVE3res reply; /* the reply */
2039 enum clnt_stat rpc_stat; /* result from RPC call */
2043 * This function presumes that the file name does exist
2045 if (file_ptr->attributes3.type == NF3DIR)
2046 return (lad_rmdir(file_ptr, name));
2048 if (DEBUG_CHILD_RPC) {
2049 (void) fprintf(stderr, "%s:lad_remove: %lx[%lx] %s\n", sfs_Myname,
2050 (int32_t) file_ptr, (int32_t) file_ptr->dir, name);
2051 (void) fflush(stderr);
2056 /* set up the arguments */
2057 args.object.name = name;
2058 (void) memmove((char *) &args.object.dir, (char *) &file_ptr->dir->fh3,
2061 /* make the call now */
2062 rpc_stat = clnt_call(NFS_client, NFSPROC3_REMOVE,
2063 xdr_REMOVE3args, (char *) &args,
2064 xdr_REMOVE3res, (char *) &reply,
2067 if (rpc_stat == RPC_SUCCESS)
2069 if (rpc_stat != RPC_TIMEDOUT) {
2070 (void) fprintf(stderr, "lad_remove(%s) RPC call failed : %s\n",
2071 name, clnt_sperrno(rpc_stat));
2073 if (!LAD_RETRIABLE(rpc_stat)) {
2079 if (reply.status != NFS3_OK) {
2080 if (reply.status != NFS3ERR_NOENT || !retried) {
2081 (void) fprintf(stderr, "lad_remove(%s) NFS call failed : %s\n",
2082 name, nfs3_strerror(reply.status));
2087 file_ptr->state = Nonexistent;
2093 * Reliably remove a directory in the current directory
2096 lad_rmdir(sfs_fh_type *file_ptr, char *name)
2099 RMDIR3res reply; /* the reply */
2100 enum clnt_stat rpc_stat; /* result from RPC call */
2104 * This function presumes that the file name does exist and is empty
2106 if (file_ptr->attributes3.type != NF3DIR)
2107 return (lad_remove(file_ptr, name));
2109 if (DEBUG_CHILD_RPC) {
2110 (void) fprintf(stderr, "%s:lad_rmdir: %lx[%lx] %s\n", sfs_Myname,
2111 (int32_t) file_ptr, (int32_t) file_ptr->dir, name);
2112 (void) fflush(stderr);
2117 /* set up the arguments */
2118 args.object.name = name;
2119 (void) memmove((char *) &args.object.dir, (char *) &file_ptr->dir->fh3,
2122 /* make the call now */
2123 rpc_stat = clnt_call(NFS_client, NFSPROC3_RMDIR,
2124 xdr_RMDIR3args, (char *) &args,
2125 xdr_RMDIR3res, (char *) &reply,
2128 if (rpc_stat == RPC_SUCCESS)
2130 if (rpc_stat != RPC_TIMEDOUT) {
2131 (void) fprintf(stderr, "lad_rmdir(%s) RPC call failed : %s\n",
2132 name, clnt_sperrno(rpc_stat));
2134 if (!LAD_RETRIABLE(rpc_stat)) {
2140 if (reply.status != NFS3_OK) {
2141 if (reply.status != NFS3ERR_NOENT || !retried) {
2142 (void) fprintf(stderr, "lad_rmdir(%s) NFS call failed : %s\n",
2143 name, nfs3_strerror(reply.status));
2148 file_ptr->state = Nonexistent;
2154 * Reliably create a symlink in the current directory
2157 lad_symlink(sfs_fh_type *file_ptr, char *target, char *name)
2160 SYMLINK3res reply; /* the reply */
2161 char sym_data[NFS_MAXPATHLEN]; /* symlink data */
2162 enum clnt_stat rpc_stat; /* result from RPC call */
2166 * This function presumes that the file name does not already exist
2168 if (DEBUG_CHILD_RPC) {
2169 (void) fprintf(stderr, "%s:lad_symlink: %lx[%lx] %s -> %s\n", sfs_Myname,
2170 (int32_t) file_ptr, (int32_t) file_ptr->dir, name, target);
2171 (void) fflush(stderr);
2176 /* set up the arguments */
2177 (void) memmove((char *) &args.where.dir, (char *) &file_ptr->dir->fh3,
2179 args.where.name = name;
2181 (void) strcpy(sym_data, "./");
2182 (void) strcat(sym_data, target);
2183 args.symlink.symlink_attributes.size.set_it = TRUE;
2184 args.symlink.symlink_attributes.size.size._p._u = (uint32_t) 0;
2185 args.symlink.symlink_attributes.size.size._p._l = strlen(sym_data);
2186 args.symlink.symlink_data = sym_data;
2188 args.symlink.symlink_attributes.mode.set_it = TRUE;
2189 args.symlink.symlink_attributes.mode.mode = (NFSMODE_LNK | 0777);
2190 args.symlink.symlink_attributes.uid.set_it = TRUE;
2191 args.symlink.symlink_attributes.uid.uid = Cur_uid;
2192 args.symlink.symlink_attributes.gid.set_it = TRUE;
2193 args.symlink.symlink_attributes.gid.gid = Cur_gid;
2194 args.symlink.symlink_attributes.atime.set_it = TRUE;
2195 args.symlink.symlink_attributes.atime.atime.seconds = Cur_time.esec;
2196 args.symlink.symlink_attributes.atime.atime.nseconds =
2197 Cur_time.usec * 1000;
2198 args.symlink.symlink_attributes.mtime.set_it = TRUE;
2199 args.symlink.symlink_attributes.mtime.mtime.seconds = Cur_time.esec;
2200 args.symlink.symlink_attributes.mtime.mtime.nseconds =
2201 Cur_time.usec * 1000;
2204 /* make the call now */
2205 rpc_stat = clnt_call(NFS_client, NFSPROC3_SYMLINK,
2206 xdr_SYMLINK3args, (char *) &args,
2207 xdr_SYMLINK3res, (char *) &reply,
2209 if (rpc_stat == RPC_SUCCESS)
2211 if (rpc_stat != RPC_TIMEDOUT) {
2212 (void) fprintf(stderr, "lad_symlink(%s) RPC call failed : %s\n",
2213 name, clnt_sperrno(rpc_stat));
2215 if (!LAD_RETRIABLE(rpc_stat)) {
2221 if (reply.status != NFS3_OK) {
2222 if (reply.status != NFS3ERR_EXIST || !retried) {
2223 (void) fprintf(stderr, "lad_symlink(%s, %s) NFS call failed : %s\n",
2224 target, name, nfs3_strerror(reply.status));
2230 * SYMLINK may not return a fh. If we try to
2231 * access this symlink (eg, remove(), readlink())
2232 * before we do a lookup, we won't have a fh to use.
2233 * So, we do a lookup call here.
2234 * If it fails, we fill in what we can.
2236 return (lad_lookup(file_ptr, name));
2240 * Reliably create a directory in the current directory
2243 lad_mkdir(sfs_fh_type *file_ptr, char *name)
2246 MKDIR3res reply; /* the reply */
2247 enum clnt_stat rpc_stat; /* result from RPC call */
2251 * This function presumes that the file name does not already exist
2253 if (DEBUG_CHILD_RPC) {
2254 (void) fprintf(stderr, "%s:lad_mkdir: %lx[%lx] %s\n", sfs_Myname,
2255 (int32_t) file_ptr, (int32_t) file_ptr->dir, name);
2256 (void) fflush(stderr);
2261 /* set up the arguments */
2262 (void) memmove((char *) &args.where.dir, (char *) &file_ptr->dir->fh3,
2264 args.where.name = name;
2265 args.attributes.mode.set_it = TRUE;
2266 args.attributes.mode.mode = (NFSMODE_DIR | 0777);
2267 args.attributes.uid.set_it = TRUE;
2268 args.attributes.uid.uid = Cur_uid;
2269 args.attributes.gid.set_it = TRUE;
2270 args.attributes.gid.gid = Cur_gid;
2271 args.attributes.size.set_it = TRUE;
2272 args.attributes.size.size._p._u = 0;
2273 args.attributes.size.size._p._l = 512;
2274 args.attributes.atime.set_it = TRUE;
2275 args.attributes.atime.atime.seconds = Cur_time.esec;
2276 args.attributes.atime.atime.nseconds = Cur_time.usec * 1000;
2277 args.attributes.mtime.set_it = TRUE;
2278 args.attributes.mtime.mtime.seconds = Cur_time.esec;
2279 args.attributes.mtime.mtime.nseconds = Cur_time.usec * 1000;
2281 /* make the call now */
2282 rpc_stat = clnt_call(NFS_client, NFSPROC3_MKDIR,
2283 xdr_MKDIR3args, (char *) &args,
2284 xdr_MKDIR3res, (char *) &reply,
2287 if (rpc_stat == RPC_SUCCESS)
2289 if (rpc_stat != RPC_TIMEDOUT) {
2290 (void) fprintf(stderr, "lad_mkdir(%s) RPC call failed : %s\n",
2291 name, clnt_sperrno(rpc_stat));
2293 if (!LAD_RETRIABLE(rpc_stat)) {
2299 if (!retried && reply.status == NFS3ERR_EXIST)
2302 if (reply.status != NFS3_OK) {
2303 if (reply.status != NFS3ERR_EXIST || !retried) {
2304 (void) fprintf(stderr, "lad_mkdir(%s) NFS call failed : %s\n",
2305 name, nfs3_strerror(reply.status));
2309 * If the first mkdir suceeded but the reply as dropped and
2310 * was retransmitted, we still need to lookup the attributes
2312 if (lad_lookup(file_ptr, name))
2315 (void) memmove((char *) &file_ptr->fh3,
2316 (char *) &reply.resok.obj.handle,
2318 (void) strcpy(file_ptr->file_name, name);
2319 (void) memmove((char *) &file_ptr->attributes3,
2320 (char *) &reply.resok.obj_attributes.attr,
2321 sizeof(file_ptr->attributes3));
2322 file_ptr->size = fh_size(file_ptr);
2324 file_ptr->state = Empty_dir;
2330 * Reliably commit a file
2333 lad_commit(sfs_fh_type *file_ptr)
2336 COMMIT3res reply; /* the reply */
2337 enum clnt_stat rpc_stat; /* result from RPC call */
2339 if (DEBUG_CHILD_RPC) {
2340 (void) fprintf(stderr, "%s:lad_commit: %lx[%lx]\n",
2342 (int32_t) file_ptr, (int32_t) file_ptr->dir);
2343 (void) fflush(stderr);
2346 /* set up the arguments */
2347 (void) memmove((char *) &args.file, (char *) &file_ptr->fh3,
2349 args.offset._p._u = args.offset._p._l = (uint32_t) 0;
2350 args.count = file_ptr->attributes3.size._p._l;
2354 rpc_stat = clnt_call(NFS_client, NFSPROC3_COMMIT,
2355 xdr_COMMIT3args, (char *) &args,
2356 xdr_COMMIT3res, (char *) &reply,
2358 if (rpc_stat == RPC_SUCCESS)
2360 if (rpc_stat != RPC_TIMEDOUT) {
2361 (void) fprintf(stderr, "lad_commit() RPC call failed : %s\n",
2362 clnt_sperrno(rpc_stat));
2364 if (!LAD_RETRIABLE(rpc_stat)) {
2373 * Reliably write a file in the current directory
2376 lad_write(sfs_fh_type *file_ptr, int32_t offset, int32_t length)
2378 static char *buf = NULL; /* the data buffer */
2379 int32_t size; /* size of data write */
2382 WRITE3res reply; /* the reply */
2383 enum clnt_stat rpc_stat; /* result from RPC call */
2386 if (DEBUG_CHILD_RPC) {
2387 (void) fprintf(stderr, "%s:lad_write: %lx[%lx] %ld %ld\n",
2389 (int32_t) file_ptr, (int32_t) file_ptr->dir, offset, length);
2390 (void) fflush(stderr);
2394 * This function presumes that the file name does exist
2395 * Initialize write buffer to known value
2398 buf = init_write_buffer();
2402 * If a short file write don't bother with the commit, just write sync.
2404 if (length <= Bytes_per_block)
2407 /* set up the arguments */
2408 (void) memmove((char *) &args.file, (char *) &file_ptr->fh3,
2410 args.offset._p._u = 0;
2411 args.offset._p._l = offset;
2413 args.stable = UNSTABLE;
2415 args.stable = FILE_SYNC;
2417 size = Bytes_per_block;
2418 for (cur_cnt = 0; cur_cnt < length; cur_cnt += size) {
2419 if ((cur_cnt + size) > length)
2420 size = length - cur_cnt;
2426 args.data.data_len = size;
2427 args.data.data_val = buf;
2429 /* make the call now */
2432 rpc_stat = clnt_call(NFS_client, NFSPROC3_WRITE,
2433 xdr_WRITE3args, (char *) &args,
2434 xdr_WRITE3res, (char *) &reply,
2437 if (rpc_stat == RPC_SUCCESS)
2439 if (rpc_stat != RPC_TIMEDOUT) {
2440 (void) fprintf(stderr, "lad_write() RPC call failed : %s\n",
2441 clnt_sperrno(rpc_stat));
2443 if (!LAD_RETRIABLE(rpc_stat)) {
2447 if (reply.status != NFS3_OK) {
2448 (void) fprintf(stderr, "lad_write() NFS call failed : %s\n",
2449 nfs3_strerror(reply.status));
2452 file_ptr->state = Exists;
2453 (void) memmove((char *) &file_ptr->attributes3,
2454 (char *) &reply.resok.file_wcc.after.attr,
2455 sizeof (file_ptr->attributes3));
2456 file_ptr->size = fh_size(file_ptr);
2458 args.offset._p._l += size;
2462 (void) lad_commit(file_ptr);
2467 * Reliably create a file in the current directory
2470 lad_create(sfs_fh_type *file_ptr, char *name)
2473 CREATE3res reply; /* the reply */
2474 enum clnt_stat rpc_stat; /* result from RPC call */
2478 * This function presumes that the file name does not already exist
2480 if (DEBUG_CHILD_RPC) {
2481 (void) fprintf(stderr, "%s:lad_create: %lx[%lx] %s\n", sfs_Myname,
2482 (int32_t) file_ptr, (int32_t) file_ptr->dir, name);
2483 (void) fflush(stderr);
2488 /* set up the arguments */
2489 (void) memmove((char *) &args.where.dir, (char *) &file_ptr->dir->fh3,
2491 args.where.name = name;
2492 args.how.mode = UNCHECKED;
2493 args.how.createhow3_u.obj_attributes.mode.set_it = TRUE;
2494 args.how.createhow3_u.obj_attributes.mode.mode = (NFSMODE_REG | 0666);
2495 args.how.createhow3_u.obj_attributes.uid.set_it = TRUE;
2496 args.how.createhow3_u.obj_attributes.uid.uid = Cur_uid;
2497 args.how.createhow3_u.obj_attributes.gid.set_it = TRUE;
2498 args.how.createhow3_u.obj_attributes.gid.gid = Cur_gid;
2499 args.how.createhow3_u.obj_attributes.atime.set_it = TRUE;
2500 args.how.createhow3_u.obj_attributes.atime.atime.seconds =
2502 args.how.createhow3_u.obj_attributes.atime.atime.nseconds =
2503 Cur_time.usec * 1000;
2504 args.how.createhow3_u.obj_attributes.mtime.set_it = TRUE;
2505 args.how.createhow3_u.obj_attributes.mtime.mtime.seconds =
2507 args.how.createhow3_u.obj_attributes.mtime.mtime.nseconds =
2508 Cur_time.usec * 1000;
2509 args.how.createhow3_u.obj_attributes.size.set_it = TRUE;
2510 args.how.createhow3_u.obj_attributes.size.size._p._u =
2512 args.how.createhow3_u.obj_attributes.size.size._p._l =
2515 /* make the call now */
2516 rpc_stat = clnt_call(NFS_client, NFSPROC3_CREATE,
2517 xdr_CREATE3args, (char *) &args,
2518 xdr_CREATE3res, (char *) &reply,
2521 if (rpc_stat == RPC_SUCCESS)
2523 if (rpc_stat != RPC_TIMEDOUT) {
2524 (void) fprintf(stderr, "lad_create(%s) RPC call failed : %s\n",
2525 name, clnt_sperrno(rpc_stat));
2527 if (!LAD_RETRIABLE(rpc_stat)) {
2533 if (!retried && reply.status == NFS3ERR_EXIST) {
2537 if (reply.status != NFS3_OK) {
2538 if (reply.status != NFS3ERR_EXIST || !retried) {
2539 (void) fprintf(stderr, "lad_create(%s) NFS call failed : %s\n",
2540 name, nfs3_strerror(reply.status));
2544 * If the first create suceeded but the reply as dropped and
2545 * was retransmitted, we still need to lookup the attributes
2547 if (lad_lookup(file_ptr, name))
2550 (void) memmove((char *) &file_ptr->fh3,
2551 (char *) &reply.resok.obj.handle,
2553 (void) strcpy(file_ptr->file_name, name);
2554 (void) memmove((char *) &file_ptr->attributes3,
2555 (char *) &reply.resok.obj_attributes.attr,
2556 sizeof(file_ptr->attributes3));
2557 file_ptr->size = fh_size(file_ptr);
2560 file_ptr->state = Exists;
2562 * Directories are created as Empty_dir, when a file is created it
2563 * becomes an Exists.
2565 file_ptr->dir->state = Exists;
2571 * Reliably set the size of a file in the current directory
2574 lad_truncate(sfs_fh_type *file_ptr, int32_t size)
2577 SETATTR3res reply; /* the reply */
2578 enum clnt_stat rpc_stat; /* result from RPC call */
2581 * This function presumes that the file name already exists
2583 if (DEBUG_CHILD_RPC) {
2584 (void) fprintf(stderr, "%s:lad_truncate: %lx[%lx] %ld\n", sfs_Myname,
2585 (int32_t) file_ptr, (int32_t) file_ptr->dir, size);
2586 (void) fflush(stderr);
2592 * set up the arguments
2593 * Set the mode and times as well
2595 (void) memmove((char *) &args.object, (char *) &file_ptr->fh3,
2597 args.new_attributes.mode.set_it = TRUE;
2598 args.new_attributes.mode.mode = (uint32_t) 0666;
2599 args.new_attributes.uid.set_it = FALSE;
2600 args.new_attributes.uid.uid = (uint32_t) -1;
2601 args.new_attributes.gid.set_it = FALSE;
2602 args.new_attributes.gid.gid = (uint32_t) -1;
2603 args.new_attributes.size.set_it = TRUE;
2604 args.new_attributes.size.size._p._u = 0;
2605 args.new_attributes.size.size._p._l = size;
2606 args.new_attributes.atime.set_it = TRUE;
2607 args.new_attributes.atime.atime.seconds = Cur_time.esec;
2608 args.new_attributes.atime.atime.nseconds = Cur_time.usec * 1000;
2609 args.new_attributes.mtime.set_it = TRUE;
2610 args.new_attributes.mtime.mtime.seconds = Cur_time.esec;
2611 args.new_attributes.mtime.mtime.nseconds = Cur_time.usec * 1000;
2612 args.guard.check = FALSE;
2615 rpc_stat = clnt_call(NFS_client, NFSPROC3_SETATTR,
2616 xdr_SETATTR3args, (char *) &args,
2617 xdr_SETATTR3res, (char *) &reply,
2620 if (rpc_stat == RPC_SUCCESS)
2622 if (rpc_stat != RPC_TIMEDOUT) {
2623 (void)fprintf(stderr,
2624 "lad_truncate(%ld) RPC call failed : %s\n",
2625 size, clnt_sperrno(rpc_stat));
2627 if (!LAD_RETRIABLE(rpc_stat)) {
2632 if (reply.status != NFS3_OK) {
2633 (void) fprintf(stderr, "lad_truncate(%ld) NFS call failed : %s\n",
2634 size, nfs3_strerror(reply.status));
2637 (void) memmove(&file_ptr->attributes3,
2638 &reply.resok.obj_wcc.after.attr,
2639 sizeof (file_ptr->attributes3));
2640 file_ptr->size = fh_size(file_ptr);
2646 nfs3_strerror(int status)
2648 static char str[40];
2651 (void) strcpy(str, "no error");
2654 (void) strcpy(str, "Not owner");
2657 (void) strcpy(str, "No such file or directory");
2660 (void) strcpy(str, "I/O error");
2663 (void) strcpy(str, "No such device or address");
2666 (void) strcpy(str, "Permission denied");
2669 (void) strcpy(str, "File exists");
2672 (void) strcpy(str, "Cross-device link");
2675 (void) strcpy(str, "No such device");
2677 case NFS3ERR_NOTDIR:
2678 (void) strcpy(str, "Not a directory");
2681 (void) strcpy(str, "Is a directory");
2684 (void) strcpy(str, "Invalid argument");
2687 (void) strcpy(str, "File too large");
2690 (void) strcpy(str, "No space left on device");
2693 (void) strcpy(str, "Read-only file system");
2696 (void) strcpy(str, "Too many links");
2698 case NFS3ERR_NAMETOOLONG:
2699 (void) strcpy(str, "File name too long");
2701 case NFS3ERR_NOTEMPTY:
2702 (void) strcpy(str, "Directory not empty");
2705 (void) strcpy(str, "Disc quota exceeded");
2708 (void) strcpy(str, "Stale NFS file handle");
2710 case NFS3ERR_REMOTE:
2711 (void) strcpy(str, "Object is remote");
2713 case NFS3ERR_BADHANDLE:
2714 (void) strcpy(str, "Bad file handle");
2716 case NFS3ERR_NOT_SYNC:
2717 (void) strcpy(str, "Not sync write");
2719 case NFS3ERR_BAD_COOKIE:
2720 (void) strcpy(str, "Bad cookie");
2722 case NFS3ERR_NOTSUPP:
2723 (void) strcpy(str, "Operation not supported");
2725 case NFS3ERR_TOOSMALL:
2726 (void) strcpy(str, "Value too small");
2728 case NFS3ERR_SERVERFAULT:
2729 (void) strcpy(str, "Server fault");
2731 case NFS3ERR_BADTYPE:
2732 (void) strcpy(str, "Bad type");
2734 case NFS3ERR_JUKEBOX:
2735 (void) strcpy(str, "Jukebox");
2737 case NFS3ERR_RFS_TIMEOUT:
2738 (void) strcpy(str, "RFS timeout");
2740 (void) sprintf(str, "Unknown status %d", status);