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 Ops[TOTAL].results.bad_calls++;
194 sfs_op_type *op_ptr; /* per operation info */
195 enum clnt_stat rpc_stat; /* result from RPC call */
196 struct ladtime start;
198 int ret; /* ret val == call success */
200 op_ptr = &Ops[NULLCALL];
205 rpc_stat = clnt_call(NFS_client, NFSPROC3_NULL,
206 xdr_void, (char *)0, xdr_void, (char *)0,
207 (Current_test_phase < Warmup_phase)
209 : Nfs_timers[op_ptr->call_class]);
213 if (rpc_stat == RPC_SUCCESS) {
214 sfs_elapsedtime(op_ptr, &start, &stop);
215 op_ptr->results.good_calls++;
216 Ops[TOTAL].results.good_calls++;
219 if (DEBUG_CHILD_ERROR) {
220 (void) fprintf(stderr, "%s: null_op call RPC error %d\n",
221 sfs_Myname, rpc_stat);
223 op_ptr->results.bad_calls++;
224 Ops[TOTAL].results.bad_calls++;
234 sfs_op_type *op_ptr; /* per operation info */
235 GETATTR3args args; /* fh to do op on */
236 GETATTR3res reply; /* the reply */
237 enum clnt_stat rpc_stat; /* result from RPC call */
238 struct ladtime start;
240 int ret; /* ret val == call success */
242 op_ptr = &Ops[GETATTR];
245 /* set up the arguments */
246 (void) memmove((char *) &args.object, (char *) &Cur_file_ptr->fh3,
251 rpc_stat = clnt_call(NFS_client, NFSPROC3_GETATTR,
252 xdr_GETATTR3args, (char *) &args,
253 xdr_GETATTR3res, (char *) &reply,
254 (Current_test_phase < Warmup_phase)
256 : Nfs_timers[op_ptr->call_class]);
260 if (rpc_stat == RPC_SUCCESS) {
261 if (reply.status == NFS3_OK) {
262 (void) memmove((char *) &Cur_file_ptr->attributes3,
263 (char *) &reply.resok.obj_attributes,
264 sizeof (Cur_file_ptr->attributes3));
265 Cur_file_ptr->size = fh_size(Cur_file_ptr);
267 if (DEBUG_CHILD_ERROR) {
268 (void) fprintf(stderr,
269 "%s: getattr call NFS error %s on file %d\n",
270 sfs_Myname, nfs3_strerror(reply.status),
271 Cur_file_ptr->unique_num);
274 sfs_elapsedtime(op_ptr, &start, &stop);
275 op_ptr->results.good_calls++;
276 Ops[TOTAL].results.good_calls++;
279 if (DEBUG_CHILD_ERROR) {
280 (void) fprintf(stderr,
281 "%s: getattr call RPC error %d on file %d\n",
282 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
284 op_ptr->results.bad_calls++;
285 Ops[TOTAL].results.bad_calls++;
293 * perform an RPC setattr operation. If 'truncate_size' is non-negative,
294 * truncate the file to that size.
300 sfs_op_type *op_ptr; /* per operation info */
302 SETATTR3res reply; /* the reply */
303 enum clnt_stat rpc_stat; /* result from RPC call */
304 struct ladtime start;
306 int ret; /* ret val == call success */
308 op_ptr = &Ops[SETATTR];
311 /* set up the arguments */
312 (void) memmove((char *) &args.object, (char *) &Cur_file_ptr->fh3,
314 args.new_attributes.mode.set_it = TRUE;
315 args.new_attributes.mode.mode = (uint32_t) 0666;
316 args.new_attributes.uid.set_it = FALSE;
317 args.new_attributes.uid.uid = (uint32_t) -1;
318 args.new_attributes.gid.set_it = FALSE;
319 args.new_attributes.gid.gid = (uint32_t) -1;
320 args.new_attributes.size.set_it = FALSE;
321 args.new_attributes.size.size._p._u = (uint32_t) ~0;
322 args.new_attributes.size.size._p._l = (uint32_t) -1;
323 args.new_attributes.atime.set_it = TRUE;
324 args.new_attributes.atime.atime.seconds = Cur_time.esec;
325 args.new_attributes.atime.atime.nseconds = Cur_time.usec * 1000;
326 args.new_attributes.mtime.set_it = TRUE;
327 args.new_attributes.mtime.mtime.seconds = Cur_time.esec;
328 args.new_attributes.mtime.mtime.nseconds = Cur_time.usec * 1000;
329 args.guard.check = FALSE;
331 /* handle file truncations */
332 if (truncate_size >= 0) {
333 args.new_attributes.size.set_it = TRUE;
334 args.new_attributes.size.size._p._u = (uint32_t) 0;
335 if (truncate_size > Cur_file_ptr->attributes3.size._p._l)
336 args.new_attributes.size.size._p._l = (uint32_t) 0;
338 args.new_attributes.size.size._p._l =
339 (uint32_t) Cur_file_ptr->attributes3.size._p._l -
345 rpc_stat = clnt_call(NFS_client, NFSPROC3_SETATTR,
346 xdr_SETATTR3args, (char *) &args,
347 xdr_SETATTR3res, (char *) &reply,
348 (Current_test_phase < Warmup_phase)
350 : Nfs_timers[op_ptr->call_class]);
355 if (rpc_stat == RPC_SUCCESS) {
356 if (reply.status == NFS3_OK) {
357 (void) memmove((char *) &Cur_file_ptr->attributes3,
358 (char *) &reply.resok.obj_wcc.after.attr,
359 sizeof (Cur_file_ptr->attributes3));
360 Cur_file_ptr->size = fh_size(Cur_file_ptr);
362 if (DEBUG_CHILD_ERROR) {
363 (void) fprintf(stderr,
364 "%s: setattr call NFS error %s on file %d\n",
365 sfs_Myname, nfs3_strerror(reply.status),
366 Cur_file_ptr->unique_num);
369 sfs_elapsedtime(op_ptr, &start, &stop);
370 op_ptr->results.good_calls++;
371 Ops[TOTAL].results.good_calls++;
374 if (DEBUG_CHILD_ERROR) {
375 (void) fprintf(stderr,
376 "%s: setattr call RPC error %d on file %d\n",
377 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
379 op_ptr->results.bad_calls++;
380 Ops[TOTAL].results.bad_calls++;
390 sfs_op_type *op_ptr; /* per operation info */
392 LOOKUP3res reply; /* the reply */
393 enum clnt_stat rpc_stat; /* result from RPC call */
394 struct ladtime start;
396 int ret; /* ret val == call success */
398 op_ptr = &Ops[LOOKUP];
401 /* set up the arguments */
402 (void) memmove((char *) &args.what.dir, (char *) &Cur_file_ptr->dir->fh3,
404 args.what.name = Cur_filename;
405 (void) memset((char *) &reply.resok.object, '\0', sizeof (nfs_fh3));
409 rpc_stat = clnt_call(NFS_client, NFSPROC3_LOOKUP,
410 xdr_LOOKUP3args, (char *) &args,
411 xdr_LOOKUP3res, (char *) &reply,
412 (Current_test_phase < Warmup_phase)
414 : Nfs_timers[op_ptr->call_class]);
418 if (rpc_stat == RPC_SUCCESS) {
419 if (reply.status == NFS3_OK) {
420 Cur_file_ptr->state = Exists;
421 (void) memmove((char *) &Cur_file_ptr->fh3,
422 (char *) &reply.resok.object,
424 (void) strcpy(Cur_file_ptr->file_name, Cur_filename);
425 (void) memmove((char *) &Cur_file_ptr->attributes3,
426 (char *) &reply.resok.obj_attributes.attr,
427 sizeof (Cur_file_ptr->attributes3));
428 Cur_file_ptr->size = fh_size(Cur_file_ptr);
430 /* We do lookup Nonexistent and this is not an error */
431 if (reply.status != NFS3ERR_NOENT ||
432 Cur_file_ptr->state != Nonexistent) {
433 if (DEBUG_CHILD_ERROR) {
434 (void) fprintf(stderr,
435 "%s: lookup call NFS error %s on file %d\n",
436 sfs_Myname, nfs3_strerror(reply.status),
437 Cur_file_ptr->unique_num);
441 sfs_elapsedtime(op_ptr, &start, &stop);
442 op_ptr->results.good_calls++;
443 Ops[TOTAL].results.good_calls++;
446 if (DEBUG_CHILD_ERROR) {
447 (void) fprintf(stderr, "%s: lookup call RPC error %d on file %d\n",
448 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
450 op_ptr->results.bad_calls++;
451 Ops[TOTAL].results.bad_calls++;
461 sfs_op_type *op_ptr; /* per operation info */
463 ACCESS3res reply; /* the reply */
464 enum clnt_stat rpc_stat; /* result from RPC call */
465 struct ladtime start;
467 int ret; /* ret val == call success */
469 op_ptr = &Ops[ACCESS];
472 /* set up the arguments */
473 (void) memmove((char *) &args.object, (char *) &Cur_file_ptr->dir->fh3,
475 args.access = ACCESS3_MODIFY;
479 rpc_stat = clnt_call(NFS_client, NFSPROC3_ACCESS,
480 xdr_ACCESS3args, (char *) &args,
481 xdr_ACCESS3res, (char *) &reply,
482 (Current_test_phase < Warmup_phase)
484 : Nfs_timers[op_ptr->call_class]);
488 if (rpc_stat == RPC_SUCCESS) {
489 if (reply.status == NFS3_OK) {
490 Cur_file_ptr->state = Exists;
491 (void) memmove((char *) &Cur_file_ptr->attributes3,
492 (char *) &reply.resok.obj_attributes.attr,
493 sizeof (Cur_file_ptr->attributes3));
494 Cur_file_ptr->size = fh_size(Cur_file_ptr);
496 if (DEBUG_CHILD_ERROR) {
497 (void) fprintf(stderr,
498 "%s: access call NFS error %s on file %d\n",
499 sfs_Myname, nfs3_strerror(reply.status),
500 Cur_file_ptr->unique_num);
503 sfs_elapsedtime(op_ptr, &start, &stop);
504 op_ptr->results.good_calls++;
505 Ops[TOTAL].results.good_calls++;
508 if (DEBUG_CHILD_ERROR) {
509 (void) fprintf(stderr, "%s: access call RPC error %d on file %d\n",
510 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
512 op_ptr->results.bad_calls++;
513 Ops[TOTAL].results.bad_calls++;
523 sfs_op_type *op_ptr; /* per operation info */
524 READLINK3args args; /* the args */
525 READLINK3res reply; /* the reply */
526 char sym_data[NFS_MAXPATHLEN];
527 enum clnt_stat rpc_stat; /* result from RPC call */
528 struct ladtime start;
530 int ret; /* ret val == call success */
532 op_ptr = &Ops[READLINK];
535 /* set up the arguments */
537 * Note: this symlink may be bogus because SYMLINK does
538 * not return a symlink ... only a status. So unless we have
539 * done a LOOKUP on this guy, the symlink will probably be bad.
540 * If it is bad it shows up as a symlink error in the results.
542 (void) memmove((char *) &args.symlink,
543 (char *) &Cur_file_ptr->fh3,
546 /* Have lower layers fill in the data directly. */
547 reply.resok.data = sym_data;
549 /* make the call now */
551 rpc_stat = clnt_call(NFS_client, NFSPROC3_READLINK,
552 xdr_READLINK3args, (char *) &args,
553 xdr_READLINK3res, (char *) &reply,
554 (Current_test_phase < Warmup_phase)
556 : Nfs_timers[op_ptr->call_class]);
560 if (rpc_stat == RPC_SUCCESS) {
561 if (reply.status == NFS3_OK) {
562 if (DEBUG_CHILD_RPC) {
563 (void) fprintf(stderr, "%s: READLINK on %s returned %s\n",
564 sfs_Myname, Cur_filename, sym_data);
565 (void) fflush(stderr);
568 if (DEBUG_CHILD_ERROR) {
569 (void) fprintf(stderr,
570 "%s: readlink call NFS error %s on file %d\n",
571 sfs_Myname, nfs3_strerror(reply.status),
572 Cur_file_ptr->unique_num);
575 sfs_elapsedtime(op_ptr, &start, &stop);
576 op_ptr->results.good_calls++;
577 Ops[TOTAL].results.good_calls++;
580 if (DEBUG_CHILD_ERROR) {
581 (void) fprintf(stderr,
582 "%s: readlink call RPC error %d on file %d\n",
583 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
585 op_ptr->results.bad_calls++;
586 Ops[TOTAL].results.bad_calls++;
594 * perform an RPC read operation of length 'xfer_size'
600 sfs_op_type *op_ptr; /* per operation info */
602 int max_cnt; /* packet ctrs */
603 char buf[DEFAULT_MAX_BUFSIZE];/* data buffer */
605 READ3res reply; /* the reply */
606 enum clnt_stat rpc_stat; /* result from RPC call */
607 struct ladtime start;
611 int ret; /* ret val == call success */
616 /* set up the arguments */
617 (void) memmove((char *) &args.file,
618 (char *) &Cur_file_ptr->fh3,
622 * Don't allow a read of less than one block size
624 if (xfer_size < Bytes_per_block)
625 xfer_size = Bytes_per_block;
628 * randomly choose an offset that is a multiple of the block size
629 * and constrained by making the transfer fit within the file
631 args.offset._p._u = 0;
632 if (Cur_file_ptr->attributes3.size._p._l > xfer_size)
633 args.offset._p._l = Bytes_per_block * (sfs_random() %
634 (((Cur_file_ptr->attributes3.size._p._l - xfer_size)
635 / Bytes_per_block) + 1));
637 args.offset._p._l = 0;
639 /* Have lower layers fill in the data directly. */
640 reply.resok.data.data_len = 0;
641 reply.resok.data.data_val = buf;
643 /* first read the whole buffers, then the fragment */
644 for (j = 0; j < 2; j++) {
647 size = Bytes_per_block;
648 max_cnt = xfer_size / Bytes_per_block;
650 /* 1KB - (Kb_per_block -1) KB fragment */
651 size = xfer_size % Bytes_per_block;
657 /* check our stats to see if this would overflow */
659 if (op_ptr->target_calls > 0) {
660 if ((op_ptr->results.good_calls + max_cnt)
661 > op_ptr->target_calls) {
662 max_cnt = op_ptr->target_calls - op_ptr->results.good_calls;
669 if (DEBUG_CHILD_RPC) {
670 (void) fprintf(stderr, "read: %d buffers\n", max_cnt);
671 (void) fflush(stderr);
674 /* make the call(s) now */
675 for (cur_cnt = 0; cur_cnt < max_cnt; cur_cnt++) {
677 /* capture length for possible dump */
678 Dump_length = fh_size(Cur_file_ptr);
681 rpc_stat = clnt_call(NFS_client, NFSPROC3_READ,
682 xdr_READ3args, (char *) &args,
683 xdr_READ3res, (char *) &reply,
684 (Current_test_phase < Warmup_phase)
686 : Nfs_timers[op_ptr->call_class]);
690 /* capture count and offset for possible dump */
691 Dump_count = (rpc_stat == RPC_SUCCESS && reply.status == NFS3_OK)
692 ? reply.resok.data.data_len : 0;
693 Dump_offset = args.offset._p._l;
695 if (rpc_stat == RPC_SUCCESS) {
696 if (reply.status == NFS3_OK) {
697 Cur_file_ptr->state = Exists;
698 (void) memmove((char *) &Cur_file_ptr->attributes3,
699 (char *) &reply.resok.file_attributes.attr,
700 sizeof (Cur_file_ptr->attributes3));
701 Cur_file_ptr->size = fh_size(Cur_file_ptr);
702 size = reply.resok.data.data_len;
704 if (DEBUG_CHILD_RPC) {
705 (void) fprintf(stderr, "%s: READ %s %d bytes\n",
706 sfs_Myname, Cur_filename, size);
707 (void) fflush(stderr);
709 args.offset._p._l += size;
711 if (DEBUG_CHILD_ERROR) {
712 (void) fprintf(stderr,
713 "%s: read call NFS error %s on file %d\n",
715 nfs3_strerror(reply.status),
716 Cur_file_ptr->unique_num);
719 sfs_elapsedtime(op_ptr, &start, &stop);
720 op_ptr->results.good_calls++;
721 Ops[TOTAL].results.good_calls++;
724 if (DEBUG_CHILD_ERROR) {
725 (void) fprintf(stderr,
726 "%s: read call RPC error %d on file %d\n",
727 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
729 op_ptr->results.bad_calls++;
730 Ops[TOTAL].results.bad_calls++;
732 } /* for reading max_cnt packets */
733 } /* for buffers and fragments */
743 static uint32_t write_buf[DEFAULT_MAX_BUFSIZE / sizeof(uint32_t)];
744 uint32_t *be = write_buf + (sizeof(write_buf) /
747 if (write_buf[0] != (uint32_t)0xdeadbeef) {
748 for (bp = write_buf; bp < be; bp++)
749 *bp = (uint32_t)0xdeadbeef;
751 return (char *)write_buf;
756 * Perform and RPC write operation of length 'xfer_size'. If 'append_flag'
757 * is true, then write the data to the end of the file.
759 * If the stab_flag is set to UNSTABLE we issue the requests and then
760 * issue a op_commit to sync the data.
766 stable_how stab_flag)
768 sfs_op_type *op_ptr; /* per operation info */
769 static char *buf = NULL; /* the data buffer */
770 unsigned int size; /* size of data write */
771 int cur_cnt; /* controls # NFS calls */
774 WRITE3res reply; /* the reply */
775 enum clnt_stat rpc_stat; /* result from RPC call */
776 struct ladtime start;
779 int ret; /* ret val == call success */
782 * For now we treat DATA_SYNC to be the same as FILE_SYNC.
784 if (stab_flag == DATA_SYNC)
785 stab_flag = FILE_SYNC;
788 * Initialize write buffer to known value
791 buf = init_write_buffer();
794 op_ptr = &Ops[WRITE];
797 /* set up the arguments */
798 (void) memmove((char *) &args.file, (char *) &Cur_file_ptr->fh3,
800 args.offset._p._u = 0;
801 if (append_flag == 1) {
802 args.offset._p._l = Cur_file_ptr->attributes3.size._p._l;
805 * randomly choose an offset that is a multiple of the block size
806 * and constrained by making the transfer fit within the file
808 if (Cur_file_ptr->attributes3.size._p._l > xfer_size) {
809 args.offset._p._l = Bytes_per_block * (sfs_random() %
810 (((Cur_file_ptr->attributes3.size._p._l - xfer_size)
811 / Bytes_per_block) + 1));
813 args.offset._p._l = 0;
816 /* stab_flag has to be set in op() in sfs_3_chd.c */
817 args.stable = stab_flag;
819 /* first write the whole buffers, then the fragment */
820 for (j = 0; j < 2; j++) {
823 size = Bytes_per_block;
824 max_cnt = xfer_size / Bytes_per_block;
826 /* 1KB - (Kb_per_block - 1) KB fragment */
827 size = xfer_size % Bytes_per_block;
834 args.data.data_len = size;
835 args.data.data_val = buf;
837 /* check our stats to see if this would overflow */
839 if (op_ptr->target_calls > 0) {
840 if ((op_ptr->results.good_calls + max_cnt)
841 > op_ptr->target_calls) {
842 max_cnt = op_ptr->target_calls - op_ptr->results.good_calls;
847 if (DEBUG_CHILD_RPC) {
848 (void) fprintf(stderr, "write: %d buffers\n", max_cnt);
849 (void) fflush(stderr);
852 /* make the call(s) now */
853 for (cur_cnt = 0; cur_cnt < max_cnt; cur_cnt++) {
855 if (DEBUG_CHILD_RPC) {
856 (void) fprintf(stderr, "%s: WRITE %s offset %u count %lu stable %d\n",
857 sfs_Myname, Cur_filename, args.offset._p._l, args.count, args.stable);
858 (void) fflush(stderr);
861 /* capture length for possible dump */
862 Dump_length = fh_size(Cur_file_ptr);
865 rpc_stat = clnt_call(NFS_client, NFSPROC3_WRITE,
866 xdr_WRITE3args, (char *) &args,
867 xdr_WRITE3res, (char *) &reply,
868 (Current_test_phase < Warmup_phase)
870 : Nfs_timers[op_ptr->call_class]);
874 /* capture count and offset for possible dump */
875 Dump_count = args.data.data_len;
876 Dump_offset = args.offset._p._l;
878 if (rpc_stat == RPC_SUCCESS) {
879 if (reply.status == NFS3_OK) {
880 Cur_file_ptr->state = Exists;
881 (void) memmove((char *) &Cur_file_ptr->attributes3,
882 (char *) &reply.resok.file_wcc.after.attr,
883 sizeof (Cur_file_ptr->attributes3));
884 Cur_file_ptr->size = fh_size(Cur_file_ptr);
885 args.offset._p._l += size;
887 if (DEBUG_CHILD_RPC) {
888 (void) fprintf(stderr, "%s: WRITE %s %d bytes\n",
889 sfs_Myname, Cur_filename, size);
890 (void) fflush(stderr);
893 if (DEBUG_CHILD_ERROR) {
894 (void) fprintf(stderr,
895 "%s: write call NFS error %s on file %d\n",
896 sfs_Myname, nfs3_strerror(reply.status),
897 Cur_file_ptr->unique_num);
900 sfs_elapsedtime(op_ptr, &start, &stop);
901 op_ptr->results.good_calls++;
902 Ops[TOTAL].results.good_calls++;
905 if (DEBUG_CHILD_ERROR) {
906 (void) fprintf(stderr,
907 "%s: write call RPC error %d on file %d\n",
908 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
910 op_ptr->results.bad_calls++;
911 Ops[TOTAL].results.bad_calls++;
913 } /* for writing max_cnt packets */
914 } /* for buffers and fragments */
917 * If we have not gotten an error and we were asked for an async write
918 * send a commit operation.
920 if (ret && stab_flag != FILE_SYNC)
931 sfs_op_type *op_ptr; /* per operation info */
933 CREATE3res reply; /* the reply */
934 enum clnt_stat rpc_stat; /* result from RPC call */
935 struct ladtime start;
937 int ret; /* ret val == call success */
939 op_ptr = &Ops[CREATE];
942 /* set up the arguments */
943 (void) memmove((char *) &args.where.dir, (char *) &Cur_file_ptr->dir->fh3,
945 args.where.name = Cur_filename;
946 args.how.mode = UNCHECKED;
947 args.how.createhow3_u.obj_attributes.mode.set_it = TRUE;
948 args.how.createhow3_u.obj_attributes.mode.mode = (NFSMODE_REG | 0666);
949 args.how.createhow3_u.obj_attributes.uid.set_it = TRUE;
950 args.how.createhow3_u.obj_attributes.uid.uid = Cur_uid;
951 args.how.createhow3_u.obj_attributes.gid.set_it = TRUE;
952 args.how.createhow3_u.obj_attributes.gid.gid = Cur_gid;
953 args.how.createhow3_u.obj_attributes.atime.set_it = TRUE;
954 args.how.createhow3_u.obj_attributes.atime.atime.seconds = Cur_time.esec;
955 args.how.createhow3_u.obj_attributes.atime.atime.nseconds =
956 Cur_time.usec * 1000;
957 args.how.createhow3_u.obj_attributes.mtime.set_it = TRUE;
958 args.how.createhow3_u.obj_attributes.mtime.mtime.seconds = Cur_time.esec;
959 args.how.createhow3_u.obj_attributes.mtime.mtime.nseconds =
960 Cur_time.usec * 1000;
961 args.how.createhow3_u.obj_attributes.size.set_it = TRUE;
962 args.how.createhow3_u.obj_attributes.size.size._p._u = (uint32_t) 0;
963 args.how.createhow3_u.obj_attributes.size.size._p._l = (uint32_t) 0;
965 /* make the call now */
967 rpc_stat = clnt_call(NFS_client, NFSPROC3_CREATE,
968 xdr_CREATE3args, (char *) &args,
969 xdr_CREATE3res, (char *) &reply,
970 (Current_test_phase < Warmup_phase)
972 : Nfs_timers[op_ptr->call_class]);
976 if (rpc_stat == RPC_SUCCESS) {
977 if (reply.status == NFS3_OK) {
978 Cur_file_ptr->state = Exists;
979 (void) memmove((char *) &Cur_file_ptr->fh3,
980 (char *) &reply.resok.obj.handle,
982 (void) strcpy(Cur_file_ptr->file_name, Cur_filename);
983 (void) memmove((char *) &Cur_file_ptr->attributes3,
984 (char *) &reply.resok.obj_attributes.attr,
985 sizeof(Cur_file_ptr->attributes3));
986 Cur_file_ptr->size = fh_size(Cur_file_ptr);
988 if (DEBUG_CHILD_ERROR) {
989 (void) fprintf(stderr,
990 "%s: create call NFS error %s on file %d\n",
991 sfs_Myname, nfs3_strerror(reply.status),
992 Cur_file_ptr->unique_num);
995 sfs_elapsedtime(op_ptr, &start, &stop);
996 op_ptr->results.good_calls++;
997 Ops[TOTAL].results.good_calls++;
1000 if (DEBUG_CHILD_ERROR) {
1001 (void) fprintf(stderr, "%s: create call RPC error %d on file %d\n",
1002 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1004 op_ptr->results.bad_calls++;
1005 Ops[TOTAL].results.bad_calls++;
1015 sfs_op_type *op_ptr; /* per operation info */
1017 MKDIR3res reply; /* the reply */
1018 enum clnt_stat rpc_stat; /* result from RPC call */
1019 struct ladtime start;
1020 struct ladtime stop;
1021 int ret; /* ret val == call success */
1023 op_ptr = &Ops[MKDIR];
1026 /* set up the arguments */
1027 (void) memmove((char *) &args.where.dir, (char *) &Cur_file_ptr->dir->fh3,
1029 args.where.name = Cur_filename;
1030 args.attributes.mode.set_it = TRUE;
1031 args.attributes.mode.mode = (NFSMODE_DIR | 0777);
1032 args.attributes.uid.set_it = TRUE;
1033 args.attributes.uid.uid = Cur_uid;
1034 args.attributes.gid.set_it = TRUE;
1035 args.attributes.gid.gid = Cur_gid;
1036 args.attributes.size.set_it = TRUE;
1037 args.attributes.size.size._p._u = 0;
1038 args.attributes.size.size._p._l = 512;
1039 args.attributes.atime.set_it = TRUE;
1040 args.attributes.atime.atime.seconds = Cur_time.esec;
1041 args.attributes.atime.atime.nseconds = Cur_time.usec * 1000;
1042 args.attributes.mtime.set_it = TRUE;
1043 args.attributes.mtime.mtime.seconds = Cur_time.esec;
1044 args.attributes.mtime.mtime.nseconds = Cur_time.usec * 1000;
1046 /* make the call now */
1047 sfs_gettime(&start);
1048 rpc_stat = clnt_call(NFS_client, NFSPROC3_MKDIR,
1049 xdr_MKDIR3args, (char *) &args,
1050 xdr_MKDIR3res, (char *) &reply,
1051 (Current_test_phase < Warmup_phase)
1053 : Nfs_timers[op_ptr->call_class]);
1057 if (rpc_stat == RPC_SUCCESS) {
1058 if (reply.status == NFS3_OK) {
1059 Cur_file_ptr->state = Empty_dir;
1060 (void) memmove((char *) &Cur_file_ptr->fh3,
1061 (char *) &reply.resok.obj.handle,
1063 (void) strcpy(Cur_file_ptr->file_name, Cur_filename);
1064 (void) memmove((char *) &Cur_file_ptr->attributes3,
1065 (char *) &reply.resok.obj_attributes.attr,
1066 sizeof(Cur_file_ptr->attributes3));
1067 Cur_file_ptr->size = fh_size(Cur_file_ptr);
1069 if (DEBUG_CHILD_ERROR) {
1070 (void) fprintf(stderr,
1071 "%s: mkdir call NFS error %s on file %d\n",
1072 sfs_Myname, nfs3_strerror(reply.status),
1073 Cur_file_ptr->unique_num);
1076 sfs_elapsedtime(op_ptr, &start, &stop);
1077 op_ptr->results.good_calls++;
1078 Ops[TOTAL].results.good_calls++;
1081 if (DEBUG_CHILD_ERROR) {
1082 (void) fprintf(stderr, "%s: mkdir call RPC error %d on file %d\n",
1083 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1085 op_ptr->results.bad_calls++;
1086 Ops[TOTAL].results.bad_calls++;
1096 sfs_op_type *op_ptr; /* per operation info */
1097 sfs_fh_type *target_fileinfo_ptr; /* target file */
1099 SYMLINK3res reply; /* the reply */
1100 char sym_data[NFS_MAXPATHLEN]; /* symlink data */
1101 enum clnt_stat rpc_stat; /* result from RPC call */
1102 struct ladtime start;
1103 struct ladtime stop;
1104 int ret; /* ret val == call success */
1106 op_ptr = &Ops[SYMLINK];
1109 /* set up the arguments */
1110 target_fileinfo_ptr = randfh(SYMLINK, 0, 0, Exists, Sfs_non_io_file);
1111 (void) memmove((char *) &args.where.dir, (char *) &Cur_file_ptr->dir->fh3,
1113 args.where.name = Cur_filename;
1115 (void) strcpy(sym_data, "./");
1116 (void) strcat(sym_data, target_fileinfo_ptr->file_name);
1117 args.symlink.symlink_attributes.size.set_it = TRUE;
1118 args.symlink.symlink_attributes.size.size._p._u = (uint32_t) 0;
1119 args.symlink.symlink_attributes.size.size._p._l = strlen(sym_data);
1120 args.symlink.symlink_data = sym_data;
1122 args.symlink.symlink_attributes.mode.set_it = TRUE;
1123 args.symlink.symlink_attributes.mode.mode = (NFSMODE_LNK | 0777);
1124 args.symlink.symlink_attributes.uid.set_it = TRUE;
1125 args.symlink.symlink_attributes.uid.uid = Cur_uid;
1126 args.symlink.symlink_attributes.gid.set_it = TRUE;
1127 args.symlink.symlink_attributes.gid.gid = Cur_gid;
1128 args.symlink.symlink_attributes.atime.set_it = TRUE;
1129 args.symlink.symlink_attributes.atime.atime.seconds = Cur_time.esec;
1130 args.symlink.symlink_attributes.atime.atime.nseconds =
1131 Cur_time.usec * 1000;
1132 args.symlink.symlink_attributes.mtime.set_it = TRUE;
1133 args.symlink.symlink_attributes.mtime.mtime.seconds = Cur_time.esec;
1134 args.symlink.symlink_attributes.mtime.mtime.nseconds =
1135 Cur_time.usec * 1000;
1137 /* make the call now */
1138 sfs_gettime(&start);
1139 rpc_stat = clnt_call(NFS_client, NFSPROC3_SYMLINK,
1140 xdr_SYMLINK3args, (char *) &args,
1141 xdr_SYMLINK3res, (char *) &reply,
1142 ((int)Current_test_phase < (int)Warmup_phase)
1144 : Nfs_timers[op_ptr->call_class]);
1148 if (rpc_stat == RPC_SUCCESS) {
1149 if (reply.status == NFS3_OK) {
1151 * SYMLINK doesn't return a fh. If we try to access this symlink
1152 * (eg, remove(), readlink()) before we do a lookup, we won't have
1153 * a fh to use. So, we do a lookup call here. If it fails, we fill
1156 Cur_file_ptr->state = Exists;
1157 if (op_lookup() == 0) {
1158 (void) strcpy(Cur_file_ptr->file_name, Cur_filename);
1159 Cur_file_ptr->attributes3.type = NF3LNK;
1160 Cur_file_ptr->attributes3.mode = (NFSMODE_LNK|0777);
1161 Cur_file_ptr->attributes3.uid = Cur_uid;
1162 Cur_file_ptr->attributes3.gid = Cur_gid;
1163 Cur_file_ptr->attributes3.atime.seconds = Cur_time.esec;
1164 Cur_file_ptr->attributes3.atime.nseconds =
1165 Cur_time.usec * 1000;
1166 Cur_file_ptr->attributes3.mtime =
1167 Cur_file_ptr->attributes3.atime;
1171 if (DEBUG_CHILD_ERROR) {
1172 (void) fprintf(stderr,
1173 "%s: symlink call NFS error %s on file %d\n",
1174 sfs_Myname, nfs3_strerror(reply.status),
1175 Cur_file_ptr->unique_num);
1178 sfs_elapsedtime(op_ptr, &start, &stop);
1179 op_ptr->results.good_calls++;
1180 Ops[TOTAL].results.good_calls++;
1183 if (DEBUG_CHILD_ERROR) {
1184 (void) fprintf(stderr,
1185 "%s: symlink call RPC error %d on file %d\n",
1186 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1188 op_ptr->results.bad_calls++;
1189 Ops[TOTAL].results.bad_calls++;
1199 sfs_op_type *op_ptr; /* per operation info */
1202 enum clnt_stat rpc_stat; /* result from RPC call */
1203 struct ladtime start;
1204 struct ladtime stop;
1205 int ret; /* ret val == call success */
1207 op_ptr = &Ops[MKNOD];
1210 /* set up the arguments */
1211 (void) memmove((char *) &args.where.dir, (char *) &Cur_file_ptr->dir->fh3,
1213 args.where.name = Cur_filename;
1214 args.what.type = NF3FIFO;
1215 args.what.mknoddata3_u.pipe_attributes.mode.set_it = TRUE;
1216 args.what.mknoddata3_u.pipe_attributes.mode.mode = (NFSMODE_FIFO | 0777);
1217 args.what.mknoddata3_u.pipe_attributes.uid.set_it = TRUE;
1218 args.what.mknoddata3_u.pipe_attributes.uid.uid = Cur_uid;
1219 args.what.mknoddata3_u.pipe_attributes.gid.set_it = TRUE;
1220 args.what.mknoddata3_u.pipe_attributes.gid.gid = Cur_gid;
1221 args.what.mknoddata3_u.pipe_attributes.size.set_it = TRUE;
1222 args.what.mknoddata3_u.pipe_attributes.size.size._p._u = (uint32_t) 0;
1223 args.what.mknoddata3_u.pipe_attributes.size.size._p._l =
1225 args.what.mknoddata3_u.pipe_attributes.atime.set_it = TRUE;
1226 args.what.mknoddata3_u.pipe_attributes.atime.atime.seconds =
1228 args.what.mknoddata3_u.pipe_attributes.atime.atime.nseconds =
1229 Cur_time.usec * 1000;
1230 args.what.mknoddata3_u.pipe_attributes.atime.set_it = TRUE;
1231 args.what.mknoddata3_u.pipe_attributes.mtime.mtime.seconds =
1233 args.what.mknoddata3_u.pipe_attributes.mtime.mtime.nseconds =
1234 Cur_time.usec * 1000;
1236 /* make the call now */
1237 sfs_gettime(&start);
1238 rpc_stat = clnt_call(NFS_client, NFSPROC3_MKNOD,
1239 xdr_MKNOD3args, (char *) &args,
1240 xdr_MKNOD3res, (char *) &reply,
1241 (Current_test_phase < Warmup_phase)
1243 : Nfs_timers[op_ptr->call_class]);
1247 if (rpc_stat == RPC_SUCCESS) {
1248 if (reply.status == NFS3_OK) {
1249 Cur_file_ptr->state = Exists;
1250 (void) memmove((char *) &Cur_file_ptr->fh3,
1251 (char *) &reply.resok.obj.handle,
1253 (void) strcpy(Cur_file_ptr->file_name, Cur_filename);
1254 (void) memmove((char *) &Cur_file_ptr->attributes3,
1255 (char *) &reply.resok.obj_attributes.attr,
1256 sizeof(Cur_file_ptr->attributes3));
1257 Cur_file_ptr->size = fh_size(Cur_file_ptr);
1259 if (DEBUG_CHILD_ERROR) {
1260 (void) fprintf(stderr,
1261 "%s: mknod call NFS error %s on file %d\n",
1262 sfs_Myname, nfs3_strerror(reply.status),
1263 Cur_file_ptr->unique_num);
1266 sfs_elapsedtime(op_ptr, &start, &stop);
1267 op_ptr->results.good_calls++;
1268 Ops[TOTAL].results.good_calls++;
1271 if (DEBUG_CHILD_ERROR) {
1272 (void) fprintf(stderr, "%s: mknod call RPC error %d on file %d\n",
1273 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1275 op_ptr->results.bad_calls++;
1276 Ops[TOTAL].results.bad_calls++;
1286 sfs_op_type *op_ptr; /* per operation info */
1288 REMOVE3res reply; /* the reply */
1289 enum clnt_stat rpc_stat; /* result from RPC call */
1290 struct ladtime start;
1291 struct ladtime stop;
1292 int ret; /* ret val == call success */
1294 op_ptr = &Ops[REMOVE];
1297 /* set up the arguments */
1298 args.object.name = Cur_filename;
1299 (void) memmove((char *) &args.object.dir,(char *) &Cur_file_ptr->dir->fh3,
1302 /* make the call now */
1303 sfs_gettime(&start);
1304 rpc_stat = clnt_call(NFS_client, NFSPROC3_REMOVE,
1305 xdr_REMOVE3args, (char *) &args,
1306 xdr_REMOVE3res, (char *) &reply,
1307 (Current_test_phase < Warmup_phase)
1309 : Nfs_timers[op_ptr->call_class]);
1313 if (rpc_stat == RPC_SUCCESS) {
1314 if (reply.status == NFS3_OK) {
1315 Cur_file_ptr->state = Nonexistent;
1317 if (DEBUG_CHILD_ERROR) {
1318 (void) fprintf(stderr,
1319 "%s: remove call NFS error %s on file %d\n",
1320 sfs_Myname, nfs3_strerror(reply.status),
1321 Cur_file_ptr->unique_num);
1324 sfs_elapsedtime(op_ptr, &start, &stop);
1325 op_ptr->results.good_calls++;
1326 Ops[TOTAL].results.good_calls++;
1329 if (DEBUG_CHILD_ERROR) {
1330 (void) fprintf(stderr, "%s: remove call RPC error %d on file %d\n",
1331 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1333 op_ptr->results.bad_calls++;
1334 Ops[TOTAL].results.bad_calls++;
1344 sfs_op_type *op_ptr; /* per operation info */
1346 RMDIR3res reply; /* the reply */
1347 enum clnt_stat rpc_stat; /* result from RPC call */
1348 struct ladtime start;
1349 struct ladtime stop;
1350 int ret; /* ret val == call success */
1352 op_ptr = &Ops[RMDIR];
1355 /* set up the arguments */
1356 (void) memmove((char *) &args.object.dir, (char *) &Cur_file_ptr->dir->fh3,
1358 args.object.name = Cur_file_ptr->file_name;
1360 /* make the call now */
1361 sfs_gettime(&start);
1362 rpc_stat = clnt_call(NFS_client, NFSPROC3_RMDIR,
1363 xdr_RMDIR3args, (char *) &args,
1364 xdr_RMDIR3res, (char *) &reply,
1365 (Current_test_phase < Warmup_phase)
1367 : Nfs_timers[op_ptr->call_class]);
1371 if (rpc_stat == RPC_SUCCESS) {
1372 if (reply.status == NFS3_OK) {
1373 Cur_file_ptr->state = Nonexistent;
1375 if (DEBUG_CHILD_ERROR) {
1376 (void) fprintf(stderr,
1377 "%s: rmdir call NFS error %s on file %d\n",
1378 sfs_Myname, nfs3_strerror(reply.status),
1379 Cur_file_ptr->unique_num);
1382 sfs_elapsedtime(op_ptr, &start, &stop);
1383 op_ptr->results.good_calls++;
1384 Ops[TOTAL].results.good_calls++;
1387 if (DEBUG_CHILD_ERROR) {
1388 (void) fprintf(stderr, "%s: rmdir call RPC error %d on file %d\n",
1389 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1391 op_ptr->results.bad_calls++;
1392 Ops[TOTAL].results.bad_calls++;
1402 sfs_op_type *op_ptr; /* per operation info */
1403 sfs_fh_type *target_fileinfo_ptr; /* target name */
1405 RENAME3res reply; /* the reply */
1406 enum clnt_stat rpc_stat; /* result from RPC call */
1407 struct ladtime start;
1408 struct ladtime stop;
1409 int ret; /* ret val == call success */
1411 op_ptr = &Ops[RENAME];
1414 /* set up the arguments */
1415 (void) memmove((char *) &args.from.dir, (char *) &Cur_file_ptr->dir->fh3,
1417 (void) memmove((char *) &args.to.dir, (char *) &Cur_file_ptr->dir->fh3,
1420 target_fileinfo_ptr = randfh(RENAME, 0, 0, Nonexistent,
1423 args.from.name = Cur_file_ptr->file_name;
1424 (void) sprintf(target_fileinfo_ptr->file_name, Filespec,
1425 target_fileinfo_ptr->unique_num);
1426 args.to.name = target_fileinfo_ptr->file_name;
1428 /* make the call now */
1429 sfs_gettime(&start);
1430 rpc_stat = clnt_call(NFS_client, NFSPROC3_RENAME,
1431 xdr_RENAME3args, (char *) &args,
1432 xdr_RENAME3res, (char *) &reply,
1433 (Current_test_phase < Warmup_phase)
1435 : Nfs_timers[op_ptr->call_class]);
1439 if (rpc_stat == RPC_SUCCESS) {
1440 if (reply.status == NFS3_OK) {
1441 target_fileinfo_ptr->state = Exists;
1442 (void) memmove((char *) &target_fileinfo_ptr->fh3,
1443 (char *) &Cur_file_ptr->fh3,
1445 target_fileinfo_ptr->attributes3 = Cur_file_ptr->attributes3;
1446 target_fileinfo_ptr->size = fh_size(Cur_file_ptr);
1447 Cur_file_ptr->state = Nonexistent;
1449 if (DEBUG_CHILD_ERROR) {
1450 (void) fprintf(stderr,
1451 "%s: rename call NFS error %s on file %d\n",
1452 sfs_Myname, nfs3_strerror(reply.status),
1453 Cur_file_ptr->unique_num);
1456 sfs_elapsedtime(op_ptr, &start, &stop);
1457 op_ptr->results.good_calls++;
1458 Ops[TOTAL].results.good_calls++;
1461 if (DEBUG_CHILD_ERROR) {
1462 (void) fprintf(stderr, "%s: rename call RPC error %d on file %d\n",
1463 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1465 op_ptr->results.bad_calls++;
1466 Ops[TOTAL].results.bad_calls++;
1476 sfs_op_type *op_ptr; /* per operation info */
1477 sfs_fh_type *target_fileinfo_ptr; /* target */
1479 LINK3res reply; /* the reply */
1480 enum clnt_stat rpc_stat; /* result from RPC call */
1481 struct ladtime start;
1482 struct ladtime stop;
1483 int ret; /* ret val == call success */
1485 op_ptr = &Ops[LINK];
1488 /* set up the arguments */
1489 target_fileinfo_ptr = randfh(LINK, 0, 0, Exists, Sfs_non_io_file);
1490 (void) memmove((char *) &args.file, (char *) &target_fileinfo_ptr->fh3,
1492 (void) memmove((char *) &args.link.dir, (char *) &Cur_file_ptr->dir->fh3,
1494 args.link.name = Cur_filename;
1496 /* make the call now */
1497 sfs_gettime(&start);
1498 rpc_stat = clnt_call(NFS_client, NFSPROC3_LINK,
1499 xdr_LINK3args, (char *) &args,
1500 xdr_LINK3res, (char *) &reply,
1501 (Current_test_phase < Warmup_phase)
1503 : Nfs_timers[op_ptr->call_class]);
1507 if (rpc_stat == RPC_SUCCESS) {
1508 if (reply.status == NFS3_OK) {
1509 Cur_file_ptr->state = Exists;
1510 (void) memmove((char *) &Cur_file_ptr->fh3,
1511 (char *) &target_fileinfo_ptr->fh3,
1513 (void) strcpy(Cur_file_ptr->file_name, Cur_filename);
1514 target_fileinfo_ptr->attributes3.nlink++;
1515 Cur_file_ptr->attributes3 = target_fileinfo_ptr->attributes3;
1516 Cur_file_ptr->size = fh_size(Cur_file_ptr);
1518 if (DEBUG_CHILD_ERROR) {
1519 (void) fprintf(stderr,
1520 "%s: link call NFS error %s on file %d\n",
1521 sfs_Myname, nfs3_strerror(reply.status),
1522 Cur_file_ptr->unique_num);
1525 sfs_elapsedtime(op_ptr, &start, &stop);
1526 op_ptr->results.good_calls++;
1527 Ops[TOTAL].results.good_calls++;
1530 if (DEBUG_CHILD_ERROR) {
1531 (void) fprintf(stderr, "%s: link call RPC error %d on file %d\n",
1532 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1534 op_ptr->results.bad_calls++;
1535 Ops[TOTAL].results.bad_calls++;
1545 sfs_op_type *op_ptr; /* per operation info */
1547 READDIR3res reply; /* the reply */
1548 enum clnt_stat rpc_stat; /* result from RPC call */
1550 struct ladtime start;
1551 struct ladtime stop;
1552 int ret; /* ret val == call success */
1554 /* array of entries */
1555 entry3 entry_stream[SFS_MAXDIRENTS];
1556 entry3 *entries; /* ptr to the dir entry */
1558 op_ptr = &Ops[READDIR];
1561 /* set up the arguments */
1562 (void) memmove((char *) &args.dir, (char *) &Cur_file_ptr->dir->fh3,
1564 args.cookie._p._l = args.cookie._p._u = (uint32_t) 0;
1565 (void) memset((char *) args.cookieverf, '\0', NFS3_COOKIEVERFSIZE);
1566 args.count = DEFAULT_MAX_BUFSIZE;
1568 /* Have lower layers fill in the data directly. */
1569 (void) memset((char *) &reply, '\0', sizeof (reply));
1570 (void) memset((char *) entry_stream, '\0',
1571 sizeof (entry3) * SFS_MAXDIRENTS);
1572 reply.resok.count = SFS_MAXDIRENTS;
1573 reply.resok.reply.entries = entry_stream;
1575 /* make the call now */
1576 sfs_gettime(&start);
1577 rpc_stat = clnt_call(NFS_client, NFSPROC3_READDIR,
1578 xdr_READDIR3args, (char *) &args,
1579 xdr_READDIR3res, (char *) &reply,
1580 (Current_test_phase < Warmup_phase)
1582 : Nfs_timers[op_ptr->call_class]);
1586 if (rpc_stat == RPC_SUCCESS) {
1587 if (reply.status == NFS3_OK) {
1589 if (DEBUG_CHILD_RPC) {
1590 hit_eof = reply.resok.reply.eof;
1591 entries = reply.resok.reply.entries;
1592 for (i = 0; i < reply.resok.count; i++) {
1593 (void) fprintf(stderr, "%s:READDIR (eof=%d) entry %s\n",
1594 sfs_Myname, hit_eof, entries[i].name);
1596 (void) fflush(stderr);
1599 if (DEBUG_CHILD_ERROR) {
1600 (void) fprintf(stderr,
1601 "%s: readdir call NFS error %s on file %d\n",
1602 sfs_Myname, nfs3_strerror(reply.status),
1603 Cur_file_ptr->unique_num);
1606 sfs_elapsedtime(op_ptr, &start, &stop);
1607 op_ptr->results.good_calls++;
1608 Ops[TOTAL].results.good_calls++;
1611 if (DEBUG_CHILD_ERROR) {
1612 (void) fprintf(stderr,
1613 "%s: readdir call RPC error %d on file %d\n",
1614 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1616 op_ptr->results.bad_calls++;
1617 Ops[TOTAL].results.bad_calls++;
1625 op_readdirplus(void)
1627 sfs_op_type *op_ptr; /* per operation info */
1628 READDIRPLUS3args args;
1629 READDIRPLUS3res reply; /* the reply */
1630 enum clnt_stat rpc_stat; /* result from RPC call */
1632 struct ladtime start;
1633 struct ladtime stop;
1634 int ret; /* ret val == call success */
1636 /* array of entries */
1637 entryplus3 entry_stream[SFS_MAXDIRENTS];
1638 entryplus3 *entries;
1640 op_ptr = &Ops[READDIRPLUS];
1643 /* set up the arguments */
1644 (void) memmove((char *) &args.dir, (char *) &Cur_file_ptr->dir->fh3,
1646 args.cookie._p._l = args.cookie._p._u = (uint32_t) 0;
1647 (void) memset((char *) args.cookieverf, '\0', NFS3_COOKIEVERFSIZE);
1648 (void) memset((char *) entry_stream, '\0',
1649 sizeof (entryplus3) * SFS_MAXDIRENTS);
1650 args.dircount = DEFAULT_MAX_BUFSIZE;
1651 args.maxcount = DEFAULT_MAX_BUFSIZE;
1653 /* Have lower layers fill in the data directly. */
1654 reply.resok.count = SFS_MAXDIRENTS;
1655 reply.resok.reply.entries = entry_stream;
1657 /* make the call now */
1658 sfs_gettime(&start);
1659 rpc_stat = clnt_call(NFS_client, NFSPROC3_READDIRPLUS,
1660 xdr_READDIRPLUS3args, (char *) &args,
1661 xdr_READDIRPLUS3res, (char *) &reply,
1662 (Current_test_phase < Warmup_phase)
1664 : Nfs_timers[op_ptr->call_class]);
1668 if (rpc_stat == RPC_SUCCESS) {
1669 if (reply.status == NFS3_OK) {
1671 if (DEBUG_CHILD_RPC) {
1672 hit_eof = reply.resok.reply.eof;
1673 entries = reply.resok.reply.entries;
1674 for (i = 0; i < reply.resok.count; i++) {
1675 (void) fprintf(stderr, "%s:READDIR (eof=%d) entry %s\n",
1676 sfs_Myname, hit_eof, entries[i].name);
1678 (void) fflush(stderr);
1681 if (DEBUG_CHILD_ERROR) {
1682 (void) fprintf(stderr,
1683 "%s: readdir call NFS error %s on file %d\n",
1684 sfs_Myname, nfs3_strerror(reply.status),
1685 Cur_file_ptr->unique_num);
1688 sfs_elapsedtime(op_ptr, &start, &stop);
1689 op_ptr->results.good_calls++;
1690 Ops[TOTAL].results.good_calls++;
1693 if (DEBUG_CHILD_ERROR) {
1694 (void) fprintf(stderr,
1695 "%s: readdir call RPC error %d on file %d\n",
1696 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1698 op_ptr->results.bad_calls++;
1699 Ops[TOTAL].results.bad_calls++;
1703 } /* op_readdirplus */
1709 sfs_op_type *op_ptr; /* per operation info */
1711 FSSTAT3res reply; /* the reply */
1712 enum clnt_stat rpc_stat; /* result from RPC call */
1713 struct ladtime start;
1714 struct ladtime stop;
1715 int ret; /* ret val == call success */
1717 op_ptr = &Ops[FSSTAT];
1720 /* set up the arguments */
1721 (void) memmove((char *) &args.fsroot, (char *) &Cur_file_ptr->dir->fh3,
1725 sfs_gettime(&start);
1726 rpc_stat = clnt_call(NFS_client, NFSPROC3_FSSTAT,
1727 xdr_FSSTAT3args, (char *) &args,
1728 xdr_FSSTAT3args, (char *) &reply,
1729 (Current_test_phase < Warmup_phase)
1731 : Nfs_timers[op_ptr->call_class]);
1735 if (rpc_stat == RPC_SUCCESS) {
1736 sfs_elapsedtime(op_ptr, &start, &stop);
1737 op_ptr->results.good_calls++;
1738 Ops[TOTAL].results.good_calls++;
1741 if (DEBUG_CHILD_ERROR) {
1742 (void) fprintf(stderr, "%s: fsstat call RPC error %d\n",
1743 sfs_Myname, rpc_stat);
1745 op_ptr->results.bad_calls++;
1746 Ops[TOTAL].results.bad_calls++;
1756 sfs_op_type *op_ptr; /* per operation info */
1758 FSINFO3res reply; /* the reply */
1759 enum clnt_stat rpc_stat; /* result from RPC call */
1760 struct ladtime start;
1761 struct ladtime stop;
1762 int ret; /* ret val == call success */
1764 op_ptr = &Ops[FSINFO];
1767 /* set up the arguments */
1768 (void) memmove((char *) &args.fsroot, (char *) &Cur_file_ptr->dir->fh3,
1772 sfs_gettime(&start);
1773 rpc_stat = clnt_call(NFS_client, NFSPROC3_FSINFO,
1774 xdr_FSINFO3args, (char *) &args,
1775 xdr_FSINFO3args, (char *) &reply,
1776 (Current_test_phase < Warmup_phase)
1778 : Nfs_timers[op_ptr->call_class]);
1782 if (rpc_stat == RPC_SUCCESS) {
1783 sfs_elapsedtime(op_ptr, &start, &stop);
1784 op_ptr->results.good_calls++;
1785 Ops[TOTAL].results.good_calls++;
1788 if (DEBUG_CHILD_ERROR) {
1789 (void) fprintf(stderr, "%s: fsinfo call RPC error %d\n",
1790 sfs_Myname, rpc_stat);
1792 op_ptr->results.bad_calls++;
1793 Ops[TOTAL].results.bad_calls++;
1803 sfs_op_type *op_ptr; /* per operation info */
1805 PATHCONF3res reply; /* the reply */
1806 enum clnt_stat rpc_stat; /* result from RPC call */
1807 struct ladtime start;
1808 struct ladtime stop;
1809 int ret; /* ret val == call success */
1811 op_ptr = &Ops[PATHCONF];
1814 /* set up the arguments */
1815 (void) memmove((char *) &args.object, (char *) &Cur_file_ptr->fh3,
1819 sfs_gettime(&start);
1820 rpc_stat = clnt_call(NFS_client, NFSPROC3_PATHCONF,
1821 xdr_PATHCONF3args, (char *) &args,
1822 xdr_PATHCONF3args, (char *) &reply,
1823 (Current_test_phase < Warmup_phase)
1825 : Nfs_timers[op_ptr->call_class]);
1829 if (rpc_stat == RPC_SUCCESS) {
1830 sfs_elapsedtime(op_ptr, &start, &stop);
1831 op_ptr->results.good_calls++;
1832 Ops[TOTAL].results.good_calls++;
1835 if (DEBUG_CHILD_ERROR) {
1836 (void) fprintf(stderr,
1837 "%s: pathconf call RPC error %d on file %d\n",
1838 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1840 op_ptr->results.bad_calls++;
1841 Ops[TOTAL].results.bad_calls++;
1851 sfs_op_type *op_ptr; /* per operation info */
1852 int32_t size; /* size of data write */
1854 COMMIT3res reply; /* the reply */
1855 enum clnt_stat rpc_stat; /* result from RPC call */
1856 struct ladtime start;
1857 struct ladtime stop;
1858 int ret; /* ret val == call success */
1860 op_ptr = &Ops[COMMIT];
1863 /* set up the arguments */
1864 (void) memmove((char *) &args.file, (char *) &Cur_file_ptr->fh3,
1866 args.offset._p._u = args.offset._p._l = (uint32_t) 0;
1867 args.count = Cur_file_ptr->attributes3.size._p._l;
1870 sfs_gettime(&start);
1871 rpc_stat = clnt_call(NFS_client, NFSPROC3_COMMIT,
1872 xdr_COMMIT3args, (char *) &args,
1873 xdr_COMMIT3res, (char *) &reply,
1874 (Current_test_phase < Warmup_phase)
1876 : Nfs_timers[op_ptr->call_class]);
1880 if (rpc_stat == RPC_SUCCESS) {
1881 if (reply.status == NFS3_OK) {
1882 Cur_file_ptr->state = Exists;
1883 (void) memmove((char *) &Cur_file_ptr->attributes3,
1884 (char *) &reply.resok.file_wcc.after.attr,
1885 sizeof(Cur_file_ptr->attributes3));
1886 Cur_file_ptr->size = fh_size(Cur_file_ptr);
1888 if (DEBUG_CHILD_RPC) {
1889 (void) fprintf(stderr, "%s: WRITE %s %ld bytes\n",
1890 sfs_Myname, Cur_filename, size);
1891 (void) fflush(stderr);
1894 if (DEBUG_CHILD_ERROR) {
1895 (void) fprintf(stderr,
1896 "%s: write call NFS error %s on file %d\n",
1897 sfs_Myname, nfs3_strerror(reply.status),
1898 Cur_file_ptr->unique_num);
1901 sfs_elapsedtime(op_ptr, &start, &stop);
1902 op_ptr->results.good_calls++;
1903 Ops[TOTAL].results.good_calls++;
1906 if (DEBUG_CHILD_ERROR) {
1907 (void) fprintf(stderr, "%s: write call RPC error %d on file %d\n",
1908 sfs_Myname, rpc_stat, Cur_file_ptr->unique_num);
1910 op_ptr->results.bad_calls++;
1911 Ops[TOTAL].results.bad_calls++;
1919 #define LAD_RETRIABLE(stat) (((stat) == RPC_TIMEDOUT) || ((stat) == RPC_CANTDECODERES))
1922 * Reliably lookup a file in the current directory
1925 * 1 File doesn't exist
1929 lad_lookup(sfs_fh_type *file_ptr, char *name)
1932 LOOKUP3res reply; /* the reply */
1933 enum clnt_stat rpc_stat; /* result from RPC call */
1935 if (DEBUG_CHILD_RPC) {
1936 (void) fprintf(stderr, "%s:lad_lookup: %lx[%lx] %s\n", sfs_Myname,
1937 (int32_t) file_ptr, (int32_t) file_ptr->dir, name);
1938 (void) fflush(stderr);
1943 /* set up the arguments */
1944 (void) memmove((char *) &args.what.dir, (char *) &file_ptr->dir->fh3,
1946 args.what.name = name;
1947 (void) memset((char *) &reply.resok.object, '\0', sizeof (nfs_fh3));
1950 rpc_stat = clnt_call(NFS_client, NFSPROC3_LOOKUP,
1951 xdr_LOOKUP3args, (char *) &args,
1952 xdr_LOOKUP3res, (char *) &reply,
1955 if (rpc_stat == RPC_SUCCESS)
1957 if (rpc_stat != RPC_TIMEDOUT) {
1958 (void) fprintf(stderr, "lad_lookup(%s) RPC call failed : %s\n",
1959 name, clnt_sperrno(rpc_stat));
1961 if (!LAD_RETRIABLE(rpc_stat)) {
1966 if (reply.status == NFS3ERR_NOENT) {
1970 if (reply.status != NFS3_OK) {
1971 (void) fprintf(stderr, "lad_lookup(%s) NFS call failed : %s\n",
1972 name, nfs3_strerror(reply.status));
1976 file_ptr->state = Exists;
1977 (void) memmove((char *) &file_ptr->fh3,
1978 (char *) &reply.resok.object,
1980 (void) strcpy(file_ptr->file_name, name);
1981 (void) memmove((char *) &file_ptr->attributes3,
1982 (char *) &reply.resok.obj_attributes.attr,
1983 sizeof (file_ptr->attributes3));
1984 file_ptr->size = fh_size(file_ptr);
1989 * Reliably remove a file in the current directory
1992 lad_remove(sfs_fh_type *file_ptr, char *name)
1995 REMOVE3res reply; /* the reply */
1996 enum clnt_stat rpc_stat; /* result from RPC call */
2000 * This function presumes that the file name does exist
2002 if (file_ptr->attributes3.type == NF3DIR)
2003 return (lad_rmdir(file_ptr, name));
2005 if (DEBUG_CHILD_RPC) {
2006 (void) fprintf(stderr, "%s:lad_remove: %lx[%lx] %s\n", sfs_Myname,
2007 (int32_t) file_ptr, (int32_t) file_ptr->dir, name);
2008 (void) fflush(stderr);
2013 /* set up the arguments */
2014 args.object.name = name;
2015 (void) memmove((char *) &args.object.dir, (char *) &file_ptr->dir->fh3,
2018 /* make the call now */
2019 rpc_stat = clnt_call(NFS_client, NFSPROC3_REMOVE,
2020 xdr_REMOVE3args, (char *) &args,
2021 xdr_REMOVE3res, (char *) &reply,
2024 if (rpc_stat == RPC_SUCCESS)
2026 if (rpc_stat != RPC_TIMEDOUT) {
2027 (void) fprintf(stderr, "lad_remove(%s) RPC call failed : %s\n",
2028 name, clnt_sperrno(rpc_stat));
2030 if (!LAD_RETRIABLE(rpc_stat)) {
2036 if (reply.status != NFS3_OK) {
2037 if (reply.status != NFS3ERR_NOENT || !retried) {
2038 (void) fprintf(stderr, "lad_remove(%s) NFS call failed : %s\n",
2039 name, nfs3_strerror(reply.status));
2044 file_ptr->state = Nonexistent;
2050 * Reliably remove a directory in the current directory
2053 lad_rmdir(sfs_fh_type *file_ptr, char *name)
2056 RMDIR3res reply; /* the reply */
2057 enum clnt_stat rpc_stat; /* result from RPC call */
2061 * This function presumes that the file name does exist and is empty
2063 if (file_ptr->attributes3.type != NF3DIR)
2064 return (lad_remove(file_ptr, name));
2066 if (DEBUG_CHILD_RPC) {
2067 (void) fprintf(stderr, "%s:lad_rmdir: %lx[%lx] %s\n", sfs_Myname,
2068 (int32_t) file_ptr, (int32_t) file_ptr->dir, name);
2069 (void) fflush(stderr);
2074 /* set up the arguments */
2075 args.object.name = name;
2076 (void) memmove((char *) &args.object.dir, (char *) &file_ptr->dir->fh3,
2079 /* make the call now */
2080 rpc_stat = clnt_call(NFS_client, NFSPROC3_RMDIR,
2081 xdr_RMDIR3args, (char *) &args,
2082 xdr_RMDIR3res, (char *) &reply,
2085 if (rpc_stat == RPC_SUCCESS)
2087 if (rpc_stat != RPC_TIMEDOUT) {
2088 (void) fprintf(stderr, "lad_rmdir(%s) RPC call failed : %s\n",
2089 name, clnt_sperrno(rpc_stat));
2091 if (!LAD_RETRIABLE(rpc_stat)) {
2097 if (reply.status != NFS3_OK) {
2098 if (reply.status != NFS3ERR_NOENT || !retried) {
2099 (void) fprintf(stderr, "lad_rmdir(%s) NFS call failed : %s\n",
2100 name, nfs3_strerror(reply.status));
2105 file_ptr->state = Nonexistent;
2111 * Reliably create a symlink in the current directory
2114 lad_symlink(sfs_fh_type *file_ptr, char *target, char *name)
2117 SYMLINK3res reply; /* the reply */
2118 char sym_data[NFS_MAXPATHLEN]; /* symlink data */
2119 enum clnt_stat rpc_stat; /* result from RPC call */
2123 * This function presumes that the file name does not already exist
2125 if (DEBUG_CHILD_RPC) {
2126 (void) fprintf(stderr, "%s:lad_symlink: %lx[%lx] %s -> %s\n", sfs_Myname,
2127 (int32_t) file_ptr, (int32_t) file_ptr->dir, name, target);
2128 (void) fflush(stderr);
2133 /* set up the arguments */
2134 (void) memmove((char *) &args.where.dir, (char *) &file_ptr->dir->fh3,
2136 args.where.name = name;
2138 (void) strcpy(sym_data, "./");
2139 (void) strcat(sym_data, target);
2140 args.symlink.symlink_attributes.size.set_it = TRUE;
2141 args.symlink.symlink_attributes.size.size._p._u = (uint32_t) 0;
2142 args.symlink.symlink_attributes.size.size._p._l = strlen(sym_data);
2143 args.symlink.symlink_data = sym_data;
2145 args.symlink.symlink_attributes.mode.set_it = TRUE;
2146 args.symlink.symlink_attributes.mode.mode = (NFSMODE_LNK | 0777);
2147 args.symlink.symlink_attributes.uid.set_it = TRUE;
2148 args.symlink.symlink_attributes.uid.uid = Cur_uid;
2149 args.symlink.symlink_attributes.gid.set_it = TRUE;
2150 args.symlink.symlink_attributes.gid.gid = Cur_gid;
2151 args.symlink.symlink_attributes.atime.set_it = TRUE;
2152 args.symlink.symlink_attributes.atime.atime.seconds = Cur_time.esec;
2153 args.symlink.symlink_attributes.atime.atime.nseconds =
2154 Cur_time.usec * 1000;
2155 args.symlink.symlink_attributes.mtime.set_it = TRUE;
2156 args.symlink.symlink_attributes.mtime.mtime.seconds = Cur_time.esec;
2157 args.symlink.symlink_attributes.mtime.mtime.nseconds =
2158 Cur_time.usec * 1000;
2161 /* make the call now */
2162 rpc_stat = clnt_call(NFS_client, NFSPROC3_SYMLINK,
2163 xdr_SYMLINK3args, (char *) &args,
2164 xdr_SYMLINK3res, (char *) &reply,
2166 if (rpc_stat == RPC_SUCCESS)
2168 if (rpc_stat != RPC_TIMEDOUT) {
2169 (void) fprintf(stderr, "lad_symlink(%s) RPC call failed : %s\n",
2170 name, clnt_sperrno(rpc_stat));
2172 if (!LAD_RETRIABLE(rpc_stat)) {
2178 if (reply.status != NFS3_OK) {
2179 if (reply.status != NFS3ERR_EXIST || !retried) {
2180 (void) fprintf(stderr, "lad_symlink(%s, %s) NFS call failed : %s\n",
2181 target, name, nfs3_strerror(reply.status));
2187 * SYMLINK may not return a fh. If we try to
2188 * access this symlink (eg, remove(), readlink())
2189 * before we do a lookup, we won't have a fh to use.
2190 * So, we do a lookup call here.
2191 * If it fails, we fill in what we can.
2193 return (lad_lookup(file_ptr, name));
2197 * Reliably create a directory in the current directory
2200 lad_mkdir(sfs_fh_type *file_ptr, char *name)
2203 MKDIR3res reply; /* the reply */
2204 enum clnt_stat rpc_stat; /* result from RPC call */
2208 * This function presumes that the file name does not already exist
2210 if (DEBUG_CHILD_RPC) {
2211 (void) fprintf(stderr, "%s:lad_mkdir: %lx[%lx] %s\n", sfs_Myname,
2212 (int32_t) file_ptr, (int32_t) file_ptr->dir, name);
2213 (void) fflush(stderr);
2218 /* set up the arguments */
2219 (void) memmove((char *) &args.where.dir, (char *) &file_ptr->dir->fh3,
2221 args.where.name = name;
2222 args.attributes.mode.set_it = TRUE;
2223 args.attributes.mode.mode = (NFSMODE_DIR | 0777);
2224 args.attributes.uid.set_it = TRUE;
2225 args.attributes.uid.uid = Cur_uid;
2226 args.attributes.gid.set_it = TRUE;
2227 args.attributes.gid.gid = Cur_gid;
2228 args.attributes.size.set_it = TRUE;
2229 args.attributes.size.size._p._u = 0;
2230 args.attributes.size.size._p._l = 512;
2231 args.attributes.atime.set_it = TRUE;
2232 args.attributes.atime.atime.seconds = Cur_time.esec;
2233 args.attributes.atime.atime.nseconds = Cur_time.usec * 1000;
2234 args.attributes.mtime.set_it = TRUE;
2235 args.attributes.mtime.mtime.seconds = Cur_time.esec;
2236 args.attributes.mtime.mtime.nseconds = Cur_time.usec * 1000;
2238 /* make the call now */
2239 rpc_stat = clnt_call(NFS_client, NFSPROC3_MKDIR,
2240 xdr_MKDIR3args, (char *) &args,
2241 xdr_MKDIR3res, (char *) &reply,
2244 if (rpc_stat == RPC_SUCCESS)
2246 if (rpc_stat != RPC_TIMEDOUT) {
2247 (void) fprintf(stderr, "lad_mkdir(%s) RPC call failed : %s\n",
2248 name, clnt_sperrno(rpc_stat));
2250 if (!LAD_RETRIABLE(rpc_stat)) {
2256 if (!retried && reply.status == NFS3ERR_EXIST)
2259 if (reply.status != NFS3_OK) {
2260 if (reply.status != NFS3ERR_EXIST || !retried) {
2261 (void) fprintf(stderr, "lad_mkdir(%s) NFS call failed : %s\n",
2262 name, nfs3_strerror(reply.status));
2266 * If the first mkdir suceeded but the reply as dropped and
2267 * was retransmitted, we still need to lookup the attributes
2269 if (lad_lookup(file_ptr, name))
2272 (void) memmove((char *) &file_ptr->fh3,
2273 (char *) &reply.resok.obj.handle,
2275 (void) strcpy(file_ptr->file_name, name);
2276 (void) memmove((char *) &file_ptr->attributes3,
2277 (char *) &reply.resok.obj_attributes.attr,
2278 sizeof(file_ptr->attributes3));
2279 file_ptr->size = fh_size(file_ptr);
2281 file_ptr->state = Empty_dir;
2287 * Reliably commit a file
2290 lad_commit(sfs_fh_type *file_ptr)
2293 COMMIT3res reply; /* the reply */
2294 enum clnt_stat rpc_stat; /* result from RPC call */
2296 if (DEBUG_CHILD_RPC) {
2297 (void) fprintf(stderr, "%s:lad_commit: %lx[%lx]\n",
2299 (int32_t) file_ptr, (int32_t) file_ptr->dir);
2300 (void) fflush(stderr);
2303 /* set up the arguments */
2304 (void) memmove((char *) &args.file, (char *) &file_ptr->fh3,
2306 args.offset._p._u = args.offset._p._l = (uint32_t) 0;
2307 args.count = file_ptr->attributes3.size._p._l;
2311 rpc_stat = clnt_call(NFS_client, NFSPROC3_COMMIT,
2312 xdr_COMMIT3args, (char *) &args,
2313 xdr_COMMIT3res, (char *) &reply,
2315 if (rpc_stat == RPC_SUCCESS)
2317 if (rpc_stat != RPC_TIMEDOUT) {
2318 (void) fprintf(stderr, "lad_commit() RPC call failed : %s\n",
2319 clnt_sperrno(rpc_stat));
2321 if (!LAD_RETRIABLE(rpc_stat)) {
2330 * Reliably write a file in the current directory
2333 lad_write(sfs_fh_type *file_ptr, int32_t offset, int32_t length)
2335 static char *buf = NULL; /* the data buffer */
2336 int32_t size; /* size of data write */
2339 WRITE3res reply; /* the reply */
2340 enum clnt_stat rpc_stat; /* result from RPC call */
2343 if (DEBUG_CHILD_RPC) {
2344 (void) fprintf(stderr, "%s:lad_write: %lx[%lx] %ld %ld\n",
2346 (int32_t) file_ptr, (int32_t) file_ptr->dir, offset, length);
2347 (void) fflush(stderr);
2351 * This function presumes that the file name does exist
2352 * Initialize write buffer to known value
2355 buf = init_write_buffer();
2359 * If a short file write don't bother with the commit, just write sync.
2361 if (length <= Bytes_per_block)
2364 /* set up the arguments */
2365 (void) memmove((char *) &args.file, (char *) &file_ptr->fh3,
2367 args.offset._p._u = 0;
2368 args.offset._p._l = offset;
2370 args.stable = UNSTABLE;
2372 args.stable = FILE_SYNC;
2374 size = Bytes_per_block;
2375 for (cur_cnt = 0; cur_cnt < length; cur_cnt += size) {
2376 if ((cur_cnt + size) > length)
2377 size = length - cur_cnt;
2383 args.data.data_len = size;
2384 args.data.data_val = buf;
2386 /* make the call now */
2389 rpc_stat = clnt_call(NFS_client, NFSPROC3_WRITE,
2390 xdr_WRITE3args, (char *) &args,
2391 xdr_WRITE3res, (char *) &reply,
2394 if (rpc_stat == RPC_SUCCESS)
2396 if (rpc_stat != RPC_TIMEDOUT) {
2397 (void) fprintf(stderr, "lad_write() RPC call failed : %s\n",
2398 clnt_sperrno(rpc_stat));
2400 if (!LAD_RETRIABLE(rpc_stat)) {
2404 if (reply.status != NFS3_OK) {
2405 (void) fprintf(stderr, "lad_write() NFS call failed : %s\n",
2406 nfs3_strerror(reply.status));
2409 file_ptr->state = Exists;
2410 (void) memmove((char *) &file_ptr->attributes3,
2411 (char *) &reply.resok.file_wcc.after.attr,
2412 sizeof (file_ptr->attributes3));
2413 file_ptr->size = fh_size(file_ptr);
2415 args.offset._p._l += size;
2419 (void) lad_commit(file_ptr);
2424 * Reliably create a file in the current directory
2427 lad_create(sfs_fh_type *file_ptr, char *name)
2430 CREATE3res reply; /* the reply */
2431 enum clnt_stat rpc_stat; /* result from RPC call */
2435 * This function presumes that the file name does not already exist
2437 if (DEBUG_CHILD_RPC) {
2438 (void) fprintf(stderr, "%s:lad_create: %lx[%lx] %s\n", sfs_Myname,
2439 (int32_t) file_ptr, (int32_t) file_ptr->dir, name);
2440 (void) fflush(stderr);
2445 /* set up the arguments */
2446 (void) memmove((char *) &args.where.dir, (char *) &file_ptr->dir->fh3,
2448 args.where.name = name;
2449 args.how.mode = UNCHECKED;
2450 args.how.createhow3_u.obj_attributes.mode.set_it = TRUE;
2451 args.how.createhow3_u.obj_attributes.mode.mode = (NFSMODE_REG | 0666);
2452 args.how.createhow3_u.obj_attributes.uid.set_it = TRUE;
2453 args.how.createhow3_u.obj_attributes.uid.uid = Cur_uid;
2454 args.how.createhow3_u.obj_attributes.gid.set_it = TRUE;
2455 args.how.createhow3_u.obj_attributes.gid.gid = Cur_gid;
2456 args.how.createhow3_u.obj_attributes.atime.set_it = TRUE;
2457 args.how.createhow3_u.obj_attributes.atime.atime.seconds =
2459 args.how.createhow3_u.obj_attributes.atime.atime.nseconds =
2460 Cur_time.usec * 1000;
2461 args.how.createhow3_u.obj_attributes.mtime.set_it = TRUE;
2462 args.how.createhow3_u.obj_attributes.mtime.mtime.seconds =
2464 args.how.createhow3_u.obj_attributes.mtime.mtime.nseconds =
2465 Cur_time.usec * 1000;
2466 args.how.createhow3_u.obj_attributes.size.set_it = TRUE;
2467 args.how.createhow3_u.obj_attributes.size.size._p._u =
2469 args.how.createhow3_u.obj_attributes.size.size._p._l =
2472 /* make the call now */
2473 rpc_stat = clnt_call(NFS_client, NFSPROC3_CREATE,
2474 xdr_CREATE3args, (char *) &args,
2475 xdr_CREATE3res, (char *) &reply,
2478 if (rpc_stat == RPC_SUCCESS)
2480 if (rpc_stat != RPC_TIMEDOUT) {
2481 (void) fprintf(stderr, "lad_create(%s) RPC call failed : %s\n",
2482 name, clnt_sperrno(rpc_stat));
2484 if (!LAD_RETRIABLE(rpc_stat)) {
2490 if (!retried && reply.status == NFS3ERR_EXIST) {
2494 if (reply.status != NFS3_OK) {
2495 if (reply.status != NFS3ERR_EXIST || !retried) {
2496 (void) fprintf(stderr, "lad_create(%s) NFS call failed : %s\n",
2497 name, nfs3_strerror(reply.status));
2501 * If the first create suceeded but the reply as dropped and
2502 * was retransmitted, we still need to lookup the attributes
2504 if (lad_lookup(file_ptr, name))
2507 (void) memmove((char *) &file_ptr->fh3,
2508 (char *) &reply.resok.obj.handle,
2510 (void) strcpy(file_ptr->file_name, name);
2511 (void) memmove((char *) &file_ptr->attributes3,
2512 (char *) &reply.resok.obj_attributes.attr,
2513 sizeof(file_ptr->attributes3));
2514 file_ptr->size = fh_size(file_ptr);
2517 file_ptr->state = Exists;
2519 * Directories are created as Empty_dir, when a file is created it
2520 * becomes an Exists.
2522 file_ptr->dir->state = Exists;
2528 * Reliably set the size of a file in the current directory
2531 lad_truncate(sfs_fh_type *file_ptr, int32_t size)
2534 SETATTR3res reply; /* the reply */
2535 enum clnt_stat rpc_stat; /* result from RPC call */
2538 * This function presumes that the file name already exists
2540 if (DEBUG_CHILD_RPC) {
2541 (void) fprintf(stderr, "%s:lad_truncate: %lx[%lx] %ld\n", sfs_Myname,
2542 (int32_t) file_ptr, (int32_t) file_ptr->dir, size);
2543 (void) fflush(stderr);
2549 * set up the arguments
2550 * Set the mode and times as well
2552 (void) memmove((char *) &args.object, (char *) &file_ptr->fh3,
2554 args.new_attributes.mode.set_it = TRUE;
2555 args.new_attributes.mode.mode = (uint32_t) 0666;
2556 args.new_attributes.uid.set_it = FALSE;
2557 args.new_attributes.uid.uid = (uint32_t) -1;
2558 args.new_attributes.gid.set_it = FALSE;
2559 args.new_attributes.gid.gid = (uint32_t) -1;
2560 args.new_attributes.size.set_it = TRUE;
2561 args.new_attributes.size.size._p._u = 0;
2562 args.new_attributes.size.size._p._l = size;
2563 args.new_attributes.atime.set_it = TRUE;
2564 args.new_attributes.atime.atime.seconds = Cur_time.esec;
2565 args.new_attributes.atime.atime.nseconds = Cur_time.usec * 1000;
2566 args.new_attributes.mtime.set_it = TRUE;
2567 args.new_attributes.mtime.mtime.seconds = Cur_time.esec;
2568 args.new_attributes.mtime.mtime.nseconds = Cur_time.usec * 1000;
2569 args.guard.check = FALSE;
2572 rpc_stat = clnt_call(NFS_client, NFSPROC3_SETATTR,
2573 xdr_SETATTR3args, (char *) &args,
2574 xdr_SETATTR3res, (char *) &reply,
2577 if (rpc_stat == RPC_SUCCESS)
2579 if (rpc_stat != RPC_TIMEDOUT) {
2580 (void)fprintf(stderr,
2581 "lad_truncate(%ld) RPC call failed : %s\n",
2582 size, clnt_sperrno(rpc_stat));
2584 if (!LAD_RETRIABLE(rpc_stat)) {
2589 if (reply.status != NFS3_OK) {
2590 (void) fprintf(stderr, "lad_truncate(%ld) NFS call failed : %s\n",
2591 size, nfs3_strerror(reply.status));
2594 (void) memmove(&file_ptr->attributes3,
2595 &reply.resok.obj_wcc.after.attr,
2596 sizeof (file_ptr->attributes3));
2597 file_ptr->size = fh_size(file_ptr);
2603 nfs3_strerror(int status)
2605 static char str[40];
2608 (void) strcpy(str, "no error");
2611 (void) strcpy(str, "Not owner");
2614 (void) strcpy(str, "No such file or directory");
2617 (void) strcpy(str, "I/O error");
2620 (void) strcpy(str, "No such device or address");
2623 (void) strcpy(str, "Permission denied");
2626 (void) strcpy(str, "File exists");
2629 (void) strcpy(str, "Cross-device link");
2632 (void) strcpy(str, "No such device");
2634 case NFS3ERR_NOTDIR:
2635 (void) strcpy(str, "Not a directory");
2638 (void) strcpy(str, "Is a directory");
2641 (void) strcpy(str, "Invalid argument");
2644 (void) strcpy(str, "File too large");
2647 (void) strcpy(str, "No space left on device");
2650 (void) strcpy(str, "Read-only file system");
2653 (void) strcpy(str, "Too many links");
2655 case NFS3ERR_NAMETOOLONG:
2656 (void) strcpy(str, "File name too long");
2658 case NFS3ERR_NOTEMPTY:
2659 (void) strcpy(str, "Directory not empty");
2662 (void) strcpy(str, "Disc quota exceeded");
2665 (void) strcpy(str, "Stale NFS file handle");
2667 case NFS3ERR_REMOTE:
2668 (void) strcpy(str, "Object is remote");
2670 case NFS3ERR_BADHANDLE:
2671 (void) strcpy(str, "Bad file handle");
2673 case NFS3ERR_NOT_SYNC:
2674 (void) strcpy(str, "Not sync write");
2676 case NFS3ERR_BAD_COOKIE:
2677 (void) strcpy(str, "Bad cookie");
2679 case NFS3ERR_NOTSUPP:
2680 (void) strcpy(str, "Operation not supported");
2682 case NFS3ERR_TOOSMALL:
2683 (void) strcpy(str, "Value too small");
2685 case NFS3ERR_SERVERFAULT:
2686 (void) strcpy(str, "Server fault");
2688 case NFS3ERR_BADTYPE:
2689 (void) strcpy(str, "Bad type");
2691 case NFS3ERR_JUKEBOX:
2692 (void) strcpy(str, "Jukebox");
2695 (void) sprintf(str, "Unknown status %d", status);