]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - io/madvise.c
c001a2ff6db9d8f1e2862eceed1fd06fbfce4f2b
[thirdparty/xfsprogs-dev.git] / io / madvise.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2004-2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
5 */
6
7 #include "command.h"
8 #include "input.h"
9 #include <sys/mman.h>
10 #include "init.h"
11 #include "io.h"
12
13 static cmdinfo_t madvise_cmd;
14
15 static void
16 madvise_help(void)
17 {
18 printf(_(
19 "\n"
20 " advise the page cache about access patterns expected for a mapping\n"
21 "\n"
22 " Modifies page cache behavior when operating on the current mapping.\n"
23 " The range arguments are required by some advise commands ([*] below).\n"
24 " With no arguments, the POSIX_MADV_NORMAL advice is implied.\n"
25 " -d -- don't need these pages (POSIX_MADV_DONTNEED) [*]\n"
26 " -r -- expect random page references (POSIX_MADV_RANDOM)\n"
27 " -s -- expect sequential page references (POSIX_MADV_SEQUENTIAL)\n"
28 " -w -- will need these pages (POSIX_MADV_WILLNEED) [*]\n"
29 " Notes:\n"
30 " NORMAL sets the default readahead setting on the file.\n"
31 " RANDOM sets the readahead setting on the file to zero.\n"
32 " SEQUENTIAL sets double the default readahead setting on the file.\n"
33 " WILLNEED forces the maximum readahead.\n"
34 "\n"));
35 }
36
37 int
38 madvise_f(
39 int argc,
40 char **argv)
41 {
42 off64_t offset, llength;
43 size_t length;
44 void *start;
45 int advise = MADV_NORMAL, c;
46 size_t blocksize, sectsize;
47
48 while ((c = getopt(argc, argv, "drsw")) != EOF) {
49 switch (c) {
50 case 'd': /* Don't need these pages */
51 advise = MADV_DONTNEED;
52 break;
53 case 'r': /* Expect random page references */
54 advise = MADV_RANDOM;
55 break;
56 case 's': /* Expect sequential page references */
57 advise = MADV_SEQUENTIAL;
58 break;
59 case 'w': /* Will need these pages */
60 advise = MADV_WILLNEED;
61 break;
62 default:
63 return command_usage(&madvise_cmd);
64 }
65 }
66
67 if (optind == argc) {
68 offset = mapping->offset;
69 length = mapping->length;
70 } else if (optind == argc - 2) {
71 init_cvtnum(&blocksize, &sectsize);
72 offset = cvtnum(blocksize, sectsize, argv[optind]);
73 if (offset < 0) {
74 printf(_("non-numeric offset argument -- %s\n"),
75 argv[optind]);
76 return 0;
77 }
78 optind++;
79 llength = cvtnum(blocksize, sectsize, argv[optind]);
80 if (llength < 0) {
81 printf(_("non-numeric length argument -- %s\n"),
82 argv[optind]);
83 return 0;
84 } else if (llength > (size_t)llength) {
85 printf(_("length argument too large -- %lld\n"),
86 (long long)llength);
87 return 0;
88 } else
89 length = (size_t)llength;
90 } else {
91 return command_usage(&madvise_cmd);
92 }
93
94 start = check_mapping_range(mapping, offset, length, 1);
95 if (!start)
96 return 0;
97
98 if (madvise(start, length, advise) < 0) {
99 perror("madvise");
100 return 0;
101 }
102 return 0;
103 }
104
105 void
106 madvise_init(void)
107 {
108 madvise_cmd.name = "madvise";
109 madvise_cmd.altname = "ma";
110 madvise_cmd.cfunc = madvise_f;
111 madvise_cmd.argmin = 0;
112 madvise_cmd.argmax = -1;
113 madvise_cmd.flags = CMD_NOFILE_OK | CMD_FOREIGN_OK;
114 madvise_cmd.args = _("[-drsw] [off len]");
115 madvise_cmd.oneline = _("give advice about use of memory");
116 madvise_cmd.help = madvise_help;
117
118 add_command(&madvise_cmd);
119 }