summaryrefslogtreecommitdiffstats
path: root/sys-utils/fstrim.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys-utils/fstrim.c')
-rw-r--r--sys-utils/fstrim.c52
1 files changed, 38 insertions, 14 deletions
diff --git a/sys-utils/fstrim.c b/sys-utils/fstrim.c
index cae38cdff..2c11a317f 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,49 @@ 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"));
+
+ /* Remove useless entries and canonicalize the table */
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) {
- /* convert LABEL= (etc.) from fstab to paths */
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;
+ }
+ }
+
+ /* de-duplicate by source */
+ mnt_table_uniq_fs(tab, MNT_UNIQ_FORWARD, uniq_fs_source_cmp);
+
+ mnt_reset_iter(itr, MNT_ITER_BACKWARD);
+
+ /* Do FITRIM */
+ 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) */
@@ -311,6 +327,14 @@ static int fstrim_all(struct fstrim_control *ctl)
if (rc)
continue; /* overlaying mount */
+ /* FITRIM on read-only filesystem can fail, and it can fail */
+ if (access(path, W_OK) != 0) {
+ if (errno == EROFS)
+ continue;
+ if (errno == EACCES)
+ continue;
+ }
+
if (!has_discard(src, &wholedisk))
continue;
cnt++;
@@ -329,10 +353,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)