--- libgtop-2.24.4/sysdeps/linux/fsusage.c	2009-08-13 23:14:16.000000000 +0400
+++ patched-libgtop-2.24.4/sysdeps/linux/fsusage.c	2009-08-13 23:01:39.000000000 +0400
@@ -24,134 +24,66 @@
  */
 
 
-
-
-static gboolean
-get_device(glibtop* server, const char *mountpoint,
-	   char* device, size_t device_size)
-{
-	const struct mntent *mnt;
-	FILE *fp;
-	gboolean found = FALSE;
-
-	if (!(fp = setmntent(MOUNTED, "r"))) {
-		glibtop_warn_io_r(server, "Could not open %s", MOUNTED);
-		goto out;
-	}
-
-	while ((mnt = getmntent(fp)))
-	{
-		if (!strcmp(mountpoint, mnt->mnt_dir)) {
-			if (!strncmp(mnt->mnt_fsname, "/dev/", 5)) {
-				g_strlcpy(device, mnt->mnt_fsname + 5, device_size);
-				found = TRUE;
-			}
-			break;
-		}
-	}
-
-	endmntent(fp);
-out:
-	return found;
-}
-
-
-/*
-  TRUE if device is like "hda3" and then set prefix to "hda".
- */
-static gboolean
-is_partition(const char* device, char* prefix, size_t prefix_size)
-{
-	g_strlcpy(prefix, device, prefix_size);
-
-	for ( ; *prefix; prefix++) {
-		if (isdigit(*prefix)) {
-			*prefix = '\0';
-			return TRUE;
-		}
-	}
-
-	return FALSE;
-}
-
-
-/*
-  Bug #539360.
-  /sys/.../stat format is partially defined in
-  linux/Documentation/block/stat.txt (looks outdated).  Before linux
-  2.5.25, /sys/block/%s/stat and /sys/block/%s/%s/stat were not the
-  same, but the following commit changed the latter to have the same
-  format and broke compatibility.
-
-  Commit 34e8beac92c27d292938065f8375842d2840767c
-  Author: Jerome Marchand <jmarchan@redhat.com>
-  Date:   Fri Feb 8 11:04:55 2008 +0100
-
-    Enhanced partition statistics: sysfs
-
-    Reports enhanced partition statistics in sysfs.
-
-    Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
-
-    fs/partitions/check.c |   22 +++++++++++++++++++---
-    1 files changed, 19 insertions(+), 3 deletions(-)
-
- */
-
-static void
-get_sys_path(glibtop* server, const char *device, char **stat_path, const char **parse_format)
-{
-	const char* linux_2_6_25_format = "%*llu %*llu %llu %*llu"
-					  "%*llu %*llu %llu %*llu";
-
-	char prefix[32];
-
-	if (is_partition(device, prefix, sizeof prefix)) {
-
-		*stat_path = g_strdup_printf("/sys/block/%s/%s/stat",
-					     prefix, device);
-		if (server->os_version_code < LINUX_VERSION_CODE(2, 6, 25))
-			*parse_format = "%*llu %llu %*llu %llu";
-		else
-			*parse_format = linux_2_6_25_format;
-	}
-	else
-	{
-		*stat_path = g_strdup_printf("/sys/block/%s/stat", device);
-		if (server->os_version_code < LINUX_VERSION_CODE(2, 6, 25))
-			*parse_format = "%*llu %*llu %llu %*llu %*llu %*llu %llu";
-		else
-			*parse_format = linux_2_6_25_format;
-	}
-}
-
-
-
 static void linux_2_6_0(glibtop *server, glibtop_fsusage *buf, const char *path)
 {
-	char *filename = NULL;
+  const char *filename="/proc/diskstats";
+  const char *linux_2_6_25_format="%i %i %*s %*llu %*llu %llu %*llu"
+    " %*llu %*llu %llu %*llu %*llu %*llu %*llu";
+  const char *old_linux_2_6_format="%i %i %*s %*llu %llu %*llu %llu";
 	const char *format;
 	int ret;
 	char buffer[BUFSIZ];
-	char device[64];
-
-	if (!get_device(server, path, device, sizeof device))
-		goto out;
-
-	get_sys_path(server, device, &filename, &format);
-
-	ret = try_file_to_buffer(buffer, sizeof buffer, filename);
-
-	if (ret < 0) goto out;
-
-	if (sscanf(buffer, format, &buf->read, &buf->write) != 2) {
-		glibtop_warn_io_r(server, "Could not parse %s", filename);
-		goto out;
-	}
-
+  struct mntent *m;
+  struct stat s;
+  FILE *fs;
+  dev_t major,minor,Major,Minor;
+  char *line, *nextline;
+
+  if((fs=setmntent(MOUNTED,"r"))) {
+    while((m=getmntent(fs))) {
+      if(!(lstat(m->mnt_fsname,&s))) {
+	if(!(strcmp(m->mnt_dir,path))) {
+	  major=MAJOR(s.st_rdev);
+	  minor=MINOR(s.st_rdev);
+	  /*
+	    the idea is to read entire file at once. for huge installations
+	    with many concurrently mounted partitions/devices the buffer
+	    size (BUFSIZ) needs to be adjusted
+	  */
+	  ret=try_file_to_buffer(buffer,sizeof(buffer),filename);
+	  if(ret<0) {
+	    glibtop_warn_io_r(server, "Could not read %s",filename);
+	    break;
+	  }
+	  if (server->os_version_code >= LINUX_VERSION_CODE(2, 6, 25))
+	    format=linux_2_6_25_format;
+	  else
+	    format=old_linux_2_6_format;
+	  line=buffer;
+	  nextline=skip_line(line);
+	  while(1) {
+ 	    sscanf(line,format,&Major,&Minor,&buf->read,&buf->write);
+	    if(Major==major && Minor==minor) {
 	buf->flags |= (1 << GLIBTOP_FSUSAGE_READ) | (1 << GLIBTOP_FSUSAGE_WRITE);
- out:
-	g_free(filename);
+	      break;
+	    }
+	    else {
+	      if(*nextline) {
+		line=nextline;
+		nextline=skip_line(line);
+	      }
+	      else
+		break;
+	    }
+	  }
+	  break;
+	}
+      }
+    }
+    endmntent(fs);
+  }
+  else
+                glibtop_warn_io_r(server, "Could not open %s", MOUNTED);
 }
 
 
