coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] df: avoid stat() for dummy file systems with -l


From: Kamil Dudka
Subject: Re: [PATCH] df: avoid stat() for dummy file systems with -l
Date: Thu, 03 Aug 2017 14:21:58 +0200
User-agent: KMail/4.14.10 (Linux/4.9.34-gentoo; KDE/4.14.32; x86_64; ; )

On Wednesday, August 02, 2017 08:10:11 Bernhard Voelker wrote:
> On 08/01/2017 04:49 PM, Kamil Dudka wrote:
> > If I understand it correctly, your patch takes effect regardless the use
> > of -l option.  Then please remove it from the summary to make it clear.
> > 
> > The optimized-out stat() call is, however, not the only change done by
> > your commit.  It has a side-effect that is observable from df's output
> > (and completely unrelated to autofs or remote file systems).  At first
> > glance, the side-effect looks useful but it should be properly analyzed
> > and documented...
> > 
> > Consider the following example:
> > 
> > # mount -t proc none /opt
> > # mount -t tmpfs none /opt
> > 
> > Now unpached df does not list the /opt entry:
> > 
> > # df | grep opt
> > 
> > ... but after your patch, it does:
> > 
> > # df | grep opt
> > none             2005384        0   2005384   0% /opt
> > 
> > Note that it was important that I have used the same "device" in both
> > the mount commands.
> 
> hmm, adding that little condition was too tempting - as there is the
> same one later on in get_dev(). ;-/
> 
> This sounds like there is another bug to fix in filter_mount_list
> wrt over-mounting.
> Maybe it should process the entries from /proc/self/mountinfo from
> the end instead of the beginning: by this it would be easier to filter
> out over-mounted file systems.
> 
> WDYT?

Sounds like it would fix the bug with over-mounted /opt.  But, for some 
reason, it breaks tests/df/skip-duplicates.sh.  This is the patch I tried:

--- a/src/df.c
+++ b/src/df.c
@@ -638,6 +638,24 @@ devlist_free (void *p)
   free (p);
 }

+/* reverse mount_entry list *plist and return its size */
+static int
+reverse_me_list(struct mount_entry **plist)
+{
+  int size = 0;
+  struct mount_entry *me, *next, *prev = NULL;
+  for (me = *plist; me; me = next)
+  {
+    size++;
+    next = me->me_next;
+    me->me_next = prev;
+    prev = me;
+  }
+
+  *plist = prev;
+  return size;
+}
+
 /* Filter mount list by skipping duplicate entries.
    In the case of duplicates - based on the device number - the mount entry
    with a '/' in its me_devname (i.e., not pseudo name like tmpfs) wins.
@@ -652,10 +670,9 @@ filter_mount_list (bool devices_only)

   /* Temporary list to keep entries ordered.  */
   struct devlist *device_list = NULL;
-  int mount_list_size = 0;

-  for (me = mount_list; me; me = me->me_next)
-    mount_list_size++;
+  /* reverse mount_list to better handle over-mounted file systems */
+  int mount_list_size = reverse_me_list(&mount_list);

   devlist_table = hash_initialize (mount_list_size, NULL,
                                  devlist_hash,
@@ -768,6 +785,9 @@ filter_mount_list (bool devices_only)
       hash_free (devlist_table);
       devlist_table = NULL;
   }
+  else
+    /* reverse mount_list back to preserve the order with --all */
+    reverse_me_list(&mount_list);
 }





reply via email to

[Prev in Thread] Current Thread [Next in Thread]