Subject: Re: bug#6555: stat enhancement

From: Pádraig Brady <[email-masked]>
Date: Mon, 23 Aug 2010 20:18:49 +0100

On 19/08/10 16:51, Pádraig Brady wrote:
> I also noticed differences with bind mounts though,
> which I need to look into further.
> There are also comments in df::show_point() to
> indicate find_mount_points() is only a fall back and
> may hang. Perhaps we need to move more of show_point()
> to `stat`?

Looking more at correlating `statm -c%m file` and `df -P file`,
I noticed an inconsistency with how df deals with bind mounts.
Take for example:

  $ mount | column -t
  /dev/shm/tdir                on  /old_home/padraig/git/tdir
  /old_home/padraig/git/tfile  on  /dev/shm/tdir/tfile

I.E. /old_home/padraig/git/tdir is replaced by /dev/shm/tdir
and /dev/shm/tdir/tfile is replaced by /old_home/padraig/git/tfile

Now if we pass an already canonicalized absolute path
to the mount target to df, we get inconsistent results:

~/git$ df -Ph tfile /dev/shm/tdir//tfile /dev/shm/tdir/tfile
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda8              37G   34G  3.0G  92% /old_home
/dev/sda8              37G   34G  3.0G  92% /old_home
/dev/sda8              37G   34G  3.0G  92% /old_home
/old_home/padraig/git/tfile   37G   34G  3.0G  92% /dev/shm/tdir/tfile
$ df -Ph tdir /old_home/padraig/git/tdir/ /old_home/padraig/git/tdir
Filesystem            Size  Used Avail Use% Mounted on
tmpfs                1004M  272K 1003M   1% /dev/shm
tmpfs                1004M  272K 1003M   1% /dev/shm
/dev/shm/tdir        1004M  272K 1003M   1% /old_home/padraig/git/tdir

I think that df should resolve to disk devices if possible.
I.E. the last line output in each of the above 2 commands above
is inconsistent and a bit confusing IMHO. This patch
removes the optimization which triggers this.

diff --git a/src/df.c b/src/df.c
index 76622fb..24877ab 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;
-    }

Note now that we have `stat -c%m`, that seems a more appropriate
place to output an aliased target if present, like:

~/git$ stat -c%m tdir /old_home/padraig/git/tdir/ /dev/shm/tdir
/dev/shm/tdir
/dev/shm/tdir
/dev/shm

cheers,
Pádraig.

p.s. I'll also update NEWS with the changed behavior
if I apply the above