From 402006fa6e4dd1ce52758f9be91caaffffb3f337 Mon Sep 17 00:00:00 2001 From: Stanislav Brabec Date: Mon, 10 Jun 2019 21:59:17 +0200 Subject: fstrim: properly de-duplicate fstrim -A fstab can contain tag based mounts. De-duplication by source has to be done after resolving the full source path. Perform the table iteration twice. First time, prepare for de-duplication, second time perform the TRIM itself. Signed-off-by: Stanislav Brabec --- sys-utils/fstrim.c | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) (limited to 'sys-utils') diff --git a/sys-utils/fstrim.c b/sys-utils/fstrim.c index ea29a5695..e0e9e57a9 100644 --- a/sys-utils/fstrim.c +++ b/sys-utils/fstrim.c @@ -241,10 +241,6 @@ static int fstrim_all(struct fstrim_control *ctl) mnt_init_debug(0); ul_path_init_debug(); - itr = mnt_new_iter(MNT_ITER_BACKWARD); - if (!itr) - err(MNT_EX_FAIL, _("failed to initialize libmount iterator")); - if (ctl->fstab) filename = mnt_get_fstab_path(); @@ -255,9 +251,6 @@ static int fstrim_all(struct fstrim_control *ctl) /* de-duplicate by mountpoints */ mnt_table_uniq_fs(tab, 0, uniq_fs_target_cmp); - /* de-duplicate by source */ - mnt_table_uniq_fs(tab, MNT_UNIQ_FORWARD, uniq_fs_source_cmp); - if (ctl->fstab) { char *rootdev = NULL; @@ -281,26 +274,50 @@ static int fstrim_all(struct fstrim_control *ctl) } } + itr = mnt_new_iter(MNT_ITER_BACKWARD); + if (!itr) + err(MNT_EX_FAIL, _("failed to initialize libmount iterator")); + while (mnt_table_next_fs(tab, itr, &fs) == 0) { const char *src = mnt_fs_get_srcpath(fs), *tgt = mnt_fs_get_target(fs); - char *path; - int rc = 1; - if (!tgt || mnt_fs_is_pseudofs(fs) || mnt_fs_is_netfs(fs)) + if (!tgt || mnt_fs_is_pseudofs(fs) || mnt_fs_is_netfs(fs)) { + mnt_table_remove_fs(tab, fs); continue; + } /* convert LABEL= (etc.) from fstab to paths */ if (!src && cache) { const char *spec = mnt_fs_get_source(fs); - if (!spec) + if (!spec) { + mnt_table_remove_fs(tab, fs); continue; + } src = mnt_resolve_spec(spec, cache); + mnt_fs_set_source(fs, src); } - if (!src || *src != '/') + if (!src || *src != '/') { + mnt_table_remove_fs(tab, fs); continue; + } + } + mnt_free_iter(itr); + + /* de-duplicate by source */ + mnt_table_uniq_fs(tab, MNT_UNIQ_FORWARD, uniq_fs_source_cmp); + + itr = mnt_new_iter(MNT_ITER_BACKWARD); + if (!itr) + err(MNT_EX_FAIL, _("failed to initialize libmount iterator")); + + while (mnt_table_next_fs(tab, itr, &fs) == 0) { + const char *src = mnt_fs_get_srcpath(fs), + *tgt = mnt_fs_get_target(fs); + char *path; + int rc = 1; /* Is it really accessible mountpoint? Not all mountpoints are * accessible (maybe over mounted by another filesystem) */ @@ -337,10 +354,10 @@ static int fstrim_all(struct fstrim_control *ctl) else if (rc == 1 && !ctl->quiet) warnx(_("%s: the discard operation is not supported"), tgt); } + mnt_free_iter(itr); ul_unref_path(wholedisk); mnt_unref_table(tab); - mnt_free_iter(itr); mnt_unref_cache(cache); if (cnt && cnt == cnt_err) -- cgit v1.2.3-55-g7522