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 out || fail=1