xfs: Verify correctness of upgrading an fs to support large extent counters
[xfstests-dev.git] / src / unwritten_sync.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <sys/types.h>
4 #include <fcntl.h>
5 #include <errno.h>
6 #include <malloc.h>
7 #include <unistd.h>
8 #include <xfs/xfs.h>
9
10 /* test thanks to judith@sgi.com */
11
12 #define IO_SIZE 1048576
13
14 void
15 print_getbmapx(
16         const char      *pathname,
17         int             fd,
18         int64_t         start,
19         int64_t         limit);
20
21 int
22 main(int argc, char *argv[])
23 {
24         int i;
25         int fd;
26         char *buf;
27         struct dioattr dio;
28         xfs_flock64_t flock;
29         off_t offset;
30         char    *file;
31         int     loops;
32         char    *dio_env;
33
34         if(argc != 3) {
35                 fprintf(stderr, "%s <loops> <file>\n", argv[0]);
36                 exit(1);
37         }
38
39         errno = 0;
40         loops = strtoull(argv[1], NULL, 0);
41         if (errno) {
42                 perror("strtoull");
43                 exit(errno);
44         }
45         file = argv[2];
46
47         while (loops-- > 0) {
48                 sleep(1);
49                 fd = open(file, O_RDWR|O_CREAT|O_DIRECT, 0666);
50                 if (fd < 0) {
51                         perror("open");
52                         exit(1);
53                 }
54                 if (xfsctl(file, fd, XFS_IOC_DIOINFO, &dio) < 0) {
55                         perror("dioinfo");
56                         exit(1);
57                 }
58
59                 dio_env = getenv("XFS_DIO_MIN");
60                 if (dio_env)
61                         dio.d_mem = dio.d_miniosz = atoi(dio_env);
62
63                 if ((dio.d_miniosz > IO_SIZE) || (dio.d_maxiosz < IO_SIZE)) {
64                         fprintf(stderr, "Test won't work - iosize out of range"
65                                 " (dio.d_miniosz=%d, dio.d_maxiosz=%d)\n",
66                                 dio.d_miniosz, dio.d_maxiosz);
67
68                         exit(1);
69                 }
70                 buf = (char *)memalign(dio.d_mem , IO_SIZE);
71                 if (buf == NULL) {
72                         fprintf(stderr,"Can't get memory\n");
73                         exit(1);
74                 }
75                 memset(buf,'Z',IO_SIZE);
76                 offset = 0;
77
78                 flock.l_whence = 0;
79                 flock.l_start= 0;
80                 flock.l_len = IO_SIZE*21;
81                 if (xfsctl(file, fd, XFS_IOC_RESVSP64, &flock) < 0) {
82                         perror("xfsctl ");
83                         exit(1);
84                 }
85                 for (i = 0; i < 21; i++) {
86                         if (pwrite(fd, buf, IO_SIZE, offset) != IO_SIZE) {
87                                 perror("pwrite");
88                                 exit(1);
89                         }
90                         offset += IO_SIZE;
91                 }
92
93                 print_getbmapx(file, fd, 0, 0);
94
95                 if (ftruncate(fd, 0)) {
96                         perror("ftruncate");
97                         exit(1);
98                 }
99
100                 print_getbmapx(file, fd, 0, 0);
101                 close(fd);
102         }
103         exit(0);
104 }
105
106 void
107 print_getbmapx(
108 const   char    *pathname,
109         int     fd,
110         int64_t start,
111         int64_t limit)
112 {
113         struct getbmapx bmapx[50];
114         int array_size = sizeof(bmapx) / sizeof(bmapx[0]);
115         int x;
116         int foundone = 0;
117         int foundany = 0;
118
119 again:
120         foundone = 0;
121         memset(bmapx, '\0', sizeof(bmapx));
122
123         bmapx[0].bmv_offset = start;
124         bmapx[0].bmv_length = -1; /* limit - start; */
125         bmapx[0].bmv_count = array_size;
126         bmapx[0].bmv_entries = 0;       /* no entries filled in yet */
127
128         bmapx[0].bmv_iflags = BMV_IF_PREALLOC;
129
130         x = array_size;
131         for (;;) {
132                 if (x > bmapx[0].bmv_entries) {
133                         if (x != array_size) {
134                                 break;  /* end of file */
135                         }
136                         if (xfsctl(pathname, fd, XFS_IOC_GETBMAPX, bmapx) < 0) {
137                                 fprintf(stderr, "XFS_IOC_GETBMAPX failed\n");
138                                 exit(1);
139                         }
140                         if (bmapx[0].bmv_entries == 0) {
141                                 break;
142                         }
143                         x = 1;  /* back at first extent in buffer */
144                 }
145                 if (bmapx[x].bmv_oflags & 1) {
146                         fprintf(stderr, "FOUND ONE %lld %lld %x\n",
147                                 (long long) bmapx[x].bmv_offset,
148                                 (long long) bmapx[x].bmv_length,
149                                 bmapx[x].bmv_oflags);
150                         foundone = 1;
151                         foundany = 1;
152                 }
153                 x++;
154         }
155         if (foundone) {
156                 sleep(1);
157                 fprintf(stderr,"Repeat\n");
158                 goto again;
159         }
160         if (foundany) {
161                 exit(1);
162         }
163 }
164