2 * $Id: bulkstat_unlink_test_modified.c,v 1.1 2007/10/03 16:23:57 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
6 * This is a modified version of bulkstat_unlink_test.c to reproduce a specific
7 * problem see pv 969192
10 #include <sys/types.h>
18 main(int argc, char *argv[])
30 struct xfs_fsop_bulkreq a;
31 struct xfs_bstat *ret;
33 char fname[MAXPATHLEN];
37 fprintf(stderr, "Usage: %s iterations nfiles stride dir\n", argv[0]);
38 fprintf(stderr, "Create dir with nfiles, unlink each stride'th file, sync, bulkstat\n");
42 iterations = atoi(argv[1]);
43 nfiles = atoi(argv[2]);
44 stride = atoi(argv[3]);
46 if (!nfiles || !iterations) {
47 fprintf(stderr, "Iterations and nfiles showld be non zero.\n");
51 inodelist = (ino_t *)malloc(nfiles * sizeof(ino_t));
52 genlist = (__u32 *)malloc(nfiles * sizeof(__u32));
53 ret = (struct xfs_bstat *)malloc(nfiles * sizeof(struct xfs_bstat));
55 for (k=0; k < iterations; k++) {
56 xfs_ino_t last_inode = 0;
60 printf("Iteration %d ... \n", k);
62 memset(inodelist, 0, nfiles * sizeof(ino_t));
63 memset(genlist, 0, nfiles * sizeof(__u32));
64 memset(ret, 0, nfiles * sizeof(struct xfs_bstat));
65 memset(&a, 0, sizeof(struct xfs_fsop_bulkreq));
66 a.lastip = (__u64 *)&last_inode;
71 if (mkdir(dirname, 0755) < 0) {
76 /* create nfiles and store their inode numbers in inodelist */
77 for (i=0; i < nfiles; i++) {
78 sprintf(fname, "%s/file%06d", dirname, i);
79 if ((fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0644)) < 0) {
83 write(fd, fname, sizeof(fname));
84 if (fstat(fd, &sbuf) < 0) {
88 inodelist[i] = sbuf.st_ino;
94 /* collect bs_gen for the nfiles files */
95 if ((fd = open(dirname, O_RDONLY)) < 0) {
102 if ((e = xfsctl(dirname, fd, XFS_IOC_FSBULKSTAT, &a)) < 0) {
103 perror("XFS_IOC_FSBULKSTAT1:");
110 for (i=0; i < count; i++) {
111 for (j=0; j < nfiles; j += stride) {
112 if (ret[i].bs_ino == inodelist[j]) {
113 genlist[j] = ret[i].bs_gen;
121 printf("testFiles %d ... \n", testFiles);
123 /* remove some of the first set of files */
124 for (i=0; i < nfiles; i += stride) {
125 sprintf(fname, "%s/file%06d", dirname, i);
126 if (unlink(fname) < 0) {
132 /* create a new set of files (replacing the unlinked ones) */
133 for (i=0; i < nfiles; i += stride) {
134 sprintf(fname, "%s/file%06d", dirname, i);
135 if ((fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0644)) < 0) {
139 write(fd, fname, sizeof(fname));
144 last_inode = 0; count = 0;
146 if ((fd = open(dirname, O_RDONLY)) < 0) {
152 if ((e = xfsctl(dirname, fd, XFS_IOC_FSBULKSTAT, &a)) < 0) {
153 perror("XFS_IOC_FSBULKSTAT:");
160 for (i=0; i < count; i++) {
161 for (j=0; j < nfiles; j += stride) {
162 if ((ret[i].bs_ino == inodelist[j]) &&
163 (ret[i].bs_gen == genlist[j])) {
164 /* oops, the same inode with old gen number */
165 printf("Unlinked inode %llu with generation %d "
166 "returned by bulkstat\n",
167 (unsigned long long)inodelist[j],
171 if (ret[i].bs_ino == inodelist[j] &&
172 ret[i].bs_gen != genlist[j] + 1) {
173 /* oops, the new gen number is not 1 bigger than the old */
174 printf("Inode with old generation %d, new generation %d\n",
175 genlist[j], ret[i].bs_gen);
184 sprintf(fname, "rm -rf %s\n", dirname);