Hi,
maybe this solution would be more suitable then.
Cheers,
Ondrej.
From cb99b2d28470f95386312edbd926c14da1cffa47 Mon Sep 17 00:00:00 2001
From: Ondrej Oprala <[email protected]>
Date: Wed, 15 Aug 2012 17:30:40 +0200
Subject: [PATCH] df: Fix outputting filesystem duplicities caused by
bind-mounts
* NEWS: Mention the fix.
* src/df.c (devlist_add): Add another entry to the global
device number list.
(dev_examined): Check if a filesystem has been examined already.
---
NEWS | 3 +++
src/df.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 71 insertions(+), 2 deletions(-)
diff --git a/NEWS b/NEWS
index 012a633..d1c84bb 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,9 @@ GNU coreutils NEWS -*-
outline -*-
** Bug fixes
+ df now properly outputs filesystem information with bind mounts
+ present on the system.
+
df now fails when the list of mounted file systems (/etc/mtab) cannot
be read, yet the file system type information is needed to process
certain options like -a, -l, -t and -x.
diff --git a/src/df.c b/src/df.c
index 9d956cd..ec6b7a5 100644
--- a/src/df.c
+++ b/src/df.c
@@ -43,6 +43,17 @@
proper_name ("David MacKenzie"), \
proper_name ("Paul Eggert")
+/* Filled with device numbers of examined filesystems to avoid
+ duplicities in output. */
+struct devlist
+{
+ dev_t dev_num;
+ struct devlist *dev_next;
+};
+
+/* Device list help pointer. */
+struct devlist *devlist_head;
+
/* If true, show inode information. */
static bool inode_format;
@@ -821,6 +832,48 @@ get_entry (char const *name, struct stat const *statp)
get_point (name, statp);
}
+/* Add a device number of the soon-to-be examined
+ filesystem to the global list devlist. */
+
+static void
+devlist_add (dev_t dev_num)
+{
+ struct devlist *devlist = devlist_head;
+ while(devlist->dev_next)
+ devlist = devlist->dev_next;
+
+ if (!devlist->dev_num)
+ devlist->dev_num = dev_num;
+ else
+ {
+ devlist->dev_next = xmalloc (sizeof *devlist);
+ devlist = devlist->dev_next;
+ devlist->dev_num = dev_num;
+ devlist->dev_next = NULL;
+ }
+}
+
+/* Check if the device was already examined. */
+
+static bool
+dev_examined (struct devlist *devlist, char *mount_dir)
+{
+ dev_t dev_num;
+ struct stat buf;
+ stat (mount_dir, &buf);
+
+ dev_num = buf.st_dev;
+ while (devlist)
+ {
+ if (devlist->dev_num == dev_num)
+ return true;
+ devlist = devlist->dev_next;
+ }
+
+ devlist_add (dev_num);
+ return false;
+}
+
/* Show all mounted file systems, except perhaps those that are of
an unselected type or are empty. */
@@ -828,10 +881,23 @@ static void
get_all_entries (void)
{
struct mount_entry *me;
+ struct devlist *devlist = xmalloc (sizeof *devlist);
+ devlist_head = devlist;
+
+ devlist->dev_num = 0;
+ devlist->dev_next = NULL;
for (me = mount_list; me; me = me->me_next)
- get_dev (me->me_devname, me->me_mountdir, NULL, me->me_type,
- me->me_dummy, me->me_remote, NULL, true);
+ if (!dev_examined (devlist, me->me_mountdir))
+ get_dev (me->me_devname, me->me_mountdir, NULL, me->me_type,
+ me->me_dummy, me->me_remote, NULL, true);
+
+ while (devlist)
+ {
+ devlist = devlist->dev_next;
+ free (devlist_head);
+ devlist_head = devlist;
+ }
}
/* Add FSTYPE to the list of file system types to display. */
--
1.7.11.2