]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
fstrim: de-duplicate by mount source too
authorKarel Zak <kzak@redhat.com>
Wed, 10 Jun 2015 12:19:45 +0000 (14:19 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 10 Jun 2015 12:19:45 +0000 (14:19 +0200)
Now fstrim de-duplicates by target (mountpoint). This patch adds
de-duplication according to mount source (device) to avoid bind mounts
or devices mounted more than once. Note that the patch also check FS
root, the different FS roots of the same multi-root FS (e.g. btrfs)
maybe mounted on different places.

  # mount --bind /home/wine /mnt/test

old version:

  # fstrim -av
  /mnt/test: 0 B (0 bytes) trimmed            <---
  /home/wine: 0 B (0 bytes) trimmed           <---
  /boot: 0 B (0 bytes) trimmed
  /home: 0 B (0 bytes) trimmed
  /: 0 B (0 bytes) trimmed

new version:

  # fstrim -av
  /mnt/test: 0 B (0 bytes) trimmed            <---
  /boot: 0 B (0 bytes) trimmed
  /home: 171.8 MiB (180113408 bytes) trimmed
  /: 0 B (0 bytes) trimmed

Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1162213
Signed-off-by: Karel Zak <kzak@redhat.com>
sys-utils/fstrim.c

index 847b81924962a21d91301fbaacd435617c75ec8f..02ab106a0cefb3599f8b813ea41eac36d72adece 100644 (file)
@@ -147,6 +147,30 @@ static int uniq_fs_target_cmp(
        return !mnt_fs_streq_target(a, mnt_fs_get_target(b));
 }
 
+static int uniq_fs_source_cmp(
+               struct libmnt_table *tb __attribute__((__unused__)),
+               struct libmnt_fs *a,
+               struct libmnt_fs *b)
+{
+       int eq;
+
+       if (mnt_fs_is_pseudofs(a) || mnt_fs_is_netfs(a) ||
+           mnt_fs_is_pseudofs(b) || mnt_fs_is_netfs(b))
+               return 1;
+
+       eq = mnt_fs_streq_srcpath(a, mnt_fs_get_srcpath(b));
+       if (eq) {
+               const char *aroot = mnt_fs_get_root(a),
+                          *broot = mnt_fs_get_root(b);
+               if (!aroot || !broot)
+                       eq = 0;
+               else if (strcmp(aroot, broot) != 0)
+                       eq = 0;
+       }
+
+       return !eq;
+}
+
 /*
  * fstrim --all follows "mount -a" return codes:
  *
@@ -172,9 +196,12 @@ static int fstrim_all(struct fstrim_range *rangetpl, int verbose)
        if (!tab)
                err(MOUNT_EX_FAIL, _("failed to parse %s"), _PATH_PROC_MOUNTINFO);
 
-       /* de-duplicate the table */
+       /* de-duplicate by mountpoints */
        mnt_table_uniq_fs(tab, 0, uniq_fs_target_cmp);
 
+       /* de-duplicate by source and root */
+       mnt_table_uniq_fs(tab, 0, uniq_fs_source_cmp);
+
        while (mnt_table_next_fs(tab, itr, &fs) == 0) {
                const char *src = mnt_fs_get_srcpath(fs),
                           *tgt = mnt_fs_get_target(fs);