From: Lukáš Zaoral Date: Tue, 14 Apr 2026 12:09:02 +0000 (+0200) Subject: df: improve detection of duplicate entries X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;p=thirdparty%2Fcoreutils.git 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 --- diff --git a/NEWS b/NEWS index ce9645f5c1..b2edbbc26b 100644 --- a/NEWS +++ b/NEWS @@ -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, diff --git a/src/df.c b/src/df.c index 377b59dcee..f41ba3a870 100644 --- a/src/df.c +++ b/src/df.c @@ -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; diff --git a/tests/df/skip-duplicates.sh b/tests/df/skip-duplicates.sh index ed7657bf62..aa1a9ac303 100755 --- a/tests/df/skip-duplicates.sh +++ b/tests/df/skip-duplicates.sh @@ -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 || 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