2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
28 * For further information regarding this notice, see:
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
33 * $DragonFly: src/test/stress/fsstress/fsstress.c,v 1.2 2008/06/05 18:06:33 swildner Exp $
38 #define XFS_ERRTAG_MAX 17
80 typedef void (*opfnc_t
)(int, long);
82 typedef struct opdesc
{
96 typedef struct flist
{
103 typedef struct pathname
{
109 #define FT_DIRm (1 << FT_DIR)
111 #define FT_REGm (1 << FT_REG)
113 #define FT_SYMm (1 << FT_SYM)
115 #define FT_DEVm (1 << FT_DEV)
117 #define FT_RTFm (1 << FT_RTF)
119 #define FT_ANYm ((1 << FT_nft) - 1)
120 #define FT_REGFILE (FT_REGm | FT_RTFm)
121 #define FT_NOTDIR (FT_ANYm & ~FT_DIRm)
123 #define FLIST_SLOT_INCR 16
126 #define MAXFSIZE ((1ULL << 63) - 1ULL)
127 #define MAXFSIZE32 ((1ULL << 40) - 1ULL)
129 void allocsp_f(int, long);
130 void attr_remove_f(int, long);
131 void attr_set_f(int, long);
132 void bulkstat_f(int, long);
133 void bulkstat1_f(int, long);
134 void chown_f(int, long);
135 void creat_f(int, long);
136 void dread_f(int, long);
137 void dwrite_f(int, long);
138 void fdatasync_f(int, long);
139 void freesp_f(int, long);
140 void fsync_f(int, long);
141 void getdents_f(int, long);
142 void link_f(int, long);
143 void mkdir_f(int, long);
144 void mknod_f(int, long);
145 void read_f(int, long);
146 void readlink_f(int, long);
147 void rename_f(int, long);
148 void resvsp_f(int, long);
149 void rmdir_f(int, long);
150 void stat_f(int, long);
151 void symlink_f(int, long);
152 void sync_f(int, long);
153 void truncate_f(int, long);
154 void unlink_f(int, long);
155 void unresvsp_f(int, long);
156 void write_f(int, long);
160 { OP_ALLOCSP
, "allocsp", allocsp_f
, 1, 1, 1 },
161 { OP_ATTR_REMOVE
, "attr_remove", attr_remove_f
, /* 1 */ 0, 1, 1 },
162 { OP_ATTR_SET
, "attr_set", attr_set_f
, /* 2 */ 0, 1, 1 },
163 { OP_BULKSTAT
, "bulkstat", bulkstat_f
, 1, 0, 1 },
164 { OP_BULKSTAT1
, "bulkstat1", bulkstat1_f
, 1, 0, 1 },
166 { OP_CHOWN
, "chown", chown_f
, 3, 1 },
167 { OP_CREAT
, "creat", creat_f
, 4, 1 },
168 { OP_DREAD
, "dread", dread_f
, 4, 0 },
169 { OP_DWRITE
, "dwrite", dwrite_f
, 4, 1 },
170 { OP_FDATASYNC
, "fdatasync", fdatasync_f
, 1, 1 },
172 { OP_FREESP
, "freesp", freesp_f
, 1, 1, 1 },
174 { OP_FSYNC
, "fsync", fsync_f
, 1, 1 },
175 { OP_GETDENTS
, "getdents", getdents_f
, 1, 0 },
176 { OP_LINK
, "link", link_f
, 1, 1 },
177 { OP_MKDIR
, "mkdir", mkdir_f
, 2, 1 },
178 { OP_MKNOD
, "mknod", mknod_f
, 2, 1 },
179 { OP_READ
, "read", read_f
, 1, 0 },
180 { OP_READLINK
, "readlink", readlink_f
, 1, 0 },
181 { OP_RENAME
, "rename", rename_f
, 2, 1 },
183 { OP_RESVSP
, "resvsp", resvsp_f
, 1, 1, 1 },
185 { OP_RMDIR
, "rmdir", rmdir_f
, 1, 1 },
186 { OP_STAT
, "stat", stat_f
, 1, 0 },
187 { OP_SYMLINK
, "symlink", symlink_f
, 2, 1 },
188 { OP_SYNC
, "sync", sync_f
, 1, 0 },
189 { OP_TRUNCATE
, "truncate", truncate_f
, 2, 1 },
190 { OP_UNLINK
, "unlink", unlink_f
, 1, 1 },
192 { OP_UNRESVSP
, "unresvsp", unresvsp_f
, 1, 1, 1 },
194 { OP_WRITE
, "write", write_f
, 4, 1 },
197 flist_t flist
[FT_nft
] = {
211 xfs_fsop_geom_t geom
;
225 unsigned long seed
= 0;
234 void add_to_flist(int, int, int);
235 void append_pathname(pathname_t
*, char *);
237 int attr_list_path(pathname_t
*, char *, const int, int,
238 attrlist_cursor_t
*);
239 int attr_remove_path(pathname_t
*, const char *, int);
240 int attr_set_path(pathname_t
*, const char *, const char *, const int, int);
242 void check_cwd(void);
243 int creat_path(pathname_t
*, mode_t
);
244 void dcache_enter(int, int);
245 void dcache_init(void);
246 fent_t
*dcache_lookup(int);
247 void dcache_purge(int);
248 void del_from_flist(int, int);
249 int dirid_to_name(char *, int);
251 void fent_to_name(pathname_t
*, flist_t
*, fent_t
*);
252 void fix_parent(int, int);
253 void free_pathname(pathname_t
*);
254 int generate_fname(fent_t
*, int, pathname_t
*, int *, int *);
255 int get_fname(int, long, pathname_t
*, flist_t
**, fent_t
**, int *);
256 void init_pathname(pathname_t
*);
257 int lchown_path(pathname_t
*, uid_t
, gid_t
);
258 int link_path(pathname_t
*, pathname_t
*);
259 int lstat64_path(pathname_t
*, struct stat64
*);
260 void make_freq_table(void);
261 int mkdir_path(pathname_t
*, mode_t
);
262 int mknod_path(pathname_t
*, mode_t
, dev_t
);
263 void namerandpad(int, char *, int);
264 int open_path(pathname_t
*, int);
265 DIR *opendir_path(pathname_t
*);
266 void process_freq(char *);
267 int readlink_path(pathname_t
*, char *, size_t);
268 int rename_path(pathname_t
*, pathname_t
*);
269 int rmdir_path(pathname_t
*);
270 void separate_pathname(pathname_t
*, char *, pathname_t
*);
271 void show_ops(int, char *);
272 int stat64_path(pathname_t
*, struct stat64
*);
273 int symlink_path(const char *, pathname_t
*);
274 int truncate64_path(pathname_t
*, off64_t
);
275 int unlink_path(pathname_t
*);
277 void write_freq(void);
278 void zero_freq(void);
280 int main(int argc
, char **argv
)
284 char *dirname
= NULL
;
296 xfs_error_injection_t err_inj
;
299 errrange
= errtag
= 0;
301 nops
= sizeof(ops
) / sizeof(ops
[0]);
302 ops_end
= &ops
[nops
];
304 while ((c
= getopt(argc
, argv
, "d:e:f:i:n:p:rs:vwzHSX")) != -1) {
310 sscanf(optarg
, "%d", &errtag
);
314 } else if (errtag
== 0)
316 if (errtag
>= XFS_ERRTAG_MAX
) {
318 "error tag %d too large (max %d)\n",
319 errtag
, XFS_ERRTAG_MAX
- 1);
324 process_freq(optarg
);
327 ilist
= realloc(ilist
, ++ilistlen
* sizeof(*ilist
));
328 ilist
[ilistlen
- 1] = strtol(optarg
, &p
, 16);
331 operations
= atoi(optarg
);
334 nproc
= atoi(optarg
);
340 seed
= strtoul(optarg
, NULL
, 0);
357 fprintf(stderr
, "%s - invalid parameters\n",
369 if (no_xfs
&& errtag
) {
370 fprintf(stderr
, "error injection only works on XFS\n");
376 for (i
= 0; ops
+i
< ops_end
; ++i
) {
383 /* no directory specified */
384 if (!nousage
) usage();
388 (void)mkdir(dirname
, 0777);
389 if (chdir(dirname
) < 0) {
393 sprintf(buf
, "fss%x", getpid());
394 fd
= creat(buf
, 0666);
395 if (lseek64(fd
, (off64_t
)(MAXFSIZE32
+ 1ULL), SEEK_SET
) < 0)
396 maxfsize
= (off64_t
)MAXFSIZE32
;
398 maxfsize
= (off64_t
)MAXFSIZE
;
403 gettimeofday(&t
, NULL
);
404 seed
= (int)t
.tv_sec
^ (int)t
.tv_usec
;
405 printf("seed = %ld\n", seed
);
409 i
= ioctl(fd
, XFS_IOC_FSGEOMETRY
, &geom
);
410 if (i
>= 0 && geom
.rtblocks
)
411 rtpct
= MIN(MAX(geom
.rtblocks
* 100 /
412 (geom
.rtblocks
+ geom
.datablocks
), 1), 99);
422 for (i
= 0; i
< j
; i
++)
425 errtag
= (random() % (XFS_ERRTAG_MAX
-1)) + 1;
431 for (i
= 0; i
< j
; i
++)
434 errtag
+= (random() % (XFS_ERRTAG_MAX
- errtag
));
436 printf("Injecting failure on tag #%d\n", errtag
);
437 err_inj
.errtag
= errtag
;
439 srval
= ioctl(fd
, XFS_IOC_ERROR_INJECTION
, &err_inj
);
441 perror("fsstress - XFS_SYSSGI error injection call");
454 for (i
= 0; i
< nproc
; i
++) {
461 while (wait(&stat
) > 0)
468 if((srval
= ioctl(fd
, XFS_IOC_ERROR_CLEARALL
, &err_inj
)) != 0) {
469 fprintf(stderr
, "Bad ej clear on %d (%d).\n", fd
, errno
);
470 perror("fsstress - XFS_SYSSGI clear error injection call");
482 add_to_flist(int ft
, int id
, int parent
)
488 if (ftp
->nfiles
== ftp
->nslots
) {
489 ftp
->nslots
+= FLIST_SLOT_INCR
;
490 ftp
->fents
= realloc(ftp
->fents
, ftp
->nslots
* sizeof(fent_t
));
492 fep
= &ftp
->fents
[ftp
->nfiles
++];
494 fep
->parent
= parent
;
498 append_pathname(pathname_t
*name
, char *str
)
504 if (len
&& *str
== '/' && name
->len
== 0) {
505 fprintf(stderr
, "fsstress: append_pathname failure\n");
511 name
->path
= realloc(name
->path
, name
->len
+ 1 + len
);
512 strcpy(&name
->path
[name
->len
], str
);
518 attr_list_path(pathname_t
*name
, char *buffer
, const int buffersize
, int flags
,
519 attrlist_cursor_t
*cursor
)
521 char buf
[MAXNAMELEN
];
525 rval
= attr_list(name
->path
, buffer
, buffersize
, flags
, cursor
);
526 if (rval
>= 0 || errno
!= ENAMETOOLONG
)
528 separate_pathname(name
, buf
, &newname
);
529 if (chdir(buf
) == 0) {
530 rval
= attr_list_path(&newname
, buffer
, buffersize
, flags
,
534 free_pathname(&newname
);
539 attr_remove_path(pathname_t
*name
, const char *attrname
, int flags
)
541 char buf
[MAXNAMELEN
];
545 rval
= attr_remove(name
->path
, attrname
, flags
);
546 if (rval
>= 0 || errno
!= ENAMETOOLONG
)
548 separate_pathname(name
, buf
, &newname
);
549 if (chdir(buf
) == 0) {
550 rval
= attr_remove_path(&newname
, attrname
, flags
);
553 free_pathname(&newname
);
558 attr_set_path(pathname_t
*name
, const char *attrname
, const char *attrvalue
,
559 const int valuelength
, int flags
)
561 char buf
[MAXNAMELEN
];
565 rval
= attr_set(name
->path
, attrname
, attrvalue
, valuelength
, flags
);
566 if (rval
>= 0 || errno
!= ENAMETOOLONG
)
568 separate_pathname(name
, buf
, &newname
);
569 if (chdir(buf
) == 0) {
570 rval
= attr_set_path(&newname
, attrname
, attrvalue
, valuelength
,
574 free_pathname(&newname
);
583 struct stat64 statbuf
;
585 if (stat64(".", &statbuf
) == 0 && statbuf
.st_ino
== top_ino
)
588 fprintf(stderr
, "fsstress: check_cwd failure\n");
595 creat_path(pathname_t
*name
, mode_t mode
)
597 char buf
[MAXNAMELEN
];
601 rval
= creat(name
->path
, mode
);
602 if (rval
>= 0 || errno
!= ENAMETOOLONG
)
604 separate_pathname(name
, buf
, &newname
);
605 if (chdir(buf
) == 0) {
606 rval
= creat_path(&newname
, mode
);
609 free_pathname(&newname
);
614 dcache_enter(int dirid
, int slot
)
616 dcache
[dirid
% NDCACHE
] = slot
;
624 for (i
= 0; i
< NDCACHE
; i
++)
629 dcache_lookup(int dirid
)
634 i
= dcache
[dirid
% NDCACHE
];
635 if (i
>= 0 && (fep
= &flist
[FT_DIR
].fents
[i
])->id
== dirid
)
641 dcache_purge(int dirid
)
645 dcp
= &dcache
[dirid
% NDCACHE
];
646 if (*dcp
>= 0 && flist
[FT_DIR
].fents
[*dcp
].id
== dirid
)
651 del_from_flist(int ft
, int slot
)
657 dcache_purge(ftp
->fents
[slot
].id
);
658 if (slot
!= ftp
->nfiles
- 1) {
660 dcache_purge(ftp
->fents
[ftp
->nfiles
- 1].id
);
661 ftp
->fents
[slot
] = ftp
->fents
[--ftp
->nfiles
];
667 dirid_to_fent(int dirid
)
673 if ((fep
= dcache_lookup(dirid
)))
675 flp
= &flist
[FT_DIR
];
676 for (fep
= flp
->fents
, efep
= &fep
[flp
->nfiles
]; fep
< efep
; fep
++) {
677 if (fep
->id
== dirid
) {
678 dcache_enter(dirid
, fep
- flp
->fents
);
688 struct stat64 statbuf
;
694 sprintf(buf
, "p%x", procid
);
695 (void)mkdir(buf
, 0777);
696 if (chdir(buf
) < 0 || stat64(".", &statbuf
) < 0) {
700 top_ino
= statbuf
.st_ino
;
701 homedir
= getcwd(NULL
, -1);
706 for (opno
= 0; opno
< operations
; opno
++) {
707 p
= &ops
[freq_table
[random() % freq_table_size
]];
708 if ((unsigned long)p
->func
< 4096) abort();
711 p
->func(opno
, random());
713 * test for forced shutdown by stat'ing the test
714 * directory. If this stat returns EIO, assume
715 * the forced shutdown happened.
717 if (errtag
!= 0 && opno
% 100 == 0) {
718 rval
= stat64(".", &statbuf
);
720 fprintf(stderr
, "Detected EIO\n");
728 fent_to_name(pathname_t
*name
, flist_t
*flp
, fent_t
*fep
)
730 char buf
[MAXNAMELEN
];
736 if (fep
->parent
!= -1) {
737 pfep
= dirid_to_fent(fep
->parent
);
738 fent_to_name(name
, &flist
[FT_DIR
], pfep
);
739 append_pathname(name
, "/");
741 i
= sprintf(buf
, "%c%x", flp
->tag
, fep
->id
);
742 namerandpad(fep
->id
, buf
, i
);
743 append_pathname(name
, buf
);
747 fix_parent(int oldid
, int newid
)
754 for (i
= 0, flp
= flist
; i
< FT_nft
; i
++, flp
++) {
755 for (j
= 0, fep
= flp
->fents
; j
< flp
->nfiles
; j
++, fep
++) {
756 if (fep
->parent
== oldid
)
763 free_pathname(pathname_t
*name
)
773 generate_fname(fent_t
*fep
, int ft
, pathname_t
*name
, int *idp
, int *v
)
775 char buf
[MAXNAMELEN
];
782 len
= sprintf(buf
, "%c%x", flp
->tag
, id
= nameseq
++);
783 namerandpad(id
, buf
, len
);
785 fent_to_name(name
, &flist
[FT_DIR
], fep
);
786 append_pathname(name
, "/");
788 append_pathname(name
, buf
);
791 for (j
= 0; !*v
&& j
< ilistlen
; j
++) {
792 if (ilist
[j
] == id
) {
801 get_fname(int which
, long r
, pathname_t
*name
, flist_t
**flpp
, fent_t
**fepp
,
811 for (i
= 0, c
= 0, flp
= flist
; i
< FT_nft
; i
++, flp
++) {
812 if (which
& (1 << i
))
824 for (i
= 0, c
= 0, flp
= flist
; i
< FT_nft
; i
++, flp
++) {
825 if (which
& (1 << i
)) {
826 if (x
< c
+ flp
->nfiles
) {
827 fep
= &flp
->fents
[x
- c
];
829 fent_to_name(name
, flp
, fep
);
835 for (j
= 0; !*v
&& j
< ilistlen
; j
++) {
836 if (ilist
[j
] == fep
->id
) {
847 fprintf(stderr
, "fsstress: get_fname failure\n");
855 init_pathname(pathname_t
*name
)
862 lchown_path(pathname_t
*name
, uid_t owner
, gid_t group
)
864 char buf
[MAXNAMELEN
];
868 rval
= lchown(name
->path
, owner
, group
);
869 if (rval
>= 0 || errno
!= ENAMETOOLONG
)
871 separate_pathname(name
, buf
, &newname
);
872 if (chdir(buf
) == 0) {
873 rval
= lchown_path(&newname
, owner
, group
);
876 free_pathname(&newname
);
881 link_path(pathname_t
*name1
, pathname_t
*name2
)
883 char buf1
[MAXNAMELEN
];
884 char buf2
[MAXNAMELEN
];
890 rval
= link(name1
->path
, name2
->path
);
891 if (rval
>= 0 || errno
!= ENAMETOOLONG
)
893 separate_pathname(name1
, buf1
, &newname1
);
894 separate_pathname(name2
, buf2
, &newname2
);
895 if (strcmp(buf1
, buf2
) == 0) {
896 if (chdir(buf1
) == 0) {
897 rval
= link_path(&newname1
, &newname2
);
901 if (strcmp(buf1
, "..") == 0)
903 else if (strcmp(buf2
, "..") == 0)
905 else if (strlen(buf1
) == 0)
907 else if (strlen(buf2
) == 0)
910 down1
= MAX(newname1
.len
, 3 + name2
->len
) <=
911 MAX(3 + name1
->len
, newname2
.len
);
913 free_pathname(&newname2
);
914 append_pathname(&newname2
, "../");
915 append_pathname(&newname2
, name2
->path
);
916 if (chdir(buf1
) == 0) {
917 rval
= link_path(&newname1
, &newname2
);
921 free_pathname(&newname1
);
922 append_pathname(&newname1
, "../");
923 append_pathname(&newname1
, name1
->path
);
924 if (chdir(buf2
) == 0) {
925 rval
= link_path(&newname1
, &newname2
);
930 free_pathname(&newname1
);
931 free_pathname(&newname2
);
936 lstat64_path(pathname_t
*name
, struct stat64
*sbuf
)
938 char buf
[MAXNAMELEN
];
942 rval
= lstat64(name
->path
, sbuf
);
943 if (rval
>= 0 || errno
!= ENAMETOOLONG
)
945 separate_pathname(name
, buf
, &newname
);
946 if (chdir(buf
) == 0) {
947 rval
= lstat64_path(&newname
, sbuf
);
950 free_pathname(&newname
);
955 make_freq_table(void)
961 for (p
= ops
, f
= 0; p
< ops_end
; p
++)
963 freq_table
= malloc(f
* sizeof(*freq_table
));
965 for (p
= ops
, i
= 0; p
< ops_end
; p
++) {
966 for (f
= 0; f
< p
->freq
; f
++, i
++)
967 freq_table
[i
] = p
->op
;
972 mkdir_path(pathname_t
*name
, mode_t mode
)
974 char buf
[MAXNAMELEN
];
978 rval
= mkdir(name
->path
, mode
);
979 if (rval
>= 0 || errno
!= ENAMETOOLONG
)
981 separate_pathname(name
, buf
, &newname
);
982 if (chdir(buf
) == 0) {
983 rval
= mkdir_path(&newname
, mode
);
986 free_pathname(&newname
);
991 mknod_path(pathname_t
*name
, mode_t mode
, dev_t dev
)
993 char buf
[MAXNAMELEN
];
997 rval
= mknod(name
->path
, mode
, dev
);
998 if (rval
>= 0 || errno
!= ENAMETOOLONG
)
1000 separate_pathname(name
, buf
, &newname
);
1001 if (chdir(buf
) == 0) {
1002 rval
= mknod_path(&newname
, mode
, dev
);
1005 free_pathname(&newname
);
1010 namerandpad(int id
, char *buf
, int i
)
1013 static int buckets
[] =
1014 { 2, 4, 8, 16, 32, 64, 128, MAXNAMELEN
- 1 };
1020 bucket
= (id
^ namerand
) % (sizeof(buckets
) / sizeof(buckets
[0]));
1021 padmod
= buckets
[bucket
] + 1 - i
;
1024 padlen
= (id
^ namerand
) % padmod
;
1026 memset(&buf
[i
], 'X', padlen
);
1027 buf
[i
+ padlen
] = '\0';
1032 open_path(pathname_t
*name
, int oflag
)
1034 char buf
[MAXNAMELEN
];
1038 rval
= open(name
->path
, oflag
);
1039 if (rval
>= 0 || errno
!= ENAMETOOLONG
)
1041 separate_pathname(name
, buf
, &newname
);
1042 if (chdir(buf
) == 0) {
1043 rval
= open_path(&newname
, oflag
);
1046 free_pathname(&newname
);
1051 opendir_path(pathname_t
*name
)
1053 char buf
[MAXNAMELEN
];
1057 rval
= opendir(name
->path
);
1058 if (rval
|| errno
!= ENAMETOOLONG
)
1060 separate_pathname(name
, buf
, &newname
);
1061 if (chdir(buf
) == 0) {
1062 rval
= opendir_path(&newname
);
1065 free_pathname(&newname
);
1070 process_freq(char *arg
)
1075 s
= strchr(arg
, '=');
1077 fprintf(stderr
, "bad argument '%s'\n", arg
);
1081 for (p
= ops
; p
< ops_end
; p
++) {
1082 if (strcmp(arg
, p
->name
) == 0) {
1087 fprintf(stderr
, "can't find op type %s for -f\n", arg
);
1092 readlink_path(pathname_t
*name
, char *lbuf
, size_t lbufsiz
)
1094 char buf
[MAXNAMELEN
];
1098 rval
= readlink(name
->path
, lbuf
, lbufsiz
);
1099 if (rval
>= 0 || errno
!= ENAMETOOLONG
)
1101 separate_pathname(name
, buf
, &newname
);
1102 if (chdir(buf
) == 0) {
1103 rval
= readlink_path(&newname
, lbuf
, lbufsiz
);
1106 free_pathname(&newname
);
1111 rename_path(pathname_t
*name1
, pathname_t
*name2
)
1113 char buf1
[MAXNAMELEN
];
1114 char buf2
[MAXNAMELEN
];
1116 pathname_t newname1
;
1117 pathname_t newname2
;
1120 rval
= rename(name1
->path
, name2
->path
);
1121 if (rval
>= 0 || errno
!= ENAMETOOLONG
)
1123 separate_pathname(name1
, buf1
, &newname1
);
1124 separate_pathname(name2
, buf2
, &newname2
);
1125 if (strcmp(buf1
, buf2
) == 0) {
1126 if (chdir(buf1
) == 0) {
1127 rval
= rename_path(&newname1
, &newname2
);
1131 if (strcmp(buf1
, "..") == 0)
1133 else if (strcmp(buf2
, "..") == 0)
1135 else if (strlen(buf1
) == 0)
1137 else if (strlen(buf2
) == 0)
1140 down1
= MAX(newname1
.len
, 3 + name2
->len
) <=
1141 MAX(3 + name1
->len
, newname2
.len
);
1143 free_pathname(&newname2
);
1144 append_pathname(&newname2
, "../");
1145 append_pathname(&newname2
, name2
->path
);
1146 if (chdir(buf1
) == 0) {
1147 rval
= rename_path(&newname1
, &newname2
);
1151 free_pathname(&newname1
);
1152 append_pathname(&newname1
, "../");
1153 append_pathname(&newname1
, name1
->path
);
1154 if (chdir(buf2
) == 0) {
1155 rval
= rename_path(&newname1
, &newname2
);
1160 free_pathname(&newname1
);
1161 free_pathname(&newname2
);
1166 rmdir_path(pathname_t
*name
)
1168 char buf
[MAXNAMELEN
];
1172 rval
= rmdir(name
->path
);
1173 if (rval
>= 0 || errno
!= ENAMETOOLONG
)
1175 separate_pathname(name
, buf
, &newname
);
1176 if (chdir(buf
) == 0) {
1177 rval
= rmdir_path(&newname
);
1180 free_pathname(&newname
);
1185 separate_pathname(pathname_t
*name
, char *buf
, pathname_t
*newname
)
1189 init_pathname(newname
);
1190 slash
= strchr(name
->path
, '/');
1191 if (slash
== NULL
) {
1196 strcpy(buf
, name
->path
);
1198 append_pathname(newname
, slash
+ 1);
1204 show_ops(int flag
, char *lead_str
)
1209 /* print in list form */
1212 for (p
= ops
; p
< ops_end
; p
++) {
1213 if (lead_str
!= NULL
&& x
+strlen(p
->name
)>=WIDTH
-5)
1214 x
=printf("%s%s", (p
==ops
)?"":"\n", lead_str
);
1215 x
+=printf("%s ", p
->name
);
1220 for (f
= 0, p
= ops
; p
< ops_end
; p
++)
1226 for (p
= ops
; p
< ops_end
; p
++) {
1227 if (flag
!= 0 || p
->freq
> 0) {
1228 if (lead_str
!= NULL
)
1229 printf("%s", lead_str
);
1230 printf("%20s %d/%d %s\n",
1231 p
->name
, p
->freq
, f
,
1232 (p
->iswrite
== 0) ? " " : "write op");
1239 stat64_path(pathname_t
*name
, struct stat64
*sbuf
)
1241 char buf
[MAXNAMELEN
];
1245 rval
= stat64(name
->path
, sbuf
);
1246 if (rval
>= 0 || errno
!= ENAMETOOLONG
)
1248 separate_pathname(name
, buf
, &newname
);
1249 if (chdir(buf
) == 0) {
1250 rval
= stat64_path(&newname
, sbuf
);
1253 free_pathname(&newname
);
1258 symlink_path(const char *name1
, pathname_t
*name
)
1260 char buf
[MAXNAMELEN
];
1264 if (!strcmp(name1
, name
->path
)) {
1265 printf("yikes! %s %s\n", name1
, name
->path
);
1269 rval
= symlink(name1
, name
->path
);
1270 if (rval
>= 0 || errno
!= ENAMETOOLONG
)
1272 separate_pathname(name
, buf
, &newname
);
1273 if (chdir(buf
) == 0) {
1274 rval
= symlink_path(name1
, &newname
);
1277 free_pathname(&newname
);
1282 truncate64_path(pathname_t
*name
, off64_t length
)
1284 char buf
[MAXNAMELEN
];
1288 rval
= truncate64(name
->path
, length
);
1289 if (rval
>= 0 || errno
!= ENAMETOOLONG
)
1291 separate_pathname(name
, buf
, &newname
);
1292 if (chdir(buf
) == 0) {
1293 rval
= truncate64_path(&newname
, length
);
1296 free_pathname(&newname
);
1301 unlink_path(pathname_t
*name
)
1303 char buf
[MAXNAMELEN
];
1307 rval
= unlink(name
->path
);
1308 if (rval
>= 0 || errno
!= ENAMETOOLONG
)
1310 separate_pathname(name
, buf
, &newname
);
1311 if (chdir(buf
) == 0) {
1312 rval
= unlink_path(&newname
);
1315 free_pathname(&newname
);
1322 printf("Usage: %s -H or\n", myprog
);
1323 printf(" %s [-d dir][-e errtg][-f op_name=freq][-n nops]\n",
1325 printf(" [-p nproc][-r len][-s seed][-v][-w][-z][-S]\n");
1327 printf(" -d dir specifies the base directory for operations\n");
1328 printf(" -e errtg specifies error injection stuff\n");
1329 printf(" -f op_name=freq changes the frequency of option name to freq\n");
1330 printf(" the valid operation names are:\n");
1332 printf(" -n nops specifies the no. of operations per process (default 1)\n");
1333 printf(" -p nproc specifies the no. of processes (default 1)\n");
1334 printf(" -r specifies random name padding\n");
1335 printf(" -s seed specifies the seed for the random generator (default random)\n");
1336 printf(" -v specifies verbose mode\n");
1337 printf(" -w zeros frequencies of non-write operations\n");
1338 printf(" -z zeros frequencies of all operations\n");
1339 printf(" -S prints the table of operations (omitting zero frequency)\n");
1340 printf(" -H prints usage and exits\n");
1341 printf(" -X don't do anything XFS specific (default with -DNO_XFS)\n");
1349 for (p
= ops
; p
< ops_end
; p
++) {
1360 for (p
= ops
; p
< ops_end
; p
++)
1367 allocsp_f(int opno
, long r
)
1379 if (!get_fname(FT_REGFILE
, r
, &f
, NULL
, NULL
, &v
)) {
1381 printf("%d/%d: allocsp - no filename\n", procid
, opno
);
1385 fd
= open_path(&f
, O_RDWR
);
1386 e
= fd
< 0 ? errno
: 0;
1390 printf("%d/%d: allocsp - open %s failed %d\n",
1391 procid
, opno
, f
.path
, e
);
1395 if (fstat64(fd
, &stb
) < 0) {
1397 printf("%d/%d: allocsp - fstat64 %s failed %d\n",
1398 procid
, opno
, f
.path
, errno
);
1403 lr
= ((__int64_t
)random() << 32) + random();
1404 off
= (off64_t
)(lr
% MIN(stb
.st_size
+ (1024 * 1024), MAXFSIZE
));
1406 fl
.l_whence
= SEEK_SET
;
1409 e
= ioctl(fd
, XFS_IOC_ALLOCSP64
, &fl
) < 0 ? errno
: 0;
1411 printf("%d/%d: ioctl(XFS_IOC_ALLOCSP64) %s %lld 0 %d\n",
1412 procid
, opno
, f
.path
, off
, e
);
1418 attr_remove_f(int opno
, long r
)
1420 attrlist_ent_t
*aep
;
1424 attrlist_cursor_t cursor
;
1433 if (!get_fname(FT_ANYm
, r
, &f
, NULL
, NULL
, &v
))
1434 append_pathname(&f
, ".");
1436 bzero(&cursor
, sizeof(cursor
));
1438 e
= attr_list_path(&f
, buf
, sizeof(buf
), ATTR_DONTFOLLOW
,
1443 alist
= (attrlist_t
*)buf
;
1444 total
+= alist
->al_count
;
1445 } while (alist
->al_more
);
1448 printf("%d/%d: attr_remove - no attrs for %s\n",
1449 procid
, opno
, f
.path
);
1453 which
= (int)(random() % total
);
1454 bzero(&cursor
, sizeof(cursor
));
1458 e
= attr_list_path(&f
, buf
, sizeof(buf
), ATTR_DONTFOLLOW
,
1463 alist
= (attrlist_t
*)buf
;
1464 if (which
< ent
+ alist
->al_count
) {
1465 aep
= (attrlist_ent_t
*)
1466 &buf
[alist
->al_offset
[which
- ent
]];
1467 aname
= aep
->a_name
;
1470 ent
+= alist
->al_count
;
1471 } while (alist
->al_more
);
1472 if (aname
== NULL
) {
1475 "%d/%d: attr_remove - name %d not found at %s\n",
1476 procid
, opno
, which
, f
.path
);
1480 e
= attr_remove_path(&f
, aname
, ATTR_DONTFOLLOW
) < 0 ? errno
: 0;
1483 printf("%d/%d: attr_remove %s %s %d\n",
1484 procid
, opno
, f
.path
, aname
, e
);
1489 attr_set_f(int opno
, long r
)
1496 static int lengths
[] = { 10, 100, 1000, 10000 };
1501 if (!get_fname(FT_ANYm
, r
, &f
, NULL
, NULL
, &v
))
1502 append_pathname(&f
, ".");
1503 sprintf(aname
, "a%x", nameseq
++);
1504 li
= (int)(random() % (sizeof(lengths
) / sizeof(lengths
[0])));
1505 len
= (int)(random() % lengths
[li
]);
1509 memset(aval
, nameseq
& 0xff, len
);
1510 e
= attr_set_path(&f
, aname
, aval
, len
, ATTR_DONTFOLLOW
) < 0 ?
1515 printf("%d/%d: attr_set %s %s %d\n", procid
, opno
, f
.path
,
1521 bulkstat_f(int opno
, long r
)
1529 xfs_fsop_bulkreq_t bsr
;
1532 nent
= (r
% 999) + 2;
1533 t
= malloc(nent
* sizeof(*t
));
1534 fd
= open(".", O_RDONLY
);
1542 while (ioctl(fd
, XFS_IOC_FSBULKSTAT
, &bsr
) == 0 && count
> 0)
1546 printf("%d/%d: bulkstat nent %d total %lld\n",
1547 procid
, opno
, nent
, total
);
1552 bulkstat1_f(int opno
, long r
)
1562 xfs_fsop_bulkreq_t bsr
;
1565 good
= random() & 1;
1567 /* use an inode we know exists */
1569 if (!get_fname(FT_ANYm
, r
, &f
, NULL
, NULL
, &v
))
1570 append_pathname(&f
, ".");
1571 ino
= stat64_path(&f
, &s
) < 0 ? (ino64_t
)r
: s
.st_ino
;
1576 * pick a random inode
1578 * note this can generate kernel warning messages
1579 * since bulkstat_one will read the disk block that
1580 * would contain a given inode even if that disk
1581 * block doesn't contain inodes.
1583 * this is detected later, but not until after the
1584 * warning is displayed.
1586 * "XFS: device 0x825- bad inode magic/vsn daddr 0x0 #0"
1592 fd
= open(".", O_RDONLY
);
1599 e
= ioctl(fd
, XFS_IOC_FSBULKSTAT_SINGLE
, &bsr
) < 0 ? errno
: 0;
1601 printf("%d/%d: bulkstat1 %s ino %lld %d\n",
1602 procid
, opno
, good
?"real":"random", (int64_t)ino
, e
);
1609 chown_f(int opno
, long r
)
1618 if (!get_fname(FT_ANYm
, r
, &f
, NULL
, NULL
, &v
))
1619 append_pathname(&f
, ".");
1620 u
= (uid_t
)random();
1621 nbits
= (int)(random() % 32);
1622 u
&= (1 << nbits
) - 1;
1623 e
= lchown_path(&f
, u
, -1) < 0 ? errno
: 0;
1626 printf("%d/%d: chown %s %d %d\n", procid
, opno
, f
.path
, u
, e
);
1631 creat_f(int opno
, long r
)
1646 if (!get_fname(FT_DIRm
, r
, NULL
, NULL
, &fep
, &v1
))
1651 type
= rtpct
? ((random() % 100) > rtpct
? FT_REG
: FT_RTF
) : FT_REG
;
1653 extsize
= (random() % 10) + 1;
1656 e
= generate_fname(fep
, type
, &f
, &id
, &v
);
1660 fent_to_name(&f
, &flist
[FT_DIR
], fep
);
1661 printf("%d/%d: creat - no filename from %s\n",
1662 procid
, opno
, f
.path
);
1667 fd
= creat_path(&f
, 0666);
1668 e
= fd
< 0 ? errno
: 0;
1675 if (extsize
&& ioctl(fd
, XFS_IOC_FSGETXATTR
, &a
) >= 0) {
1676 a
.fsx_xflags
|= XFS_XFLAG_REALTIME
;
1678 geom
.rtextsize
* geom
.blocksize
* extsize
;
1679 if (ioctl(fd
, XFS_IOC_FSSETXATTR
, &a
) < 0)
1681 esz
= a
.fsx_estsize
;
1684 add_to_flist(type
, id
, parid
);
1689 printf("%d/%d: creat %s x:%d %d %d\n", procid
, opno
, f
.path
,
1699 static int no_direct
;
1705 flags
= fcntl(fd
, F_GETFL
, 0);
1709 if (fcntl(fd
, F_SETFL
, flags
|O_DIRECT
) < 0) {
1714 printf("cannot set O_DIRECT: %s\n", strerror(errno
));
1722 dread_f(int opno
, long r
)
1726 struct dioattr diob
;
1737 if (!get_fname(FT_REGFILE
, r
, &f
, NULL
, NULL
, &v
)) {
1739 printf("%d/%d: dread - no filename\n", procid
, opno
);
1743 fd
= open_path(&f
, O_RDONLY
);
1745 if (!setdirect(fd
)) {
1749 e
= fd
< 0 ? errno
: 0;
1753 printf("%d/%d: dread - open %s failed %d\n",
1754 procid
, opno
, f
.path
, e
);
1758 if (fstat64(fd
, &stb
) < 0) {
1760 printf("%d/%d: dread - fstat64 %s failed %d\n",
1761 procid
, opno
, f
.path
, errno
);
1766 if (stb
.st_size
== 0) {
1768 printf("%d/%d: dread - %s zero size\n", procid
, opno
,
1776 diob
.d_miniosz
= stb
.st_blksize
;
1777 diob
.d_maxiosz
= stb
.st_blksize
* 256; /* good number ? */
1778 diob
.d_mem
= stb
.st_blksize
;
1781 else if (ioctl(fd
, XFS_IOC_DIOINFO
, &diob
) < 0) {
1784 "%d/%d: dread - ioctl(fd, XFS_IOC_DIOINFO) %s failed %d\n",
1785 procid
, opno
, f
.path
, errno
);
1791 align
= (__int64_t
)diob
.d_miniosz
;
1792 lr
= ((__int64_t
)random() << 32) + random();
1793 off
= (off64_t
)(lr
% stb
.st_size
);
1794 off
-= (off
% align
);
1795 lseek64(fd
, off
, SEEK_SET
);
1796 len
= (random() % (getpagesize() * 32)) + 1;
1797 len
-= (len
% align
);
1800 else if (len
> diob
.d_maxiosz
)
1801 len
= diob
.d_maxiosz
;
1802 buf
= memalign(diob
.d_mem
, len
);
1803 e
= read(fd
, buf
, len
) < 0 ? errno
: 0;
1806 printf("%d/%d: dread %s [%lld,%d] %d\n",
1807 procid
, opno
, f
.path
, off
, len
, e
);
1813 dwrite_f(int opno
, long r
)
1817 struct dioattr diob
;
1828 if (!get_fname(FT_REGFILE
, r
, &f
, NULL
, NULL
, &v
)) {
1830 printf("%d/%d: dwrite - no filename\n", procid
, opno
);
1834 fd
= open_path(&f
, O_WRONLY
);
1835 e
= fd
< 0 ? errno
: 0;
1839 printf("%d/%d: dwrite - open %s failed %d\n",
1840 procid
, opno
, f
.path
, e
);
1847 if (fstat64(fd
, &stb
) < 0) {
1849 printf("%d/%d: dwrite - fstat64 %s failed %d\n",
1850 procid
, opno
, f
.path
, errno
);
1856 diob
.d_miniosz
= stb
.st_blksize
;
1857 diob
.d_maxiosz
= stb
.st_blksize
* 256; /* good number ? */
1858 diob
.d_mem
= stb
.st_blksize
;
1861 else if (ioctl(fd
, XFS_IOC_DIOINFO
, &diob
) < 0) {
1864 "%d/%d: dwrite - ioctl(fd, XFS_IOC_DIOINFO) %s failed %d\n",
1865 procid
, opno
, f
.path
, errno
);
1871 align
= (__int64_t
)diob
.d_miniosz
;
1872 lr
= ((__int64_t
)random() << 32) + random();
1873 off
= (off64_t
)(lr
% MIN(stb
.st_size
+ (1024 * 1024), MAXFSIZE
));
1874 off
-= (off
% align
);
1875 lseek64(fd
, off
, SEEK_SET
);
1876 len
= (random() % (getpagesize() * 32)) + 1;
1877 len
-= (len
% align
);
1880 else if (len
> diob
.d_maxiosz
)
1881 len
= diob
.d_maxiosz
;
1882 buf
= memalign(diob
.d_mem
, len
);
1884 lseek64(fd
, off
, SEEK_SET
);
1885 memset(buf
, nameseq
& 0xff, len
);
1886 e
= write(fd
, buf
, len
) < 0 ? errno
: 0;
1889 printf("%d/%d: dwrite %s [%lld,%d] %d\n",
1890 procid
, opno
, f
.path
, off
, len
, e
);
1896 fdatasync_f(int opno
, long r
)
1904 if (!get_fname(FT_REGFILE
, r
, &f
, NULL
, NULL
, &v
)) {
1906 printf("%d/%d: fdatasync - no filename\n",
1911 fd
= open_path(&f
, O_WRONLY
);
1912 e
= fd
< 0 ? errno
: 0;
1916 printf("%d/%d: fdatasync - open %s failed %d\n",
1917 procid
, opno
, f
.path
, e
);
1921 e
= fdatasync(fd
) < 0 ? errno
: 0;
1923 printf("%d/%d: fdatasync %s %d\n", procid
, opno
, f
.path
, e
);
1930 freesp_f(int opno
, long r
)
1942 if (!get_fname(FT_REGFILE
, r
, &f
, NULL
, NULL
, &v
)) {
1944 printf("%d/%d: freesp - no filename\n", procid
, opno
);
1948 fd
= open_path(&f
, O_RDWR
);
1949 e
= fd
< 0 ? errno
: 0;
1953 printf("%d/%d: freesp - open %s failed %d\n",
1954 procid
, opno
, f
.path
, e
);
1958 if (fstat64(fd
, &stb
) < 0) {
1960 printf("%d/%d: freesp - fstat64 %s failed %d\n",
1961 procid
, opno
, f
.path
, errno
);
1966 lr
= ((__int64_t
)random() << 32) + random();
1967 off
= (off64_t
)(lr
% MIN(stb
.st_size
+ (1024 * 1024), MAXFSIZE
));
1969 fl
.l_whence
= SEEK_SET
;
1972 e
= ioctl(fd
, XFS_IOC_FREESP64
, &fl
) < 0 ? errno
: 0;
1974 printf("%d/%d: ioctl(XFS_IOC_FREESP64) %s %lld 0 %d\n",
1975 procid
, opno
, f
.path
, off
, e
);
1983 fsync_f(int opno
, long r
)
1991 if (!get_fname(FT_REGFILE
, r
, &f
, NULL
, NULL
, &v
)) {
1993 printf("%d/%d: fsync - no filename\n", procid
, opno
);
1997 fd
= open_path(&f
, O_WRONLY
);
1998 e
= fd
< 0 ? errno
: 0;
2002 printf("%d/%d: fsync - open %s failed %d\n",
2003 procid
, opno
, f
.path
, e
);
2007 e
= fsync(fd
) < 0 ? errno
: 0;
2009 printf("%d/%d: fsync %s %d\n", procid
, opno
, f
.path
, e
);
2015 getdents_f(int opno
, long r
)
2022 if (!get_fname(FT_DIRm
, r
, &f
, NULL
, NULL
, &v
))
2023 append_pathname(&f
, ".");
2024 dir
= opendir_path(&f
);
2028 printf("%d/%d: getdents - can't open %s\n",
2029 procid
, opno
, f
.path
);
2033 while (readdir64(dir
) != NULL
)
2036 printf("%d/%d: getdents %s 0\n", procid
, opno
, f
.path
);
2042 link_f(int opno
, long r
)
2055 if (!get_fname(FT_NOTDIR
, r
, &f
, &flp
, NULL
, &v1
)) {
2057 printf("%d/%d: link - no file\n", procid
, opno
);
2061 if (!get_fname(FT_DIRm
, random(), NULL
, NULL
, &fep
, &v
))
2067 e
= generate_fname(fep
, flp
- flist
, &l
, &id
, &v1
);
2071 fent_to_name(&l
, &flist
[FT_DIR
], fep
);
2072 printf("%d/%d: link - no filename from %s\n",
2073 procid
, opno
, l
.path
);
2079 e
= link_path(&f
, &l
) < 0 ? errno
: 0;
2082 add_to_flist(flp
- flist
, id
, parid
);
2084 printf("%d/%d: link %s %s %d\n", procid
, opno
, f
.path
, l
.path
,
2091 mkdir_f(int opno
, long r
)
2101 if (!get_fname(FT_DIRm
, r
, NULL
, NULL
, &fep
, &v
))
2106 e
= generate_fname(fep
, FT_DIR
, &f
, &id
, &v1
);
2110 fent_to_name(&f
, &flist
[FT_DIR
], fep
);
2111 printf("%d/%d: mkdir - no filename from %s\n",
2112 procid
, opno
, f
.path
);
2117 e
= mkdir_path(&f
, 0777) < 0 ? errno
: 0;
2120 add_to_flist(FT_DIR
, id
, parid
);
2122 printf("%d/%d: mkdir %s %d\n", procid
, opno
, f
.path
, e
);
2127 mknod_f(int opno
, long r
)
2137 if (!get_fname(FT_DIRm
, r
, NULL
, NULL
, &fep
, &v
))
2142 e
= generate_fname(fep
, FT_DEV
, &f
, &id
, &v1
);
2146 fent_to_name(&f
, &flist
[FT_DIR
], fep
);
2147 printf("%d/%d: mknod - no filename from %s\n",
2148 procid
, opno
, f
.path
);
2153 e
= mknod_path(&f
, S_IFCHR
|0444, 0) < 0 ? errno
: 0;
2156 add_to_flist(FT_DEV
, id
, parid
);
2158 printf("%d/%d: mknod %s %d\n", procid
, opno
, f
.path
, e
);
2163 read_f(int opno
, long r
)
2176 if (!get_fname(FT_REGFILE
, r
, &f
, NULL
, NULL
, &v
)) {
2178 printf("%d/%d: read - no filename\n", procid
, opno
);
2182 fd
= open_path(&f
, O_RDONLY
);
2183 e
= fd
< 0 ? errno
: 0;
2187 printf("%d/%d: read - open %s failed %d\n",
2188 procid
, opno
, f
.path
, e
);
2192 if (fstat64(fd
, &stb
) < 0) {
2194 printf("%d/%d: read - fstat64 %s failed %d\n",
2195 procid
, opno
, f
.path
, errno
);
2200 if (stb
.st_size
== 0) {
2202 printf("%d/%d: read - %s zero size\n", procid
, opno
,
2208 lr
= ((__int64_t
)random() << 32) + random();
2209 off
= (off64_t
)(lr
% stb
.st_size
);
2210 lseek64(fd
, off
, SEEK_SET
);
2211 len
= (random() % (getpagesize() * 32)) + 1;
2213 e
= read(fd
, buf
, len
) < 0 ? errno
: 0;
2216 printf("%d/%d: read %s [%lld,%d] %d\n",
2217 procid
, opno
, f
.path
, off
, len
, e
);
2223 readlink_f(int opno
, long r
)
2231 if (!get_fname(FT_SYMm
, r
, &f
, NULL
, NULL
, &v
)) {
2233 printf("%d/%d: readlink - no filename\n", procid
, opno
);
2237 e
= readlink_path(&f
, buf
, PATH_MAX
) < 0 ? errno
: 0;
2240 printf("%d/%d: readlink %s %d\n", procid
, opno
, f
.path
, e
);
2245 rename_f(int opno
, long r
)
2260 if (!get_fname(FT_ANYm
, r
, &f
, &flp
, &fep
, &v1
)) {
2262 printf("%d/%d: rename - no filename\n", procid
, opno
);
2266 if (!get_fname(FT_DIRm
, random(), NULL
, NULL
, &dfep
, &v
))
2271 init_pathname(&newf
);
2272 e
= generate_fname(dfep
, flp
- flist
, &newf
, &id
, &v1
);
2276 fent_to_name(&f
, &flist
[FT_DIR
], dfep
);
2277 printf("%d/%d: rename - no filename from %s\n",
2278 procid
, opno
, f
.path
);
2280 free_pathname(&newf
);
2284 e
= rename_path(&f
, &newf
) < 0 ? errno
: 0;
2287 if (flp
- flist
== FT_DIR
) {
2289 fix_parent(oldid
, id
);
2291 del_from_flist(flp
- flist
, fep
- flp
->fents
);
2292 add_to_flist(flp
- flist
, id
, parid
);
2295 printf("%d/%d: rename %s to %s %d\n", procid
, opno
, f
.path
,
2297 free_pathname(&newf
);
2303 resvsp_f(int opno
, long r
)
2315 if (!get_fname(FT_REGFILE
, r
, &f
, NULL
, NULL
, &v
)) {
2317 printf("%d/%d: resvsp - no filename\n", procid
, opno
);
2321 fd
= open_path(&f
, O_RDWR
);
2322 e
= fd
< 0 ? errno
: 0;
2326 printf("%d/%d: resvsp - open %s failed %d\n",
2327 procid
, opno
, f
.path
, e
);
2331 if (fstat64(fd
, &stb
) < 0) {
2333 printf("%d/%d: resvsp - fstat64 %s failed %d\n",
2334 procid
, opno
, f
.path
, errno
);
2339 lr
= ((__int64_t
)random() << 32) + random();
2340 off
= (off64_t
)(lr
% MIN(stb
.st_size
+ (1024 * 1024), MAXFSIZE
));
2342 fl
.l_whence
= SEEK_SET
;
2344 fl
.l_len
= (off64_t
)(random() % (1024 * 1024));
2345 e
= ioctl(fd
, XFS_IOC_RESVSP64
, &fl
) < 0 ? errno
: 0;
2347 printf("%d/%d: ioctl(XFS_IOC_RESVSP64) %s %lld %lld %d\n",
2348 procid
, opno
, f
.path
, off
, fl
.l_len
, e
);
2355 rmdir_f(int opno
, long r
)
2363 if (!get_fname(FT_DIRm
, r
, &f
, NULL
, &fep
, &v
)) {
2365 printf("%d/%d: rmdir - no directory\n", procid
, opno
);
2369 e
= rmdir_path(&f
) < 0 ? errno
: 0;
2372 del_from_flist(FT_DIR
, fep
- flist
[FT_DIR
].fents
);
2374 printf("%d/%d: rmdir %s %d\n", procid
, opno
, f
.path
, e
);
2379 stat_f(int opno
, long r
)
2387 if (!get_fname(FT_ANYm
, r
, &f
, NULL
, NULL
, &v
)) {
2389 printf("%d/%d: stat - no entries\n", procid
, opno
);
2393 e
= lstat64_path(&f
, &stb
) < 0 ? errno
: 0;
2396 printf("%d/%d: stat %s %d\n", procid
, opno
, f
.path
, e
);
2401 symlink_f(int opno
, long r
)
2414 if (!get_fname(FT_DIRm
, r
, NULL
, NULL
, &fep
, &v
))
2419 e
= generate_fname(fep
, FT_SYM
, &f
, &id
, &v1
);
2423 fent_to_name(&f
, &flist
[FT_DIR
], fep
);
2424 printf("%d/%d: symlink - no filename from %s\n",
2425 procid
, opno
, f
.path
);
2430 len
= (int)(random() % PATH_MAX
);
2431 val
= malloc(len
+ 1);
2433 memset(val
, 'x', len
);
2435 for (i
= 10; i
< len
- 1; i
+= 10)
2437 e
= symlink_path(val
, &f
) < 0 ? errno
: 0;
2440 add_to_flist(FT_SYM
, id
, parid
);
2443 printf("%d/%d: symlink %s %d\n", procid
, opno
, f
.path
, e
);
2449 sync_f(int opno
, long r
)
2453 printf("%d/%d: sync\n", procid
, opno
);
2457 truncate_f(int opno
, long r
)
2467 if (!get_fname(FT_REGFILE
, r
, &f
, NULL
, NULL
, &v
)) {
2469 printf("%d/%d: truncate - no filename\n", procid
, opno
);
2473 e
= stat64_path(&f
, &stb
) < 0 ? errno
: 0;
2477 printf("%d/%d: truncate - stat64 %s failed %d\n",
2478 procid
, opno
, f
.path
, e
);
2482 lr
= ((__int64_t
)random() << 32) + random();
2483 off
= (off64_t
)(lr
% MIN(stb
.st_size
+ (1024 * 1024), MAXFSIZE
));
2485 e
= truncate64_path(&f
, off
) < 0 ? errno
: 0;
2488 printf("%d/%d: truncate %s %lld %d\n", procid
, opno
, f
.path
,
2494 unlink_f(int opno
, long r
)
2503 if (!get_fname(FT_NOTDIR
, r
, &f
, &flp
, &fep
, &v
)) {
2505 printf("%d/%d: unlink - no file\n", procid
, opno
);
2509 e
= unlink_path(&f
) < 0 ? errno
: 0;
2512 del_from_flist(flp
- flist
, fep
- flp
->fents
);
2514 printf("%d/%d: unlink %s %d\n", procid
, opno
, f
.path
, e
);
2520 unresvsp_f(int opno
, long r
)
2532 if (!get_fname(FT_REGFILE
, r
, &f
, NULL
, NULL
, &v
)) {
2534 printf("%d/%d: unresvsp - no filename\n", procid
, opno
);
2538 fd
= open_path(&f
, O_RDWR
);
2539 e
= fd
< 0 ? errno
: 0;
2543 printf("%d/%d: unresvsp - open %s failed %d\n",
2544 procid
, opno
, f
.path
, e
);
2548 if (fstat64(fd
, &stb
) < 0) {
2550 printf("%d/%d: unresvsp - fstat64 %s failed %d\n",
2551 procid
, opno
, f
.path
, errno
);
2556 lr
= ((__int64_t
)random() << 32) + random();
2557 off
= (off64_t
)(lr
% MIN(stb
.st_size
+ (1024 * 1024), MAXFSIZE
));
2559 fl
.l_whence
= SEEK_SET
;
2561 fl
.l_len
= (off64_t
)(random() % (1 << 20));
2562 e
= ioctl(fd
, XFS_IOC_UNRESVSP64
, &fl
) < 0 ? errno
: 0;
2564 printf("%d/%d: ioctl(XFS_IOC_UNRESVSP64) %s %lld %lld %d\n",
2565 procid
, opno
, f
.path
, off
, fl
.l_len
, e
);
2572 write_f(int opno
, long r
)
2585 if (!get_fname(FT_REGm
, r
, &f
, NULL
, NULL
, &v
)) {
2587 printf("%d/%d: write - no filename\n", procid
, opno
);
2591 fd
= open_path(&f
, O_WRONLY
);
2592 e
= fd
< 0 ? errno
: 0;
2596 printf("%d/%d: write - open %s failed %d\n",
2597 procid
, opno
, f
.path
, e
);
2601 if (fstat64(fd
, &stb
) < 0) {
2603 printf("%d/%d: write - fstat64 %s failed %d\n",
2604 procid
, opno
, f
.path
, errno
);
2609 lr
= ((__int64_t
)random() << 32) + random();
2610 off
= (off64_t
)(lr
% MIN(stb
.st_size
+ (1024 * 1024), MAXFSIZE
));
2612 lseek64(fd
, off
, SEEK_SET
);
2613 len
= (random() % (getpagesize() * 32)) + 1;
2615 memset(buf
, nameseq
& 0xff, len
);
2616 e
= write(fd
, buf
, len
) < 0 ? errno
: 0;
2619 printf("%d/%d: write %s [%lld,%d] %d\n",
2620 procid
, opno
, f
.path
, off
, len
, e
);