From: Pádraig Brady
Date: Tue, 24 Aug 2010 07:13:33 +0000 (+0100) Subject: df: always print the device name for bind mounted files X-Git-Tag: v8.6~62 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0380e4c98e9d53ae314f5537c5f1a4b891577768;p=thirdparty%2Fcoreutils.git df: always print the device name for bind mounted files * src/df (show_point): Remove the optimization for comparing the specified path with the device name, as this produces inconsistent results in the presence of bind mounts. For bind mounts, the device name is populated with the bind mount target. * NEWS: Mention the change in behavior. --- diff --git a/NEWS b/NEWS index ae7b8397d2..85f55a2610 100644 --- a/NEWS +++ b/NEWS @@ -26,6 +26,9 @@ GNU coreutils NEWS -*- outline -*- ** Changes in behavior + df now consistently prints the device name for a bind mounted file, + rather than its aliased target. + du now uses less than half as much memory when operating on trees with many hard-linked files. With --count-links (-l), or when operating on trees with no hard-linked files, there is no change. diff --git a/src/df.c b/src/df.c index 76622fb692..24877ab135 100644 --- a/src/df.c +++ b/src/df.c @@ -643,54 +643,35 @@ show_point (const char *point, const struct stat *statp) struct mount_entry *me; struct mount_entry const *best_match = NULL; - /* If POINT is an absolute file name, see if we can find the - mount point without performing any extra stat calls at all. */ - if (*point == '/') - { - /* Find the best match: prefer non-dummies, and then prefer the - last match if there are ties. */ - - for (me = mount_list; me; me = me->me_next) - if (STREQ (me->me_mountdir, point) && !STREQ (me->me_type, "lofs") - && (!best_match || best_match->me_dummy || !me->me_dummy)) - best_match = me; - } - /* Calculate the real absolute file name for POINT, and use that to find the mount point. This avoids statting unavailable mount points, which can hang df. */ - if (! best_match) + char *resolved = canonicalize_file_name (point); + if (resolved && resolved[0] == '/') { - char *resolved = canonicalize_file_name (point); + size_t resolved_len = strlen (resolved); + size_t best_match_len = 0; - if (resolved && resolved[0] == '/') + for (me = mount_list; me; me = me->me_next) + if (!STREQ (me->me_type, "lofs") + && (!best_match || best_match->me_dummy || !me->me_dummy)) { - size_t resolved_len = strlen (resolved); - size_t best_match_len = 0; - - for (me = mount_list; me; me = me->me_next) - if (!STREQ (me->me_type, "lofs") - && (!best_match || best_match->me_dummy || !me->me_dummy)) - { - size_t len = strlen (me->me_mountdir); - if (best_match_len <= len && len <= resolved_len - && (len == 1 /* root file system */ - || ((len == resolved_len || resolved[len] == '/') - && strncmp (me->me_mountdir, resolved, len) == 0))) - { - best_match = me; - best_match_len = len; - } - } + size_t len = strlen (me->me_mountdir); + if (best_match_len <= len && len <= resolved_len + && (len == 1 /* root file system */ + || ((len == resolved_len || resolved[len] == '/') + && strncmp (me->me_mountdir, resolved, len) == 0))) + { + best_match = me; + best_match_len = len; + } } - - free (resolved); - - if (best_match - && (stat (best_match->me_mountdir, &disk_stats) != 0 - || disk_stats.st_dev != statp->st_dev)) - best_match = NULL; } + free (resolved); + if (best_match + && (stat (best_match->me_mountdir, &disk_stats) != 0 + || disk_stats.st_dev != statp->st_dev)) + best_match = NULL; if (! best_match) for (me = mount_list; me; me = me->me_next)