/* * mmap vs extent issue * * Copyright (C) 2014 Anton Blanchard , IBM * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #include #include #include #include #include #include #include #include #include static void check_fiemap(int fd) { struct fiemap *fiemap; unsigned long i, ex_size; fiemap = malloc(sizeof(struct fiemap)); if (!fiemap) { perror("malloc"); exit(1); } memset(fiemap, 0, sizeof(struct fiemap)); fiemap->fm_length = ~0; if (ioctl(fd, FS_IOC_FIEMAP, fiemap) == -1) { perror("ioctl(FIEMAP)"); exit(1); } ex_size = sizeof(struct fiemap_extent) * fiemap->fm_mapped_extents; fiemap = realloc(fiemap, sizeof(struct fiemap) + ex_size); if (!fiemap) { perror("realloc"); exit(1); } memset(fiemap->fm_extents, 0, ex_size); fiemap->fm_extent_count = fiemap->fm_mapped_extents; fiemap->fm_mapped_extents = 0; if (ioctl(fd, FS_IOC_FIEMAP, fiemap) < 0) { perror("ioctl(FIEMAP)"); exit(1); } for (i = 0; i < fiemap->fm_mapped_extents; i++) { unsigned long start = fiemap->fm_extents[i].fe_logical; unsigned long end = fiemap->fm_extents[i].fe_logical + fiemap->fm_extents[i].fe_length; if (start <= 48*1024 && end > 48*1024) { printf("GOOD\n"); exit(0); } } printf("BAD:\n"); for (i = 0; i < fiemap->fm_mapped_extents; i++) { printf("%ld:\t%016llx %016llx\n", i, fiemap->fm_extents[i].fe_logical, fiemap->fm_extents[i].fe_length); } exit(1); } int main(int argc, char *argv[]) { char name[] = "mmap-lseek-XXXXXX"; int fd; char *p; fd = mkstemp(name); if (fd == -1) { perror("mkstemp"); exit(1); } /* Create a 48 kB file */ lseek(fd, 48 * 1024 - 1, SEEK_SET); if (write(fd, "\0", 1) != 1) { perror("write"); exit(1); } /* Map it, allowing space for it to grow */ p = mmap(NULL, 128 * 1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (p == MAP_FAILED) { perror("mmap"); exit(1); } /* Write to the start of the file */ *(p) = 1; /* Extend the file */ lseek(fd, 128 * 1024 - 1, SEEK_SET); if (write(fd, "\0", 1) != 1) { perror("write"); exit(1); } /* write to the new space in the first page */ *(p + 49 * 1024) = 1; munmap(p, 128 * 1024); check_fiemap(fd); close(fd); return 0; }