From 8dd51c183396c4bf6344d08b01fb84658e0a8eb4 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 10 Jun 2015 14:19:45 +0200 Subject: fstrim: de-duplicate by mount source too 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 --- sys-utils/fstrim.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'sys-utils/fstrim.c') diff --git a/sys-utils/fstrim.c b/sys-utils/fstrim.c index 847b81924..02ab106a0 100644 --- a/sys-utils/fstrim.c +++ b/sys-utils/fstrim.c @@ -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); -- cgit v1.2.3-55-g7522