busybox/util-linux/fstrim.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * fstrim.c - discard the part (or whole) of mounted filesystem.
   4 *
   5 * 03 March 2012 - Malek Degachi <malek-degachi@laposte.net>
   6 * Adapted for busybox from util-linux-2.12a.
   7 *
   8 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
   9 */
  10//config:config FSTRIM
  11//config:       bool "fstrim (4.4 kb)"
  12//config:       default y
  13//config:       help
  14//config:       Discard unused blocks on a mounted filesystem.
  15
  16//applet:IF_FSTRIM(APPLET_NOEXEC(fstrim, fstrim, BB_DIR_SBIN, BB_SUID_DROP, fstrim))
  17
  18//kbuild:lib-$(CONFIG_FSTRIM) += fstrim.o
  19
  20//usage:#define fstrim_trivial_usage
  21//usage:       "[OPTIONS] MOUNTPOINT"
  22//usage:#define fstrim_full_usage "\n\n"
  23//usage:       "        -o OFFSET       Offset in bytes to discard from"
  24//usage:     "\n        -l LEN          Bytes to discard"
  25//usage:     "\n        -m MIN          Minimum extent length"
  26//usage:     "\n        -v              Print number of discarded bytes"
  27
  28#include "libbb.h"
  29#include <linux/fs.h>
  30
  31#ifndef FITRIM
  32struct fstrim_range {
  33        uint64_t start;
  34        uint64_t len;
  35        uint64_t minlen;
  36};
  37#define FITRIM          _IOWR('X', 121, struct fstrim_range)
  38#endif
  39
  40int fstrim_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  41int fstrim_main(int argc UNUSED_PARAM, char **argv)
  42{
  43        struct fstrim_range range;
  44        char *arg_o, *arg_l, *arg_m, *mp;
  45        unsigned opts;
  46        int fd;
  47
  48        enum {
  49                OPT_o = (1 << 0),
  50                OPT_l = (1 << 1),
  51                OPT_m = (1 << 2),
  52                OPT_v = (1 << 3),
  53        };
  54
  55#if ENABLE_LONG_OPTS
  56        static const char fstrim_longopts[] ALIGN1 =
  57                "offset\0"    Required_argument    "o"
  58                "length\0"    Required_argument    "l"
  59                "minimum\0"   Required_argument    "m"
  60                "verbose\0"   No_argument          "v"
  61                ;
  62#endif
  63
  64        opts = getopt32long(argv, "^"
  65                        "o:l:m:v"
  66                        "\0" "=1", fstrim_longopts,
  67                        &arg_o, &arg_l, &arg_m
  68        );
  69
  70        memset(&range, 0, sizeof(range));
  71        range.len = ULLONG_MAX;
  72
  73        if (opts & OPT_o)
  74                range.start = xatoull_sfx(arg_o, kmg_i_suffixes);
  75        if (opts & OPT_l)
  76                range.len = xatoull_sfx(arg_l, kmg_i_suffixes);
  77        if (opts & OPT_m)
  78                range.minlen = xatoull_sfx(arg_m, kmg_i_suffixes);
  79
  80        mp = argv[optind];
  81//Wwhy bother checking that it's a blockdev?
  82//      if (find_block_device(mp)) {
  83                fd = xopen_nonblocking(mp);
  84
  85                /* On ENOTTY error, util-linux 2.31 says:
  86                 * "fstrim: FILE: the discard operation is not supported"
  87                 */
  88                xioctl(fd, FITRIM, &range);
  89
  90                if (ENABLE_FEATURE_CLEAN_UP)
  91                        close(fd);
  92
  93                if (opts & OPT_v)
  94                        printf("%s: %llu bytes trimmed\n", mp, (unsigned long long)range.len);
  95                return EXIT_SUCCESS;
  96//      }
  97        return EXIT_FAILURE;
  98}
  99