| // SPDX-License-Identifier: GPL-2.0 |
| /* |
| * Copyright (c) 2004-2005 Silicon Graphics, Inc. |
| * All Rights Reserved. |
| */ |
| |
| #include "command.h" |
| #include "input.h" |
| #include "init.h" |
| #include "io.h" |
| |
| static cmdinfo_t fadvise_cmd; |
| |
| static void |
| fadvise_help(void) |
| { |
| printf(_( |
| "\n" |
| " advise the page cache about expected I/O patterns on the current file\n" |
| "\n" |
| " Modifies kernel page cache behaviour when operating on the current file.\n" |
| " The range arguments are required by some advise commands ([*] below).\n" |
| " With no arguments, the POSIX_FADV_NORMAL advice is implied.\n" |
| " -d -- don't need these pages (POSIX_FADV_DONTNEED) [*]\n" |
| " -n -- data will be accessed once (POSIX_FADV_NOREUSE) [*]\n" |
| " -r -- expect random page references (POSIX_FADV_RANDOM)\n" |
| " -s -- expect sequential page references (POSIX_FADV_SEQUENTIAL)\n" |
| " -w -- will need these pages (POSIX_FADV_WILLNEED) [*]\n" |
| " Notes: these interfaces are not supported in Linux kernels before 2.6.\n" |
| " NORMAL sets the default readahead setting on the file.\n" |
| " RANDOM sets the readahead setting on the file to zero.\n" |
| " SEQUENTIAL sets double the default readahead setting on the file.\n" |
| " WILLNEED and NOREUSE are equivalent, and force the maximum readahead.\n" |
| "\n")); |
| } |
| |
| static int |
| fadvise_f( |
| int argc, |
| char **argv) |
| { |
| off_t offset = 0, length = 0; |
| int c, range = 0, advise = POSIX_FADV_NORMAL; |
| |
| while ((c = getopt(argc, argv, "dnrsw")) != EOF) { |
| switch (c) { |
| case 'd': /* Don't need these pages */ |
| advise = POSIX_FADV_DONTNEED; |
| range = 1; |
| break; |
| case 'n': /* Data will be accessed once */ |
| advise = POSIX_FADV_NOREUSE; |
| range = 1; |
| break; |
| case 'r': /* Expect random page references */ |
| advise = POSIX_FADV_RANDOM; |
| range = 0; |
| break; |
| case 's': /* Expect sequential page references */ |
| advise = POSIX_FADV_SEQUENTIAL; |
| range = 0; |
| break; |
| case 'w': /* Will need these pages */ |
| advise = POSIX_FADV_WILLNEED; |
| range = 1; |
| break; |
| default: |
| exitcode = 1; |
| return command_usage(&fadvise_cmd); |
| } |
| } |
| if (range) { |
| size_t blocksize, sectsize; |
| |
| if (optind != argc - 2) { |
| exitcode = 1; |
| return command_usage(&fadvise_cmd); |
| } |
| init_cvtnum(&blocksize, §size); |
| offset = cvtnum(blocksize, sectsize, argv[optind]); |
| if (offset < 0) { |
| printf(_("non-numeric offset argument -- %s\n"), |
| argv[optind]); |
| exitcode = 1; |
| return 0; |
| } |
| optind++; |
| length = cvtnum(blocksize, sectsize, argv[optind]); |
| if (length < 0) { |
| printf(_("non-numeric length argument -- %s\n"), |
| argv[optind]); |
| exitcode = 1; |
| return 0; |
| } |
| } else if (optind != argc) { |
| exitcode = 1; |
| return command_usage(&fadvise_cmd); |
| } |
| |
| if (posix_fadvise(file->fd, offset, length, advise) < 0) { |
| perror("fadvise"); |
| exitcode = 1; |
| return 0; |
| } |
| return 0; |
| } |
| |
| void |
| fadvise_init(void) |
| { |
| fadvise_cmd.name = "fadvise"; |
| fadvise_cmd.cfunc = fadvise_f; |
| fadvise_cmd.argmin = 0; |
| fadvise_cmd.argmax = -1; |
| fadvise_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; |
| fadvise_cmd.args = _("[-dnrsw] [off len]"); |
| fadvise_cmd.oneline = _("advisory commands for sections of a file"); |
| fadvise_cmd.help = fadvise_help; |
| |
| add_command(&fadvise_cmd); |
| } |