>From 80ea8041e1389262a4b1b4eec002330ab4054352 Mon Sep 17 00:00:00 2001 From: Fridolin Pokorny Date: Wed, 27 Aug 2014 15:00:14 +0200 Subject: [PATCH 1/2] df: let me_dev be populated from gnulib * src/df.c (filter_mount_list, get_dev): Avoid using stat()s when me_dev is populated from Gnulib. This will give more accurate output when using df in chroot'ed environments. Device IDs are not determined by stat() call using mountpoint, so it is not possible to make a collision when same names are used (e.g. /home/ and CHROOT-ROOT/home/). --- src/df.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/df.c b/src/df.c index e907b94..abddb88 100644 --- a/src/df.c +++ b/src/df.c @@ -622,11 +622,7 @@ filter_mount_list (bool devices_only) struct devlist *devlist; struct mount_entry *discard_me = NULL; - /* TODO: On Linux we might avoid this stat() and another in get_dev() - by using the device IDs available from /proc/self/mountinfo. - read_file_system_list() could populate me_dev from those - for efficiency and accuracy. */ - if (-1 == stat (me->me_mountdir, &buf)) + if (me->me_dev == (dev_t) -1 && stat (me->me_mountdir, &buf) == -1) { /* Stat failed - add ME to be able to complain about it later. */ buf.st_dev = me->me_dev; @@ -870,13 +866,14 @@ add_to_grand_total (struct field_values_t *bv, struct field_values_t *iv) If MOUNT_POINT is non-NULL, then DISK may be NULL -- certain systems may not be able to produce statistics in this case. ME_DUMMY and ME_REMOTE are the mount entry flags. + ME_DEV is mount entry device id or -1. Caller must set PROCESS_ALL to true when iterating over all entries, as when df is invoked with no non-option argument. See below for details. */ static void get_dev (char const *disk, char const *mount_point, char const* file, char const *stat_file, char const *fstype, - bool me_dummy, bool me_remote, + bool me_dummy, bool me_remote, dev_t me_dev, const struct fs_usage *force_fsu, bool process_all) { @@ -930,9 +927,9 @@ get_dev (char const *disk, char const *mount_point, char const* file, /* Ensure we don't output incorrect stats for over-mounted directories. Discard stats when the device name doesn't match. */ struct stat sb; - if (stat (stat_file, &sb) == 0) + if (me_dev != (dev_t) -1 || stat (stat_file, &sb) == 0) { - char const * devname = devname_for_dev (sb.st_dev); + char const * devname = devname_for_dev (me_dev); if (devname && ! STREQ (devname, disk)) { fstype = "-"; @@ -1212,7 +1209,7 @@ get_disk (char const *disk) { get_dev (best_match->me_devname, best_match->me_mountdir, file, NULL, best_match->me_type, best_match->me_dummy, - best_match->me_remote, NULL, false); + best_match->me_remote, best_match->me_dev, NULL, false); return true; } else if (eclipsed_device) @@ -1307,7 +1304,7 @@ get_point (const char *point, const struct stat *statp) if (best_match) get_dev (best_match->me_devname, best_match->me_mountdir, point, point, best_match->me_type, best_match->me_dummy, best_match->me_remote, - NULL, false); + best_match->me_dev, NULL, false); else { /* We couldn't find the mount entry corresponding to POINT. Go ahead and @@ -1318,7 +1315,8 @@ get_point (const char *point, const struct stat *statp) char *mp = find_mount_point (point, statp); if (mp) { - get_dev (NULL, mp, point, NULL, NULL, false, false, NULL, false); + get_dev (NULL, mp, point, NULL, NULL, false, false, + (dev_t) -1, NULL, false); free (mp); } } @@ -1349,7 +1347,7 @@ get_all_entries (void) for (me = mount_list; me; me = me->me_next) get_dev (me->me_devname, me->me_mountdir, NULL, NULL, me->me_type, - me->me_dummy, me->me_remote, NULL, true); + me->me_dummy, me->me_remote, me->me_dev, NULL, true); } /* Add FSTYPE to the list of file system types to display. */ @@ -1699,8 +1697,8 @@ main (int argc, char **argv) { if (print_grand_total) get_dev ("total", - (field_data[SOURCE_FIELD].used ? "-" : "total"), - NULL, NULL, NULL, false, false, &grand_fsu, false); + (field_data[SOURCE_FIELD].used ? "-" : "total"), NULL, + NULL, NULL, false, false, (dev_t) -1, &grand_fsu, false); print_table (); } -- 1.9.3