fsx: increase number of logged operations
[xfstests-dev.git] / src / bulkstat_unlink_test.c
1 /*
2  * $Id: bulkstat_unlink_test.c,v 1.3 2007/10/30 03:07:42 mohamedb.longdrop.melbourne.sgi.com Exp $
3  * Test bulkstat doesn't returned unlinked inodes.
4  * Mark Goodwin <markgw@sgi.com> Fri Jul 20 09:13:57 EST 2007
5  */
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include <xfs/xfs.h>
10 #include <unistd.h>
11 #include <getopt.h>
12
13 int
14 main(int argc, char *argv[])
15 {
16         int e;
17         int i;
18         int j;
19         int k;
20         int nfiles;
21         int stride;
22
23         int c;
24
25         struct stat sbuf;
26         ino_t *inodelist;
27         xfs_fsop_bulkreq_t a;
28         xfs_bstat_t *ret;
29         int iterations;
30         char fname[MAXPATHLEN];
31         char *dirname;
32         int chknb = 0;
33
34         while ((c = getopt(argc, argv, "r")) != -1) {
35                 switch(c) {
36                 case 'r':
37                         chknb = 1;
38                         break;
39                 default:
40                         break;
41                 }
42         }
43
44         if ((argc - optind) != 4) {
45                 fprintf(stderr, "Usage: %s iterations nfiles stride dir [options]\n", argv[0]);
46                 fprintf(stderr, "Create dir with nfiles, unlink each stride'th file, sync, bulkstat\n");
47                 exit(1);
48         }
49
50
51         iterations = atoi(argv[optind++]);
52         nfiles     = atoi(argv[optind++]);
53         stride     = atoi(argv[optind++]);
54
55         dirname = argv[optind++];
56
57         if (chknb)
58                 printf("Runing extended checks.\n");
59
60         inodelist = (ino_t *)malloc(nfiles * sizeof(ino_t));
61         ret = (xfs_bstat_t *)malloc(nfiles * sizeof(xfs_bstat_t));
62
63         for (k=0; k < iterations; k++) {
64                 int fd[nfiles + 1];
65                 xfs_ino_t last_inode = 0;
66                 int count = 0, scount = -1;
67
68                 printf("Iteration %d ... (%d files)", k, nfiles);
69
70                 memset(&a, 0, sizeof(xfs_fsop_bulkreq_t));
71                 a.lastip = (__u64 *)&last_inode;
72                 a.icount = nfiles;
73                 a.ubuffer = ret;
74                 a.ocount = &count;
75
76                 if (mkdir(dirname, 0755) < 0) {
77                         printf("Warning (%s,%d), mkdir(%s) failed.\n", __FILE__, __LINE__, dirname);
78                         perror(dirname);
79                         exit(1);
80                 }
81
82                 if ((fd[nfiles] = open(dirname, O_RDONLY)) < 0) {
83                         printf("Warning (%s,%d), open(%s) failed.\n", __FILE__, __LINE__, dirname);
84                         perror(dirname);
85                         exit(1);
86                 }
87
88                 if (chknb) { /* Get the original number of inodes (lazy) */
89                         sync();
90                         if (xfsctl(dirname, fd[nfiles], XFS_IOC_FSBULKSTAT, &a) != 0) {
91                                 printf("Warning (%s:%d), xfsctl(XFS_IOC_FSBULKSTAT) FAILED.\n", __FILE__, __LINE__);
92                         }
93
94                         scount = count;
95                 }
96
97                 for (i=0; i < nfiles; i++) { /* Open the files */
98                         sprintf(fname, "%s/file%06d", dirname, i);
99                         if ((fd[i] = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0644)) < 0) {
100                                 printf("Warning (%s,%d), open(%s) failed.\n", __FILE__, __LINE__, fname);
101                                 perror(fname);
102                                 exit(1);
103                         }
104                         write(fd[i], fname, sizeof(fname));
105                         if (fstat(fd[i], &sbuf) < 0) {
106                                 printf("Warning (%s,%d), fstat failed.\n", __FILE__, __LINE__);
107                                 perror(fname);
108                                 exit(1);
109                         }
110                         inodelist[i] = sbuf.st_ino;
111                         unlink(fname);
112                 }
113
114                 if (chknb) {
115                         /*
116                          *The files are still opened (but unlink()ed) ,
117                          * we should have more inodes than before
118                          */
119                         sync();
120                         last_inode = 0;
121                         if (xfsctl(dirname, fd[nfiles], XFS_IOC_FSBULKSTAT, &a) != 0) {
122                                 printf("Warning (%s:%d), xfsctl(XFS_IOC_FSBULKSTAT) FAILED.\n", __FILE__, __LINE__);
123                         }
124                         if (count < scount) {
125                                 printf("ERROR, count(%d) < scount(%d).\n", count, scount);
126                                 return -1;
127                         }
128                 }
129
130                 /* Close all the files */
131                 for (i = 0; i < nfiles; i++) {
132                         close(fd[i]);
133                 }
134
135                 if (chknb) {
136                         /*
137                          * The files are now closed, we should be back to our,
138                          * previous inode count
139                          */
140                         sync();
141                         last_inode = 0;
142                         if (xfsctl(dirname, fd[nfiles], XFS_IOC_FSBULKSTAT, &a) != 0) {
143                                 printf("Warning (%s:%d), xfsctl(XFS_IOC_FSBULKSTAT) FAILED.\n", __FILE__, __LINE__);
144                         }
145                         if (count != scount) {
146                                 printf("ERROR, count(%d) != scount(%d).\n", count, scount);
147                                 return -1;
148                         }
149                 }
150
151                 sync();
152                 last_inode = 0;
153                 for (;;) {
154                         if ((e = xfsctl(dirname, fd[nfiles], XFS_IOC_FSBULKSTAT, &a)) < 0) {
155                                 printf("Warning (%s,%d), xfsctl failed.\n", __FILE__, __LINE__);
156                                 perror("XFS_IOC_FSBULKSTAT:");
157                                 exit(1);
158                         }
159
160                         if (count == 0)
161                                 break;
162
163                         for (i=0; i < count; i++) {
164                                 for (j=0; j < nfiles; j += stride) {
165                                         if (ret[i].bs_ino == inodelist[j]) {
166                                                 /* oops ... */
167                                                 printf("failed. Unlinked inode %llu returned by bulkstat\n", (unsigned long long)inodelist[j]);
168                                                 exit(1);
169                                         }
170                                 }
171                         }
172                 }
173
174                 close(fd[nfiles]);
175                 sprintf(fname, "rm -rf %s\n", dirname);
176                 system(fname);
177
178                 sync();
179                 sleep(2);
180                 printf("passed\n");
181         }
182
183         exit(0);
184 }