3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 only,
7 * as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License version 2 for more details (a copy is included
13 * in the LICENSE file that accompanied this code).
15 * You should have received a copy of the GNU General Public License
16 * version 2 along with this program; If not, see http://www.gnu.org/licenses
18 * Please visit http://www.xyratex.com/contact if you need additional
19 * information or have any questions.
25 * Copyright 2013 Xyratex Technology Limited
27 * Author: Artem Blagodarenko <Artem_Blagodarenko@xyratex.com>
34 #include <sys/ioctl.h>
35 #include <sys/types.h>
41 #include <linux/types.h>
43 #include <lustre/lustre_user.h>
46 # define FS_IOC_FIEMAP (_IOWR('f', 11, struct fiemap))
51 /* This test executes fiemap ioctl and check
52 * a) there are no file ranges marked with FIEMAP_EXTENT_UNWRITTEN
53 * b) data ranges sizes sum is equal to given in second param */
54 int check_fiemap(int fd, long long orig_size)
56 /* This buffer is enougth for 1MB length file */
57 union { struct fiemap f; char c[4096]; } fiemap_buf;
58 struct fiemap *fiemap = &fiemap_buf.f;
59 struct fiemap_extent *fm_extents = &fiemap->fm_extents[0];
60 unsigned int count = (sizeof(fiemap_buf) - sizeof(*fiemap)) /
63 long long file_size = 0;
65 memset(&fiemap_buf, 0, sizeof(fiemap_buf));
68 fiemap->fm_flags = (FIEMAP_FLAG_SYNC | FIEMAP_FLAG_DEVICE_ORDER);
69 fiemap->fm_extent_count = count;
70 fiemap->fm_length = FIEMAP_MAX_OFFSET;
72 if (ioctl(fd, FS_IOC_FIEMAP, fiemap) < 0) {
73 fprintf(stderr, "error while ioctl %i\n", errno);
77 for (i = 0; i < fiemap->fm_mapped_extents; i++) {
79 "offset %lu, length %lu\n"
81 (unsigned long)fm_extents[i].fe_logical,
82 (unsigned long)fm_extents[i].fe_length,
83 fm_extents[i].fe_flags);
85 if (fm_extents[i].fe_flags & FIEMAP_EXTENT_UNWRITTEN) {
86 fprintf(stderr, "Unwritten extent\n");
89 file_size += fm_extents[i].fe_length;
93 printf("No unwritten extents, extents number %u, "
94 "file size %lli, original size %lli\n",
95 fiemap->fm_mapped_extents,
96 file_size, orig_size);
97 return file_size != orig_size;
100 int main(int argc, char **argv)
103 struct option long_opts[] = {
104 { .name = "test", .has_arg = no_argument, .val = 't' },
111 while ((c = getopt_long(argc, argv, "t", long_opts, NULL)) != -1) {
116 fprintf(stderr, "error: %s: option '%s' unrecognized\n",
117 argv[0], argv[optind - 1]);
122 if (optind != argc - 2) {
123 fprintf(stderr, "Usage: %s <filename> <filesize>\n", argv[0]);
127 fd = open(argv[optind], O_RDONLY);
129 fprintf(stderr, "cannot open %s for reading, error %i",
130 argv[optind], errno);
134 fprintf(stderr, "fd: %i\n", fd);
136 rc = check_fiemap(fd, atoll(argv[optind + 1]));
139 fprintf(stderr, "closing %s, error %i", argv[optind], errno);