QA test to exercise unwritten extent conversion for sync direct I/O
[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
31         if(argc != 3) {
32                 fprintf(stderr, "%s <loops> <file>\n", argv[0]);
33                 exit(1);
34         }
35
36         errno = 0;
37         loops = strtoull(argv[1], NULL, 0);
38         if (errno) {
39                 perror("strtoull");
40                 exit(errno);
41         }
42         file = argv[2];
43
44         while (loops-- > 0) {
45                 sleep(1);
46                 fd = open(file, O_RDWR|O_CREAT|O_DIRECT, 0666);
47                 if (fd < 0) {
48                         perror("open");
49                         exit(1);
50                 }
51                 if (xfsctl(file, fd, XFS_IOC_DIOINFO, &dio) < 0) {
52                         perror("dioinfo");
53                         exit(1);
54                 }
55
56                 if ((dio.d_miniosz > IO_SIZE) || (dio.d_maxiosz < IO_SIZE)) {
57                         fprintf(stderr, "Test won't work - iosize out of range"
58                                 " (dio.d_miniosz=%d, dio.d_maxiosz=%d)\n",
59                                 dio.d_miniosz, dio.d_maxiosz);
60
61                         exit(1);
62                 }
63                 buf = (char *)memalign(dio.d_mem , IO_SIZE);
64                 if (buf == NULL) {
65                         fprintf(stderr,"Can't get memory\n");
66                         exit(1);
67                 }
68                 memset(buf,'Z',IO_SIZE);
69                 offset = 0;
70
71                 flock.l_whence = 0;
72                 flock.l_start= 0;
73                 flock.l_len = IO_SIZE*21;
74                 if (xfsctl(file, fd, XFS_IOC_RESVSP64, &flock) < 0) {
75                         perror("xfsctl ");
76                         exit(1);
77                 }
78                 for (i = 0; i < 21; i++) {
79                         if (pwrite(fd, buf, IO_SIZE, offset) != IO_SIZE) {
80                                 perror("pwrite");
81                                 exit(1);
82                         }
83                         offset += IO_SIZE;
84                 }
85
86                 print_getbmapx(file, fd, 0, 0);
87
88                 flock.l_whence = 0;
89                 flock.l_start= 0;
90                 flock.l_len = 0;
91                 xfsctl(file, fd, XFS_IOC_FREESP64, &flock);
92                 print_getbmapx(file, fd, 0, 0);
93                 close(fd);
94         }
95         exit(0);
96 }
97
98 void
99 print_getbmapx(
100 const   char    *pathname,
101         int     fd,
102         int64_t start,
103         int64_t limit)
104 {
105         struct getbmapx bmapx[50];
106         int array_size = sizeof(bmapx) / sizeof(bmapx[0]);
107         int x;
108         int foundone = 0;
109         int foundany = 0;
110
111 again:
112         foundone = 0;
113         memset(bmapx, '\0', sizeof(bmapx));
114
115         bmapx[0].bmv_offset = start;
116         bmapx[0].bmv_length = -1; /* limit - start; */
117         bmapx[0].bmv_count = array_size;
118         bmapx[0].bmv_entries = 0;       /* no entries filled in yet */
119
120         bmapx[0].bmv_iflags = BMV_IF_PREALLOC;
121
122         x = array_size;
123         for (;;) {
124                 if (x > bmapx[0].bmv_entries) {
125                         if (x != array_size) {
126                                 break;  /* end of file */
127                         }
128                         if (xfsctl(pathname, fd, XFS_IOC_GETBMAPX, bmapx) < 0) {
129                                 fprintf(stderr, "XFS_IOC_GETBMAPX failed\n");
130                                 exit(1);
131                         }
132                         if (bmapx[0].bmv_entries == 0) {
133                                 break;
134                         }
135                         x = 1;  /* back at first extent in buffer */
136                 }
137                 if (bmapx[x].bmv_oflags & 1) {
138                         fprintf(stderr, "FOUND ONE %lld %lld %x\n",
139                                 bmapx[x].bmv_offset, bmapx[x].bmv_length,bmapx[x].bmv_oflags);
140                         foundone = 1;
141                         foundany = 1;
142                 }
143                 x++;
144         }
145         if (foundone) {
146                 sleep(1);
147                 fprintf(stderr,"Repeat\n");
148                 goto again;
149         }
150         if (foundany) {
151                 exit(1);
152         }
153 }
154