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
| | #include "compat-util.h"
static struct fa_advice {
const char *name;
const int nr;
} advice_table[] = {
{ "normal", POSIX_FADV_NORMAL },
{ "sequential", POSIX_FADV_SEQUENTIAL },
{ "random", POSIX_FADV_RANDOM },
{ "noreuse", POSIX_FADV_NOREUSE },
{ "willneed", POSIX_FADV_WILLNEED },
{ "dontneed" , POSIX_FADV_DONTNEED }
};
static int usage(const char * argv0)
{
int i;
fprintf(stderr,
"Usage: %s [-a ADVICE] [-o OFFSET] "
"[-l LENGTH] FILE...\n", argv0);
fprintf(stderr, "\nPossible values for advice:\n");
for (i = 0; i < ARRAY_SIZE(advice_table); ++i)
fprintf(stderr, "\t%s\n", advice_table[i].name);
return 1;
}
static void apply_fadvise(const char *path, off_t offset, off_t len, int advice)
{
int fd;
if ((fd = open_noatime(path) < 0)) {
fprintf(stderr, "%s: open(): %s\n", path, strerror(errno));
return;
}
if (len <= 0) {
/* for compatibility with kernels < 2.6.6 */
struct stat sb;
if (fstat(fd, &sb) < 0) {
fprintf(stderr, "%s: fstat(%d): %s\n",
path, fd, strerror(errno));
goto out;
}
len = sb.st_size;
}
if (posix_fadvise(fd, offset, len, advice) < 0)
fprintf(stderr,
"%s: posix_fadvise("
"offset=%lu,len=%lu,advice=%d): %s\n",
path,
(unsigned long)offset,
(unsigned long)len,
advice, strerror(errno));
out:
close(fd);
}
int main(int argc, char * const argv[])
{
off_t offset = 0;
off_t len = 0;
int advice = POSIX_FADV_NORMAL;
int opt;
int argi = 1;
while ((opt = getopt(argc, argv, "o:l:a:h")) != -1) {
int i;
char *err;
argi += 2;
switch(opt) {
case 'o':
offset = cstr_to_off_t(optarg, &err, 10);
if (*err || offset < 0) {
fprintf(stderr, "offset must be >= 0\n");
return 1;
}
break;
case 'l':
len = cstr_to_off_t(optarg, &err, 10);
if (*err || len < 0) {
fprintf(stderr, "length must be >= 0\n");
return 1;
}
break;
case 'a':
for (i = 0; i < ARRAY_SIZE(advice_table); ++i) {
if (strcmp(advice_table[i].name, optarg))
continue;
advice = advice_table[i].nr;
break;
}
if (i < ARRAY_SIZE(advice_table))
break;
fprintf(stderr, "advice '%s' not understood\n", optarg);
/* fall-through */
default:
return usage(argv[0]);
}
}
if (argi >= argc)
return usage(argv[0]);
for (; argi < argc; ++argi)
apply_fadvise(argv[argi], offset, len, advice);
return 0;
}
|