1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
// SPDX-License-Identifier: GPL-2.0+
/*
* t_stripealign.c
* Print whether the file start block is stripe-aligned.
* Copyright (c) 2010 Eric Sandeen <sandeen@sandeen.net>
*/
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/vfs.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <linux/fiemap.h>
#include <linux/fs.h>
#ifndef FIEMAP_EXTENT_SHARED
# define FIEMAP_EXTENT_SHARED 0x00002000
#endif
#define FIEMAP_EXTENT_ACCEPTABLE (FIEMAP_EXTENT_LAST | \
FIEMAP_EXTENT_DATA_ENCRYPTED | FIEMAP_EXTENT_ENCODED | \
FIEMAP_EXTENT_UNWRITTEN | FIEMAP_EXTENT_MERGED | \
FIEMAP_EXTENT_SHARED)
/*
* If only filename given, print first block.
*
* If filename & sunit (in blocks) given, print whether we are well-aligned
*/
int main(int argc, char ** argv)
{
struct statfs sb;
struct fiemap *fie;
struct fiemap_extent *fe;
int fd;
int ret;
int sunit = 0; /* in blocks */
char *filename;
unsigned long long block;
if (argc < 3) {
printf("Usage: %s <filename> <sunit in blocks>\n", argv[0]);
return 1;
}
filename = argv[1];
sunit = atoi(argv[2]);
fd = open(filename, O_RDONLY);
if (fd < 0) {
perror("can't open file\n");
return 1;
}
ret = fstatfs(fd, &sb);
if (ret) {
perror(filename);
close(fd);
return 1;
}
fie = calloc(1, sizeof(struct fiemap) + sizeof(struct fiemap_extent));
if (!fie) {
close(fd);
perror("malloc");
return 1;
}
fie->fm_length = 1;
fie->fm_flags = FIEMAP_FLAG_SYNC;
fie->fm_extent_count = 1;
ret = ioctl(fd, FS_IOC_FIEMAP, fie);
if (ret < 0) {
unsigned int bmap = 0;
ret = ioctl(fd, FIBMAP, &bmap);
if (ret <= 0) {
if (ret < 0)
perror("fibmap");
else
fprintf(stderr, "fibmap returned no result\n");
free(fie);
close(fd);
return 1;
}
block = bmap;
goto check;
}
if (fie->fm_mapped_extents != 1) {
printf("%s: no extents?\n", filename);
free(fie);
close(fd);
return 1;
}
fe = &fie->fm_extents[0];
if (fe->fe_flags & ~FIEMAP_EXTENT_ACCEPTABLE) {
printf("%s: bad flags 0x%x\n", filename, fe->fe_flags);
free(fie);
close(fd);
return 1;
}
block = fie->fm_extents[0].fe_physical / sb.f_bsize;
check:
if (block % sunit) {
printf("%s: Start block %llu not multiple of sunit %u\n",
filename, block, sunit);
return 1;
} else
printf("%s: well-aligned\n", filename);
free(fie);
close(fd);
return 0;
}
|