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