diff options
author | Pádraig Brady <P@draigBrady.com> | 2010-08-24 08:13:33 +0100 |
---|---|---|
committer | Pádraig Brady <P@draigBrady.com> | 2010-08-25 23:02:55 +0100 |
commit | 0380e4c98e9d53ae314f5537c5f1a4b891577768 (patch) | |
tree | 80ee5be3fe23dff9e4fec89655e969c831784286 | |
parent | 2ed90c4c9dca45ca266f4d5d25b6bac982765004 (diff) | |
download | coreutils-0380e4c98e9d53ae314f5537c5f1a4b891577768.tar.xz |
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.
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | src/df.c | 61 |
2 files changed, 24 insertions, 40 deletions
@@ -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. @@ -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) |