1
0
mirror of https://git.savannah.gnu.org/git/coreutils.git synced 2026-10-24 02:08:57 +03:00

df: improve detection of duplicate entries

Do not compare only with the latest entry for given device id but also
all previously saved entries with the same id.

* src/df.c (struct devlist): Add next_same_dev struct member.
(filter_mount_list): Iterate over next_same_dev to find duplicates.
* tests/df/skip-duplicates.sh: Add test cases.
* NEWS: Mention the improvement.
https://redhat.atlassian.net/browse/RHEL-5649
This commit is contained in:
Lukáš Zaoral
2026-04-14 14:09:02 +02:00
committed by Pádraig Brady
parent 5cb0cca3b8
commit f6fda635bd
3 changed files with 12 additions and 4 deletions

3
NEWS
View File

@@ -62,6 +62,9 @@ GNU coreutils NEWS -*- outline -*-
'df --local' recognises more file system types as remote.
Specifically: autofs, ncpfs, smb, smb2, gfs, gfs2, userlandfs.
'df' improves duplicate mount suppression, by checking each mount against
all previously kept entries for the same device, not just the latest one.
'expand' and 'unexpand' now support multi-byte characters.
'groups' and 'id' will now exit sooner after a write error,

View File

@@ -50,6 +50,7 @@ struct devlist
dev_t dev_num;
struct mount_entry *me;
struct devlist *next;
struct devlist *next_same_dev;
struct devlist *seen_last; /* valid for hashed devlist entries only */
};
@@ -720,6 +721,7 @@ filter_mount_list (bool devices_only)
{
struct stat buf;
struct mount_entry *discard_me = NULL;
struct devlist *last_seen_dev = NULL, *seen_dev = NULL;
/* Avoid stating remote file systems as that may hang.
On Linux we probably have me_dev populated from /proc/self/mountinfo,
@@ -737,9 +739,9 @@ filter_mount_list (bool devices_only)
else
{
/* If we've already seen this device... */
struct devlist *seen_dev = devlist_for_dev (buf.st_dev);
last_seen_dev = seen_dev = devlist_for_dev (buf.st_dev);
if (seen_dev)
for (; seen_dev && ! discard_me; seen_dev = seen_dev->next_same_dev)
{
bool target_nearer_root = strlen (seen_dev->me->me_mountdir)
> strlen (me->me_mountdir);
@@ -796,6 +798,7 @@ filter_mount_list (bool devices_only)
struct devlist *devlist = xmalloc (sizeof *devlist);
devlist->me = me;
devlist->dev_num = buf.st_dev;
devlist->next_same_dev = last_seen_dev;
devlist->next = device_list;
device_list = devlist;

View File

@@ -138,6 +138,8 @@ struct mntent *getmntent (FILE *fp)
{.mnt_fsname="rem:ote1",.mnt_dir="/REMOTE", .mnt_opts=""},
{.mnt_fsname="rem:ote1",.mnt_dir="/REMOTE", .mnt_opts=""},
{.mnt_fsname="rem:ote2",.mnt_dir="/REMOTE", .mnt_opts=""},
{.mnt_fsname="rem:ote1",.mnt_dir="/REMOTE", .mnt_opts=""},
{.mnt_fsname="rem:ote2",.mnt_dir="/REMOTE", .mnt_opts=""},
};
if (done == 1)
@@ -152,7 +154,7 @@ struct mntent *getmntent (FILE *fp)
if (done == 1 && !getenv ("CU_TEST_DUPE_INVALID"))
done++; /* skip the first entry. */
while (done++ <= 10)
while (done++ <= 12)
{
if (!mntents[done-2].mnt_type)
mntents[done-2].mnt_type = "-";
@@ -210,7 +212,7 @@ test $(grep -c 'virtfs2.*t2' <out) -eq 1 || { fail=1; cat out; }
# Ensure that filtering duplicates does not affect -a processing.
LD_PRELOAD=$LD_PRELOAD:./k.so df -a >out || fail=1
total_fs=6; test "$CU_REMOTE_FS" && total_fs=$(expr $total_fs + 3)
total_fs=6; test "$CU_REMOTE_FS" && total_fs=$(expr $total_fs + 5)
test $(wc -l <out) -eq $total_fs || { fail=1; cat out; }
# Ensure placeholder "-" values used for the eclipsed "virtfs"
test $(grep -c 'virtfs *-' <out) -eq 1 || { fail=1; cat out; }