| #include <stdlib.h> |
| #include <string.h> |
| #include <sys/types.h> |
| #include <fcntl.h> |
| #include <errno.h> |
| #include <malloc.h> |
| #include <unistd.h> |
| #include <xfs/xfs.h> |
| |
| /* test thanks to judith@sgi.com */ |
| |
| #define IO_SIZE 1048576 |
| |
| void |
| print_getbmapx( |
| const char *pathname, |
| int fd, |
| int64_t start, |
| int64_t limit); |
| |
| int |
| main(int argc, char *argv[]) |
| { |
| int i; |
| int fd; |
| char *buf; |
| struct dioattr dio; |
| xfs_flock64_t flock; |
| off_t offset; |
| char *file; |
| int loops; |
| char *dio_env; |
| |
| if(argc != 3) { |
| fprintf(stderr, "%s <loops> <file>\n", argv[0]); |
| exit(1); |
| } |
| |
| errno = 0; |
| loops = strtoull(argv[1], NULL, 0); |
| if (errno) { |
| perror("strtoull"); |
| exit(errno); |
| } |
| file = argv[2]; |
| |
| while (loops-- > 0) { |
| sleep(1); |
| fd = open(file, O_RDWR|O_CREAT|O_DIRECT, 0666); |
| if (fd < 0) { |
| perror("open"); |
| exit(1); |
| } |
| if (xfsctl(file, fd, XFS_IOC_DIOINFO, &dio) < 0) { |
| perror("dioinfo"); |
| exit(1); |
| } |
| |
| dio_env = getenv("XFS_DIO_MIN"); |
| if (dio_env) |
| dio.d_mem = dio.d_miniosz = atoi(dio_env); |
| |
| if ((dio.d_miniosz > IO_SIZE) || (dio.d_maxiosz < IO_SIZE)) { |
| fprintf(stderr, "Test won't work - iosize out of range" |
| " (dio.d_miniosz=%d, dio.d_maxiosz=%d)\n", |
| dio.d_miniosz, dio.d_maxiosz); |
| |
| exit(1); |
| } |
| buf = (char *)memalign(dio.d_mem , IO_SIZE); |
| if (buf == NULL) { |
| fprintf(stderr,"Can't get memory\n"); |
| exit(1); |
| } |
| memset(buf,'Z',IO_SIZE); |
| offset = 0; |
| |
| flock.l_whence = 0; |
| flock.l_start= 0; |
| flock.l_len = IO_SIZE*21; |
| if (xfsctl(file, fd, XFS_IOC_RESVSP64, &flock) < 0) { |
| perror("xfsctl "); |
| exit(1); |
| } |
| for (i = 0; i < 21; i++) { |
| if (pwrite(fd, buf, IO_SIZE, offset) != IO_SIZE) { |
| perror("pwrite"); |
| exit(1); |
| } |
| offset += IO_SIZE; |
| } |
| |
| print_getbmapx(file, fd, 0, 0); |
| |
| flock.l_whence = 0; |
| flock.l_start= 0; |
| flock.l_len = 0; |
| xfsctl(file, fd, XFS_IOC_FREESP64, &flock); |
| print_getbmapx(file, fd, 0, 0); |
| close(fd); |
| } |
| exit(0); |
| } |
| |
| void |
| print_getbmapx( |
| const char *pathname, |
| int fd, |
| int64_t start, |
| int64_t limit) |
| { |
| struct getbmapx bmapx[50]; |
| int array_size = sizeof(bmapx) / sizeof(bmapx[0]); |
| int x; |
| int foundone = 0; |
| int foundany = 0; |
| |
| again: |
| foundone = 0; |
| memset(bmapx, '\0', sizeof(bmapx)); |
| |
| bmapx[0].bmv_offset = start; |
| bmapx[0].bmv_length = -1; /* limit - start; */ |
| bmapx[0].bmv_count = array_size; |
| bmapx[0].bmv_entries = 0; /* no entries filled in yet */ |
| |
| bmapx[0].bmv_iflags = BMV_IF_PREALLOC; |
| |
| x = array_size; |
| for (;;) { |
| if (x > bmapx[0].bmv_entries) { |
| if (x != array_size) { |
| break; /* end of file */ |
| } |
| if (xfsctl(pathname, fd, XFS_IOC_GETBMAPX, bmapx) < 0) { |
| fprintf(stderr, "XFS_IOC_GETBMAPX failed\n"); |
| exit(1); |
| } |
| if (bmapx[0].bmv_entries == 0) { |
| break; |
| } |
| x = 1; /* back at first extent in buffer */ |
| } |
| if (bmapx[x].bmv_oflags & 1) { |
| fprintf(stderr, "FOUND ONE %lld %lld %x\n", |
| (long long) bmapx[x].bmv_offset, |
| (long long) bmapx[x].bmv_length, |
| bmapx[x].bmv_oflags); |
| foundone = 1; |
| foundany = 1; |
| } |
| x++; |
| } |
| if (foundone) { |
| sleep(1); |
| fprintf(stderr,"Repeat\n"); |
| goto again; |
| } |
| if (foundany) { |
| exit(1); |
| } |
| } |
| |