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:       select PLATFORM_LINUX
  14//config:       help
  15//config:       Discard unused blocks on a mounted filesystem.
  16
  17//applet:IF_FSTRIM(APPLET_NOEXEC(fstrim, fstrim, BB_DIR_SBIN, BB_SUID_DROP, fstrim))
  18
  19//kbuild:lib-$(CONFIG_FSTRIM) += fstrim.o
  20
  21//usage:#define fstrim_trivial_usage
  22//usage:       "[OPTIONS] MOUNTPOINT"
  23//usage:#define fstrim_full_usage "\n\n"
  24//usage:        IF_LONG_OPTS(
  25//usage:       "        -o,--offset OFFSET      Offset in bytes to discard from"
  26//usage:     "\n        -l,--length LEN         Bytes to discard"
  27//usage:     "\n        -m,--minimum MIN        Minimum extent length"
  28//usage:     "\n        -v,--verbose            Print number of discarded bytes"
  29//usage:        )
  30//usage:        IF_NOT_LONG_OPTS(
  31//usage:       "        -o OFFSET       Offset in bytes to discard from"
  32//usage:     "\n        -l LEN          Bytes to discard"
  33//usage:     "\n        -m MIN          Minimum extent length"
  34//usage:     "\n        -v              Print number of discarded bytes"
  35//usage:        )
  36
  37#include "libbb.h"
  38#include <linux/fs.h>
  39
  40#ifndef FITRIM
  41struct fstrim_range {
  42        uint64_t start;
  43        uint64_t len;
  44        uint64_t minlen;
  45};
  46#define FITRIM          _IOWR('X', 121, struct fstrim_range)
  47#endif
  48
  49int fstrim_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  50int fstrim_main(int argc UNUSED_PARAM, char **argv)
  51{
  52        struct fstrim_range range;
  53        char *arg_o, *arg_l, *arg_m, *mp;
  54        unsigned opts;
  55        int fd;
  56
  57        enum {
  58                OPT_o = (1 << 0),
  59                OPT_l = (1 << 1),
  60                OPT_m = (1 << 2),
  61                OPT_v = (1 << 3),
  62        };
  63
  64#if ENABLE_LONG_OPTS
  65        static const char fstrim_longopts[] ALIGN1 =
  66                "offset\0"    Required_argument    "o"
  67                "length\0"    Required_argument    "l"
  68                "minimum\0"   Required_argument    "m"
  69                "verbose\0"   No_argument          "v"
  70                ;
  71#endif
  72
  73        opts = getopt32long(argv, "^"
  74                        "o:l:m:v"
  75                        "\0" "=1", fstrim_longopts,
  76                        &arg_o, &arg_l, &arg_m
  77        );
  78
  79        memset(&range, 0, sizeof(range));
  80        range.len = ULLONG_MAX;
  81
  82        if (opts & OPT_o)
  83                range.start = xatoull_sfx(arg_o, kmg_i_suffixes);
  84        if (opts & OPT_l)
  85                range.len = xatoull_sfx(arg_l, kmg_i_suffixes);
  86        if (opts & OPT_m)
  87                range.minlen = xatoull_sfx(arg_m, kmg_i_suffixes);
  88
  89        mp = argv[optind];
  90//Wwhy bother checking that it's a blockdev?
  91//      if (find_block_device(mp)) {
  92                fd = xopen_nonblocking(mp);
  93
  94                /* On ENOTTY error, util-linux 2.31 says:
  95                 * "fstrim: FILE: the discard operation is not supported"
  96                 */
  97                xioctl(fd, FITRIM, &range);
  98
  99                if (ENABLE_FEATURE_CLEAN_UP)
 100                        close(fd);
 101
 102                if (opts & OPT_v)
 103                        printf("%s: %llu bytes trimmed\n", mp, (unsigned long long)range.len);
 104                return EXIT_SUCCESS;
 105//      }
 106        return EXIT_FAILURE;
 107}
 108