fstrim: add --types to filter out by filesystem types

Fixes: https://github.com/util-linux/util-linux/issues/2040
Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2023-01-24 19:03:15 +01:00
parent 6729c112f7
commit b233ae61db
3 changed files with 20 additions and 3 deletions

View file

@ -22,6 +22,7 @@ _fstrim_module()
--offset
--length
--minimum
--types
--verbose
--dry-run
--help

View file

@ -53,6 +53,14 @@ Filesystems with "X-fstrim.notrim" mount option in fstab are skipped.
*-m, --minimum* _minimum-size_::
Minimum contiguous free range to discard, in bytes. (This value is internally rounded up to a multiple of the filesystem block size.) Free ranges smaller than this will be ignored and *fstrim* will adjust the minimum if it's smaller than the device's minimum, and report that (fstrim_range.minlen) back to userspace. By increasing this value, the *fstrim* operation will complete more quickly for filesystems with badly fragmented freespace, although not all blocks will be discarded. The default value is zero, discarding every free block.
*-t*, *--types* _list_::
Specifies allowed or forbidden filesystem types when used with *--all* or
*--fstab*. The _list_ is a comma-separated list of the filesystem names. The
_list_ follows how *mount -t* evaluates type patterns. Only specified
filesystem types are allowed. All specified types are forbidden if the list is
prefixed by "no" or each filesystem prefixed by "no" is forbidden. If the
option is not used, then all filesystems (except "autofs") are allowed.
*-v, --verbose*::
Verbose execution. With this option *fstrim* will output the number of bytes passed from the filesystem down the block stack to the device for potential discard. This number is a maximum discard amount from the storage device's perspective, because _FITRIM_ ioctl called repeated will keep sending the same sectors for discard repeatedly.
+

View file

@ -62,6 +62,7 @@ struct fstrim_range {
struct fstrim_control {
struct fstrim_range range;
char *type_pattern;
unsigned int verbose : 1,
quiet_unsupp : 1,
@ -210,7 +211,7 @@ fail:
return 1;
}
static int is_unwanted_fs(struct libmnt_fs *fs, const char *tgt)
static int is_unwanted_fs(struct libmnt_fs *fs, const char *tgt, const char *types)
{
struct statfs vfs;
int fd, rc;
@ -227,6 +228,8 @@ static int is_unwanted_fs(struct libmnt_fs *fs, const char *tgt)
return 1;
if (mnt_fs_match_options(fs, "+X-fstrim.notrim"))
return 1;
if (types && mnt_fs_match_fstype(fs, types) == 0)
return 1;
fd = open(tgt, O_PATH);
if (fd < 0)
@ -332,7 +335,7 @@ static int fstrim_all_from_file(struct fstrim_control *ctl, const char *filename
char *path;
int rc = 1;
if (!tgt || is_unwanted_fs(fs, tgt)) {
if (!tgt || is_unwanted_fs(fs, tgt, ctl->type_pattern)) {
mnt_table_remove_fs(tab, fs);
continue;
}
@ -460,6 +463,7 @@ static void __attribute__((__noreturn__)) usage(void)
fputs(_(" -o, --offset <num> the offset in bytes to start discarding from\n"), out);
fputs(_(" -l, --length <num> the number of bytes to discard\n"), out);
fputs(_(" -m, --minimum <num> the minimum extent length to discard\n"), out);
fputs(_(" -t, --types <list> limit the set of filesystem types\n"), out);
fputs(_(" -v, --verbose print number of discarded bytes\n"), out);
fputs(_(" --quiet-unsupported suppress error messages if trim unsupported\n"), out);
fputs(_(" -n, --dry-run does everything, but trim\n"), out);
@ -495,6 +499,7 @@ int main(int argc, char **argv)
{ "offset", required_argument, NULL, 'o' },
{ "length", required_argument, NULL, 'l' },
{ "minimum", required_argument, NULL, 'm' },
{ "types", required_argument, NULL, 't' },
{ "verbose", no_argument, NULL, 'v' },
{ "quiet-unsupported", no_argument, NULL, OPT_QUIET_UNSUPP },
{ "dry-run", no_argument, NULL, 'n' },
@ -512,7 +517,7 @@ int main(int argc, char **argv)
textdomain(PACKAGE);
close_stdout_atexit();
while ((c = getopt_long(argc, argv, "AahI:l:m:no:Vv", longopts, NULL)) != -1) {
while ((c = getopt_long(argc, argv, "AahI:l:m:no:t:Vv", longopts, NULL)) != -1) {
err_exclusive_options(c, longopts, excl, excl_st);
@ -544,6 +549,9 @@ int main(int argc, char **argv)
ctl.range.minlen = strtosize_or_err(optarg,
_("failed to parse minimum extent length"));
break;
case 't':
ctl.type_pattern = optarg;
break;
case 'v':
ctl.verbose = 1;
break;