Hello,

I have an issue with df (both in version 8.23 and in master branch).

I have tmpfs mounted as /run . There is /run/cgs/httpd subdirectory in
/run (just a subdirectory, not a tmpfs or another mount). This
/run/cgs/httpd is bind-mounted to /usr/cgs/httpd/run.

The current algorithm in df.c:filter_mount_list() chooses the bind
mountpoint since it has the leading slash in the "device" name
("/run/cgs/httpd" vs "run") which is wrong in my setup.

The similar (but not the same) issue is fixed by commit:
http://git.savannah.gnu.org/cgit/coreutils.git/commit/src/df.c?id=ed1a495b3ccb2665a13229ca866f2115bd768d17

I guess the "let real devices with / in the name win" replacement branch
should only be applied if mountpoints are the same as well.

Below is the data to reproduce the bug.

=== /etc/mtab (partial) ===
run /run tmpfs rw,noatime,nodiratime,nodev,noexec,mode=0755,size=1m 0 0
/run/cgs/httpd /usr/cgs/httpd/run none rw,bind 0 0
======

=== Real output (git) ===
Filesystem      Size  Used Avail Use% Mounted on
/run/cgs/httpd  1.0M  8.0K 1016K   1% /usr/cgs/httpd/run
======

=== Expected output (with the attached patch applied) ===
Filesystem      Size  Used Avail Use% Mounted on
run             1.0M  8.0K 1016K   1% /run
======

-- 
Vladimir A. Pavlov
--- coreutils-git.orig/src/df.c	2015-01-12 01:46:48.000000000 +0300
+++ coreutils-git/src/df.c	2015-01-12 02:08:11.190012207 +0300
@@ -650,7 +650,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, '/'))
+                        && ! strchr (devlist->me->me_devname, '/')
+                        && STREQ (me->me_mountdir, devlist->me->me_mountdir))
                        /* let a shorter mountdir win.  */
                        || (strlen (devlist->me->me_mountdir)
                            > strlen (me->me_mountdir))

Reply via email to