]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
df: prioritize mounts nearer the device root
authorDave Chiluk <chiluk@canonical.com>
Mon, 21 Sep 2015 20:04:11 +0000 (15:04 -0500)
committerPádraig Brady <P@draigBrady.com>
Wed, 23 Sep 2015 00:02:44 +0000 (01:02 +0100)
In the presence of bind mounts of a device, the 4th "mount root" field
from /proc/self/mountinfo is now considered, so as to prefer mount
points closer to the root of the device.  Note on older systems with
an /etc/mtab file, the source device was listed as the originating
directory, and so this was not an issue.
Details at http://pad.lv/1432871

* src/df.c (filter_mount_list): When deduplicating mount entries,
only prefer sources nearer or at the root of the device, when the
target is nearer the root of the device.
* NEWS: Mention the change in behavior.

NEWS
src/df.c

diff --git a/NEWS b/NEWS
index 63574da2d161e9a4e3de98b2ee4e2e631c995a1c..9aec2594566c00eaf90fb773948cfcb30bacebe9 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,9 @@ GNU coreutils NEWS                                    -*- outline -*-
   base64 no longer supports hex or oct --wrap parameters,
   thus better supporting decimals with leading zeros.
 
+  df now prefers sources towards the root of a device when
+  eliding duplicate bind mounted entries.
+
 ** Improvements
 
   du no longer stats all mount points at startup, only doing so
index 2e541b952e42eac2a84ea72fd490bd5b58071c89..17a2de43706168f365a9743af5f3d34fb5e0d95c 100644 (file)
--- a/src/df.c
+++ b/src/df.c
@@ -641,6 +641,13 @@ filter_mount_list (bool devices_only)
 
           if (devlist)
             {
+              bool target_nearer_root = strlen (devlist->me->me_mountdir)
+                                        > strlen (me->me_mountdir);
+              /* With bind mounts, prefer items nearer the root of the source */
+              bool source_below_root = devlist->me->me_mntroot != NULL
+                                       && me->me_mntroot != NULL
+                                       && (strlen (devlist->me->me_mntroot)
+                                           < strlen (me->me_mntroot));
               if (! print_grand_total && me->me_remote && devlist->me->me_remote
                   && ! STREQ (devlist->me->me_devname, me->me_devname))
                 {
@@ -652,9 +659,8 @@ filter_mount_list (bool devices_only)
               else if ((strchr (me->me_devname, '/')
                        /* let "real" devices with '/' in the name win.  */
                         && ! strchr (devlist->me->me_devname, '/'))
-                       /* let a shorter mountdir win.  */
-                       || (strlen (devlist->me->me_mountdir)
-                           > strlen (me->me_mountdir))
+                       /* let points towards the root of the device win.  */
+                       || (target_nearer_root && ! source_below_root)
                        /* let an entry overmounted on a new device win...  */
                        || (! STREQ (devlist->me->me_devname, me->me_devname)
                            /* ... but only when matching an existing mnt point,