diff options
author | Karel Zak | 2015-06-10 14:19:45 +0200 |
---|---|---|
committer | Karel Zak | 2015-06-10 14:19:45 +0200 |
commit | 8dd51c183396c4bf6344d08b01fb84658e0a8eb4 (patch) | |
tree | a9474cce6b6c9ec89e81f3aa544080a0a3d31595 /sys-utils/fstrim.c | |
parent | fdisk: differentiate between +<sector> and +<size>{M,G,...} (diff) | |
download | kernel-qcow2-util-linux-8dd51c183396c4bf6344d08b01fb84658e0a8eb4.tar.gz kernel-qcow2-util-linux-8dd51c183396c4bf6344d08b01fb84658e0a8eb4.tar.xz kernel-qcow2-util-linux-8dd51c183396c4bf6344d08b01fb84658e0a8eb4.zip |
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 <kzak@redhat.com>
Diffstat (limited to 'sys-utils/fstrim.c')
-rw-r--r-- | sys-utils/fstrim.c | 29 |
1 files changed, 28 insertions, 1 deletions
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); |