From: Pádraig Brady
Date: Thu, 29 May 2014 14:30:46 +0000 (+0100)
Subject: df: use the last device name provided by the system
X-Git-Tag: v8.23~51
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=v8.22-108-g25a2c94;p=thirdparty%2Fcoreutils.git
df: use the last device name provided by the system
The device name reported for a particular mount entry
may no longer be valid if the mount point was subsequently
mounted on a different device. Therefore honor the order
of the mount list returned by the system and use the last
reported device name.
* src/df.c (filter_mount_list): When discarding the current
mount entry, ensure that a new device name is not also discarded.
* tests/df/skip-duplicates.sh: Add a test case. Also fix
a false failure in the edge case of a system with only a
single file system.
* NEWS: Mention the fix.
---
diff --git a/NEWS b/NEWS
index 9679b46843..3919b7245b 100644
--- a/NEWS
+++ b/NEWS
@@ -44,7 +44,9 @@ GNU coreutils NEWS -*- outline -*-
[These dd bugs were present in "the beginning".]
- df now correctly elides duplicates for virtual file systems like tmpfs.
+ df now elides duplicates for virtual file systems like tmpfs, and will
+ display the correct device name for directories mounted multiple times.
+ [These bugs were present in "the beginning".]
head --bytes=-N and --lines=-N now handles devices more
consistently, not ignoring data from virtual devices like /dev/zero,
diff --git a/src/df.c b/src/df.c
index 01ecca6c52..82b0c5f378 100644
--- a/src/df.c
+++ b/src/df.c
@@ -604,7 +604,7 @@ excluded_fstype (const char *fstype)
}
/* Filter mount list by skipping duplicate entries.
- In the case of duplicities - based on to the device number - the mount entry
+ In the case of duplicities - based on the device number - the mount entry
with a '/' in its me_devname (i.e. not pseudo name like tmpfs) wins.
If both have a real devname (e.g. bind mounts), then that with the shorter
me_mountdir wins. */
@@ -638,17 +638,33 @@ filter_mount_list (void)
if (devlist)
{
- discard_me = me;
-
/* ...let the shorter mountdir win. */
if ((strchr (me->me_devname, '/')
&& ! strchr (devlist->me->me_devname, '/'))
|| (strlen (devlist->me->me_mountdir)
> strlen (me->me_mountdir)))
{
+ /* Discard mount entry for existing device. */
discard_me = devlist->me;
devlist->me = me;
}
+ else
+ {
+ /* Discard mount entry currently being processed. */
+ discard_me = me;
+
+ /* We might still want the devname from this mount entry as
+ the dev_num might not correlate with st_dev if another
+ device is subsequently overmounted at mountdir, so honor
+ the order of the presented list and replace with the
+ latest devname encountered. */
+ if (! STREQ (devlist->me->me_devname, me->me_devname))
+ {
+ free (devlist->me->me_devname);
+ devlist->me->me_devname = xstrdup (me->me_devname);
+ }
+ }
+
}
}
diff --git a/tests/df/skip-duplicates.sh b/tests/df/skip-duplicates.sh
index 44f7d4ca78..6fb6ff5618 100755
--- a/tests/df/skip-duplicates.sh
+++ b/tests/df/skip-duplicates.sh
@@ -55,7 +55,7 @@ struct mntent *getmntent (FILE *fp)
{.mnt_fsname="/fsname", .mnt_dir="/."},
{.mnt_fsname="/fsname", .mnt_dir="/"},
{.mnt_fsname="virtfs", .mnt_dir="/NONROOT"},
- {.mnt_fsname="virtfs", .mnt_dir="/NONROOT"},
+ {.mnt_fsname="virtfs2", .mnt_dir="/NONROOT"},
{.mnt_fsname="netns", .mnt_dir="net:[1234567]"},
};
@@ -100,9 +100,14 @@ LD_PRELOAD=./k.so CU_TEST_DUPE_INVALID=1 df >out && fail=1
test $(wc -l