--- libgtop2-2.26.0/sysdeps/linux/fsusage.c.orig	2009-07-19 12:52:37.000000000 -0700
+++ libgtop2-2.26.0/sysdeps/linux/fsusage.c	2009-07-20 21:09:23.000000000 -0700
@@ -16,6 +16,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <mntent.h>
+#include <dirent.h>
 
 
 /*
@@ -28,11 +29,12 @@
 
 static gboolean
 get_device(glibtop* server, const char *mountpoint,
-	   char* device, size_t device_size)
+	   dev_t* device)
 {
 	const struct mntent *mnt;
 	FILE *fp;
 	gboolean found = FALSE;
+	struct stat st;
 
 	if (!(fp = setmntent(MOUNTED, "r"))) {
 		glibtop_warn_io_r(server, "Could not open %s", MOUNTED);
@@ -42,8 +44,8 @@
 	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);
+			if (!lstat(mnt->mnt_fsname, &st) && S_ISBLK(st.st_mode)) {
+				*device = st.st_rdev;
 				found = TRUE;
 			}
 			break;
@@ -56,22 +58,21 @@
 }
 
 
-/*
-  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)
+get_major_minor(unsigned long int *major, unsigned long int *minor, const char *path)
 {
-	g_strlcpy(prefix, device, prefix_size);
-
-	for ( ; *prefix; prefix++) {
-		if (isdigit(*prefix)) {
-			*prefix = '\0';
-			return TRUE;
+	gboolean rval = FALSE;
+	char buf[8];
+	FILE *fp = fopen(path, "r");
+	if (fp) {
+		if (fread(&buf,sizeof(char), 8, fp)) {
+			if (sscanf(buf, "%lu:%lu", major, minor) == 2) {
+				rval = TRUE;
+			}
 		}
+		fclose(fp);
 	}
-
-	return FALSE;
+	return rval;
 }
 
 
@@ -99,29 +100,59 @@
  */
 
 static void
-get_sys_path(glibtop* server, const char *device, char **stat_path, const char **parse_format)
+get_sys_path(glibtop* server, dev_t 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];
+	struct stat st;
 
-	if (is_partition(device, prefix, sizeof prefix)) {
+	/* This is the default statistics format */
+	*parse_format = linux_2_6_25_format;
 
-		*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;
+	/* Find the block device statistics file for this major/minor number.
+	 * Use /sys/dev/block/<major>:<minor>/stat if it exists,
+	 * Otherwise crawl /sys/block/<device>/<partition> looking for it.
+	 */
+	*stat_path = g_strdup_printf("/sys/dev/block/%lu:%lu/stat", MAJOR(device), MINOR(device));
+
+	if (lstat(*stat_path, &st)) {
+		/* if /sys/dev/block/... doesn't exist, start crawling */
+		DIR *block_dir;
+		DIR *part_dir;
+		struct dirent *block_ent;
+		struct dirent *part_ent;
+		unsigned long int major;
+		unsigned long int minor;
+		if ((block_dir = opendir("/sys/block/"))) {
+			gboolean found = FALSE;
+			while (!found && (block_ent = readdir(block_dir))) {
+				if (get_major_minor(&major, &minor, g_strdup_printf("/sys/block/%s/dev", block_ent->d_name)) && major == MAJOR(device)) {
+					if (minor == MINOR(device)) {
+						*stat_path = g_strdup_printf("/sys/block/%s/stat", block_ent->d_name);
+						if (server->os_version_code < LINUX_VERSION_CODE(2, 6, 25))
+							*parse_format = "%*llu %*llu %llu %*llu %*llu %*llu %llu";
+						found = TRUE;
+					} else {
+						/* Major matched, but minor did not.
+						 * Maybe this device is partitioned.
+						 */
+						if ((part_dir = opendir(g_strdup_printf("/sys/block/%s", block_ent->d_name)))) {
+							while (!found && (part_ent = readdir(part_dir))) {
+								if (get_major_minor(&major, &minor, g_strdup_printf("/sys/block/%s/%s/dev", block_ent->d_name, part_ent->d_name))) {
+									*stat_path = g_strdup_printf("/sys/block/%s/%s/stat", block_ent->d_name, part_ent->d_name);
+									if (server->os_version_code < LINUX_VERSION_CODE(2, 6, 25))
+										*parse_format = "%*llu %llu %*llu %llu";
+									found = TRUE;
+								}
+							}	
+							closedir(part_dir);
+						}
+					}
+				}
+			}
+			closedir(block_dir);
+		}
 	}
 }
 
@@ -133,9 +164,9 @@
 	const char *format;
 	int ret;
 	char buffer[BUFSIZ];
-	char device[64];
+	dev_t device;
 
-	if (!get_device(server, path, device, sizeof device))
+	if (!get_device(server, path, &device))
 		goto out;
 
 	get_sys_path(server, device, &filename, &format);
