df: always print the device name for bind mounted files
authorPádraig Brady <P@draigBrady.com>
Tue, 24 Aug 2010 07:13:33 +0000 (08:13 +0100)
committerPádraig Brady <P@draigBrady.com>
Wed, 25 Aug 2010 22:02:55 +0000 (23:02 +0100)
* 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.

NEWS
src/df.c

diff --git a/NEWS b/NEWS
index ae7b839..85f55a2 100644 (file)
--- 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.
index 76622fb..24877ab 100644 (file)
--- 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)