diff -Naur util-linux-2.12q.orig/disk-utils/fsck.cramfs.c util-linux-2.12q/disk-utils/fsck.cramfs.c
--- util-linux-2.12q.orig/disk-utils/fsck.cramfs.c	2004-12-11 16:53:16.000000000 +0200
+++ util-linux-2.12q/disk-utils/fsck.cramfs.c	2005-06-11 16:29:20.000000000 +0300
@@ -47,14 +47,12 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
-#include <sys/ioctl.h>
 #include <sys/sysmacros.h>	/* for major, minor */
 
 #include "cramfs.h"
 #include "../defines.h"		/* for HAVE_lchown */
 #include "nls.h"
-
-#define BLKGETSIZE _IO(0x12,96) /* return device size */
+#include "disk_size.h"
 
 static const char *progname = "cramfsck";
 
@@ -503,22 +510,8 @@
 		perror(filename);
 		exit(8);
 	}
-	if (S_ISBLK(st.st_mode)) {
-		if (ioctl(fd, BLKGETSIZE, &length) < 0) {
-			fprintf(stderr, _("%s: warning--unable to determine "
-					  "filesystem size \n"), filename);
-			exit(4);
-		}
-		length = length * 512;
-	}
-	else if (S_ISREG(st.st_mode)) {
-		length = st.st_size;
-	}
-	else {
-		fprintf(stderr, _("%s is not a block device or file\n"),
-			filename);
-		exit(8);
-	}
+
+	length = (size_t)disk_get_sectors(fd) * 512;
 
 	if (length < sizeof(struct cramfs_super)) {
 		fprintf(stderr, _("%s: invalid cramfs--file length "
diff -Naur util-linux-2.12q.orig/disk-utils/Makefile util-linux-2.12q/disk-utils/Makefile
--- util-linux-2.12q.orig/disk-utils/Makefile	2004-12-21 19:14:16.000000000 +0200
+++ util-linux-2.12q/disk-utils/Makefile	2005-06-11 16:00:56.000000000 +0300
@@ -43,7 +53,7 @@
 all: $(SBIN) $(USRBIN)
 
 fsck.cramfs: fsck.cramfs.o
-	$(CC) $(LDFLAGS) -o fsck.cramfs fsck.cramfs.o -lz
+	$(CC) $(LDFLAGS) -o fsck.cramfs fsck.cramfs.o $(LIB)/disk_size.o -lz
 
 mkfs.cramfs: mkfs.cramfs.o $(LIB)/md5.o
 	$(CC) $(LDFLAGS) -o mkfs.cramfs mkfs.cramfs.o $(LIB)/md5.o -lz
@@ -57,6 +67,8 @@
 mkswap: mkswap.o $(LIB)/xstrncpy.o
 	$(CC) $(LDFLAGS) -o $@ $^ $(MKSWAP_LIBS)
 
+mkfs.minix mkfs.bfs mkswap: $(LIB)/disk_size.o
+
 install: all
 	$(INSTALLDIR) $(SBINDIR) $(USRBINDIR) $(ETCDIR)
 	$(INSTALLBIN) $(SBIN) $(SBINDIR)
diff -Naur util-linux-2.12q.orig/disk-utils/mkfs.bfs.c util-linux-2.12q/disk-utils/mkfs.bfs.c
--- util-linux-2.12q.orig/disk-utils/mkfs.bfs.c	2002-03-09 00:58:05.000000000 +0200
+++ util-linux-2.12q/disk-utils/mkfs.bfs.c	2005-06-11 16:00:56.000000000 +0300
@@ -10,17 +10,12 @@
 #include <stdarg.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/ioctl.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <string.h>
 #include <time.h>
 #include "nls.h"
-
-/* cannot include <linux/fs.h> */
-#ifndef BLKGETSIZE
-#define BLKGETSIZE _IO(0x12,96)    /* return device size */
-#endif
+#include "disk_size.h"
 
 #define BFS_ROOT_INO		2
 #define BFS_NAMELEN		14
@@ -181,13 +176,9 @@
 	else if (optind != argc)
 		usage();
 
-	if (ioctl(fd, BLKGETSIZE, &total_blocks) == -1) {
-		if (!user_specified_total_blocks) {
-			perror("BLKGETSIZE");
-			fatal(_("cannot get size of %s"), device);
-		}
-		total_blocks = user_specified_total_blocks;
-	} else if (user_specified_total_blocks) {
+	total_blocks = disk_get_sectors(fd);
+
+	if (user_specified_total_blocks) {
 		if (user_specified_total_blocks > total_blocks)
 			fatal(_("blocks argument too large, max is %lu"),
 			      total_blocks);
diff -Naur util-linux-2.12q.orig/disk-utils/mkfs.minix.c util-linux-2.12q/disk-utils/mkfs.minix.c
--- util-linux-2.12q.orig/disk-utils/mkfs.minix.c	2004-08-25 01:32:36.000000000 +0300
+++ util-linux-2.12q/disk-utils/mkfs.minix.c	2005-06-11 16:00:56.000000000 +0300
@@ -68,16 +68,12 @@
 #include <stdlib.h>
 #include <termios.h>
 #include <sys/stat.h>
-#include <sys/ioctl.h>
 #include <mntent.h>
 #include <getopt.h>
 
 #include "minix.h"
 #include "nls.h"
-
-#ifndef BLKGETSIZE
-#define BLKGETSIZE _IO(0x12,96)    /* return device size */
-#endif
+#include "disk_size.h"
 
 #ifndef __GNUC__
 #error "needs gcc for the bitop-__asm__'s"
@@ -188,37 +184,6 @@
 }
 
 static long
-valid_offset (int fd, int offset) {
-	char ch;
-
-	if (lseek (fd, offset, 0) < 0)
-		return 0;
-	if (read (fd, &ch, 1) < 1)
-		return 0;
-	return 1;
-}
-
-static int
-count_blocks (int fd) {
-	int high, low;
-
-	low = 0;
-	for (high = 1; valid_offset (fd, high); high *= 2)
-		low = high;
-	while (low < high - 1)
-	{
-		const int mid = (low + high) / 2;
-
-		if (valid_offset (fd, mid))
-			low = mid;
-		else
-			high = mid;
-	}
-	valid_offset (fd, 0);
-	return (low + 1);
-}
-
-static int
 get_size(const char  *file) {
 	int	fd;
 	long	size;
@@ -228,12 +193,8 @@
 		perror(file);
 		exit(1);
 	}
-	if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
-		close(fd);
-		return (size * 512);
-	}
-		
-	size = count_blocks(fd);
+	size = disk_get_sectors(fd);
+
 	close(fd);
 	return size;
 }
@@ -676,8 +637,10 @@
      }
   }
 
-  if (device_name && !BLOCKS)
-    BLOCKS = get_size (device_name) / 1024;
+  if (device_name && !BLOCKS) {
+    int sectors_per_block = 1024 / 512;
+    BLOCKS = get_size (device_name) / sectors_per_block;
+  }
   if (!device_name || BLOCKS<10) {
     usage();
   }
diff -Naur util-linux-2.12q.orig/disk-utils/mkswap.c util-linux-2.12q/disk-utils/mkswap.c
--- util-linux-2.12q.orig/disk-utils/mkswap.c	2004-12-21 19:21:24.000000000 +0200
+++ util-linux-2.12q/disk-utils/mkswap.c	2005-06-11 16:00:56.000000000 +0300
@@ -36,13 +36,13 @@
 #include <string.h>
 #include <fcntl.h>
 #include <stdlib.h>
-#include <sys/ioctl.h>		/* for _IO */
 #include <sys/utsname.h>
 #include <sys/stat.h>
 #include "../defines.h"
 #include "swapheader.h"
 #include "xstrncpy.h"
 #include "nls.h"
+#include "disk_size.h"
 
 #ifdef HAVE_uuid_uuid_h
 #include <uuid/uuid.h>
@@ -59,14 +62,6 @@
 #endif
 #endif
 
-#ifndef _IO
-/* pre-1.3.45 */
-#define BLKGETSIZE 0x1260
-#else
-/* same on i386, m68k, arm; different on alpha, mips, sparc, ppc */
-#define BLKGETSIZE _IO(0x12,96)
-#endif
-
 static char * program_name = "mkswap";
 static char * device_name = NULL;
 static int DEV = -1;
@@ -438,39 +435,11 @@
 		printf(_("%lu bad pages\n"), badpages);
 }
 
-static long
-valid_offset (int fd, off_t offset) {
-	char ch;
-
-	if (lseek (fd, offset, 0) < 0)
-		return 0;
-	if (read (fd, &ch, 1) < 1)
-		return 0;
-	return 1;
-}
-
-static off_t
-find_size (int fd) {
-	off_t high, low;
-
-	low = 0;
-	for (high = 1; high > 0 && valid_offset (fd, high); high *= 2)
-		low = high;
-	while (low < high - 1) {
-		const off_t mid = (low + high) / 2;
-
-		if (valid_offset (fd, mid))
-			low = mid;
-		else
-			high = mid;
-	}
-	return (low + 1);
-}
-
 /* return size in pages, to avoid integer overflow */
 static unsigned long
 get_size(const char  *file) {
 	int	fd;
+	int	sectors_per_page = pagesize / 512;
 	unsigned long	size;
 
 	fd = open(file, O_RDONLY);
@@ -478,14 +447,10 @@
 		perror(file);
 		exit(1);
 	}
-	if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
-		int sectors_per_page = pagesize/512;
-		size /= sectors_per_page;
-	} else {
-		size = find_size(fd) / pagesize;
-	}
+	size = disk_get_sectors(fd);
+
 	close(fd);
-	return size;
+	return (size / sectors_per_page);
 }
 
 static int
diff -Naur util-linux-2.12q.orig/fdisk/cfdisk.c util-linux-2.12q/fdisk/cfdisk.c
--- util-linux-2.12q.orig/fdisk/cfdisk.c	2004-12-22 20:06:01.000000000 +0200
+++ util-linux-2.12q/fdisk/cfdisk.c	2005-06-11 16:00:56.000000000 +0300
@@ -77,11 +77,11 @@
 #include <math.h>
 #include <string.h>
 #include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <linux/types.h>
 
 #include "nls.h"
 #include "xstrncpy.h"
+#include "disk_size.h"
+#include "disk_geom.h"
 #include "common.h"
 
 extern long long ext2_llseek(unsigned int fd, long long offset,
@@ -89,8 +89,16 @@
 
 #define VERSION UTIL_LINUX_VERSION
 
+#ifdef __GNU__
+#define DEFAULT_DEVICE "/dev/hd0"
+#define ALTERNATE_DEVICE "/dev/sd0"
+#elif defined(__FreeBSD__)
+#define DEFAULT_DEVICE "/dev/ad0"
+#define ALTERNATE_DEVICE "/dev/da0"
+#else
 #define DEFAULT_DEVICE "/dev/hda"
 #define ALTERNATE_DEVICE "/dev/sda"
+#endif
 
 /* With K=1024 we have `binary' megabytes, gigabytes, etc.
    Some misguided hackers like that.
@@ -172,7 +180,7 @@
 long long cylinders = 0;
 int cylinder_size = 0;		/* heads * sectors */
 long long total_size = 0;	/* actual_size rounded down */
-long long actual_size = 0;	/* (in 512-byte sectors) - set using ioctl */
+long long actual_size = 0;	/* (in 512-byte sectors) */
 				/* explicitly given user values */
 int user_heads = 0, user_sectors = 0;
 long long user_cylinders = 0;
@@ -1522,18 +1530,6 @@
 	    print_warning(errmsg);
 }
 
-static void
-get_kernel_geometry(void) {
-#ifdef HDIO_GETGEO
-    struct hd_geometry geometry;
-
-    if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
-	kern_heads = geometry.heads;
-	kern_sectors = geometry.sectors;
-    }
-#endif
-}
-
 static int
 said_yes(char answer) {
 #ifdef HAVE_rpmatch
@@ -1655,7 +1651,7 @@
 fill_p_info(void) {
     int pn, i;
     long long bs, bsz;
-    unsigned long long llsectors;
+    struct disk_geom g;
     struct partition *p;
     partition_table buffer;
     partition_info tmp_ext = { 0, 0, 0, 0, FREE_SPACE, PRIMARY };
@@ -1674,23 +1670,15 @@
 	 opentype = O_RDWR;
     opened = TRUE;
 
-    /* Blocks are visible in more than one way:
-       e.g. as block on /dev/hda and as block on /dev/hda3
-       By a bug in the Linux buffer cache, we will see the old
-       contents of /dev/hda when the change was made to /dev/hda3.
-       In order to avoid this, discard all blocks on /dev/hda.
-       Note that partition table blocks do not live in /dev/hdaN,
-       so this only plays a role if we want to show volume labels. */
-    ioctl(fd, BLKFLSBUF);	/* ignore errors */
-				/* e.g. Permission Denied */
-
-    if (disksize(fd, &llsectors))
-	    fatal(_("Cannot get disk size"), 3);
-    actual_size = llsectors;
+    disk_flush_cache(fd);
+
+    actual_size = disk_get_sectors(fd);
 
     read_sector(buffer.c.b, 0);
 
-    get_kernel_geometry();
+    disk_get_geometry(fd, &g);
+    kern_heads = g.heads;
+    kern_sectors = g.sectors;
 
     if (!zero_table || use_partition_table_geometry)
 	get_partition_table_geometry(& buffer);
@@ -1892,12 +1880,8 @@
 	}
 
     if (is_bdev) {
-	 sync();
-	 sleep(2);
-	 if (!ioctl(fd,BLKRRPART))
+	 if (disk_reread_partition_table(fd) == 0)
 	      changed = TRUE;
-	 sync();
-	 sleep(4);
 
 	 clear_warning();
 	 if (changed)
diff -Naur util-linux-2.12q.orig/fdisk/common.h util-linux-2.12q/fdisk/common.h
--- util-linux-2.12q.orig/fdisk/common.h	2004-09-06 21:07:11.000000000 +0300
+++ util-linux-2.12q/fdisk/common.h	2005-06-11 16:00:56.000000000 +0300
@@ -1,25 +1,5 @@
 /* common stuff for fdisk, cfdisk, sfdisk */
 
-/* including <linux/fs.h> fails */
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#define BLKRRPART    _IO(0x12,95)    /* re-read partition table */
-#define BLKGETSIZE   _IO(0x12,96)    /* return device size */
-#define BLKFLSBUF    _IO(0x12,97)    /* flush buffer cache */
-#define BLKSSZGET    _IO(0x12,104)   /* get block device sector size */
-#define BLKGETSIZE64 _IOR(0x12,114,size_t)	/* size in bytes */
-
-/* including <linux/hdreg.h> also fails */
-struct hd_geometry {
-      unsigned char heads;
-      unsigned char sectors;
-      unsigned short cylinders;
-      unsigned long start;
-};
-
-#define HDIO_GETGEO		0x0301	/* get device geometry */
-
-
 struct systypes {
 	unsigned char type;
 	char *name;
@@ -29,4 +9,3 @@
 
 extern char *partname(char *dev, int pno, int lth);
 
-int disksize(int fd, unsigned long long *sectors);
diff -Naur util-linux-2.12q.orig/fdisk/disksize.c util-linux-2.12q/fdisk/disksize.c
--- util-linux-2.12q.orig/fdisk/disksize.c	2004-12-14 03:52:07.000000000 +0200
+++ util-linux-2.12q/fdisk/disksize.c	1970-01-01 02:00:00.000000000 +0200
@@ -1,17 +0,0 @@
-#include "common.h"
-
-int disksize(int fd, unsigned long long *sectors) {
-	int err;
-	long sz;
-	long long b;
-
-	err = ioctl(fd, BLKGETSIZE, &sz);
-	if (err)
-		return err;
-	err = ioctl(fd, BLKGETSIZE64, &b);
-	if (err || b == 0 || b == sz)
-		*sectors = sz;
-	else
-		*sectors = (b >> 9);
-	return 0;
-}
diff -Naur util-linux-2.12q.orig/fdisk/fdisk.8 util-linux-2.12q/fdisk/fdisk.8
--- util-linux-2.12q.orig/fdisk/fdisk.8	2004-08-24 16:29:15.000000000 +0300
+++ util-linux-2.12q/fdisk/fdisk.8	2005-06-11 16:00:56.000000000 +0300
@@ -132,7 +132,7 @@
 Partitions beginning in cylinder 1 cannot begin on a cylinder boundary, but
 this is unlikely to cause difficulty unless you have OS/2 on your machine.
 
-A sync() and a BLKRRPART ioctl() (reread partition table from disk)
+A sync() and a disk_reread_partition_table()
 are performed before exiting when the partition table has been updated.
 Long ago it used to be necessary to reboot after the use of fdisk.
 I do not think this is the case anymore - indeed, rebooting too quickly
diff -Naur util-linux-2.12q.orig/fdisk/fdisk.c util-linux-2.12q/fdisk/fdisk.c
--- util-linux-2.12q.orig/fdisk/fdisk.c	2004-12-18 04:00:31.000000000 +0200
+++ util-linux-2.12q/fdisk/fdisk.c	2005-06-11 16:00:56.000000000 +0300
@@ -21,6 +21,8 @@
 
 #include "nls.h"
 #include "common.h"
+#include "disk_size.h"
+#include "disk_geom.h"
 #include "fdisk.h"
 
 #include "fdisksunlabel.h"
@@ -220,11 +222,6 @@
 			snprintf(error, sizeof(error),
 				_("Unable to write %s\n"), disk_device);
 			break;
-		case ioctl_error:
-			snprintf(error, sizeof(error),
-				 _("BLKGETSIZE ioctl failed on %s\n"),
-				disk_device);
-			break;
 		case out_of_memory:
 			message = _("Unable to allocate any more memory\n");
 			break;
@@ -736,73 +733,29 @@
 	get_boot(create_empty_dos);
 }
 
-#include <sys/utsname.h>
-#define MAKE_VERSION(p,q,r)     (65536*(p) + 256*(q) + (r))
-
-static int
-linux_version_code(void) {
-	static int kernel_version = 0;
-        struct utsname my_utsname;
-        int p, q, r;
-
-        if (!kernel_version && uname(&my_utsname) == 0) {
-                p = atoi(strtok(my_utsname.release, "."));
-                q = atoi(strtok(NULL, "."));
-                r = atoi(strtok(NULL, "."));
-                kernel_version = MAKE_VERSION(p,q,r);
-        }
-        return kernel_version;
-}
-
 static void
 get_sectorsize(int fd) {
-#if defined(BLKSSZGET)
-	if (!user_set_sector_size &&
-	    linux_version_code() >= MAKE_VERSION(2,3,3)) {
-		int arg;
-		if (ioctl(fd, BLKSSZGET, &arg) == 0)
-			sector_size = arg;
+	/* maybe the user specified it; and otherwise we still
+	   have the DEFAULT_SECTOR_SIZE default */
+	if (!user_set_sector_size) {
+		sector_size = disk_get_sector_size(fd);
 		if (sector_size != DEFAULT_SECTOR_SIZE)
 			printf(_("Note: sector size is %d (not %d)\n"),
 			       sector_size, DEFAULT_SECTOR_SIZE);
 	}
-#else
-	/* maybe the user specified it; and otherwise we still
-	   have the DEFAULT_SECTOR_SIZE default */
-#endif
-}
-
-static void
-get_kernel_geometry(int fd) {
-#ifdef HDIO_GETGEO
-	struct hd_geometry geometry;
-
-	if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
-		kern_heads = geometry.heads;
-		kern_sectors = geometry.sectors;
-		/* never use geometry.cylinders - it is truncated */
-	}
-#endif
 }
 
 static int
 is_probably_full_disk(char *name) {
-#ifdef HDIO_GETGEO
-	struct hd_geometry geometry;
-	int fd, i = 0;
+	struct disk_geom geometry;
+	int fd;
 
 	fd = open(name, O_RDONLY);
 	if (fd >= 0) {
-		i = ioctl(fd, HDIO_GETGEO, &geometry);
+		disk_get_geometry(fd, &geometry);
 		close(fd);
 	}
-	return (fd >= 0 && i == 0 && geometry.start == 0);
-#else
-	/* silly heuristic */
-	while (*name)
-		name++;
-	return !isdigit(name[-1]);
-#endif
+	return (fd >= 0 && geometry.start == 0);
 }
 
 static void
@@ -840,7 +793,8 @@
 void
 get_geometry(int fd, struct geom *g) {
 	int sec_fac;
-	unsigned long long llsectors, llcyls;
+	unsigned long long llcyls;
+	struct disk_geom dg;
 
 	get_sectorsize(fd);
 	sec_fac = sector_size / 512;
@@ -849,7 +803,10 @@
 	kern_heads = kern_sectors = 0;
 	pt_heads = pt_sectors = 0;
 
-	get_kernel_geometry(fd);
+	disk_get_geometry(fd, &dg);
+	kern_heads = dg.heads;
+	kern_sectors = dg.sectors;
+
 	get_partition_table_geometry();
 
 	heads = user_heads ? user_heads :
@@ -859,10 +816,7 @@
 		pt_sectors ? pt_sectors :
 		kern_sectors ? kern_sectors : 63;
 
-	if (disksize(fd, &llsectors))
-		llsectors = 0;
-
-	total_number_of_sectors = llsectors;
+	total_number_of_sectors = disk_get_sectors(fd);
 
 	sector_offset = 1;
 	if (dos_compatible_flag)
@@ -2160,24 +2114,11 @@
 void
 reread_partition_table(int leave) {
 	int error = 0;
-	int i;
 
-	printf(_("Calling ioctl() to re-read partition table.\n"));
-	sync();
-	sleep(2);
-	if ((i = ioctl(fd, BLKRRPART)) != 0) {
-                error = errno;
-        } else {
-                /* some kernel versions (1.2.x) seem to have trouble
-                   rereading the partition table, but if asked to do it
-		   twice, the second time works. - biro@yggdrasil.com */
-                sync();
-                sleep(2);
-                if ((i = ioctl(fd, BLKRRPART)) != 0)
-                        error = errno;
-        }
+	printf(_("Asking the kernel to to re-read partition table.\n"));
+	error = disk_reread_partition_table(fd);
 
-	if (i) {
+	if (error) {
 		printf(_("\nWARNING: Re-reading the partition table "
 			 "failed with error %d: %s.\n"
 			 "The kernel still uses the old table.\n"
@@ -2201,7 +2142,7 @@
 		printf(_("Syncing disks.\n"));
 		sync();
 		sleep(4);		/* for sync() */
-		exit(!!i);
+		exit(!!error);
 	}
 }
 
@@ -2564,8 +2505,7 @@
 			disk_device = argv[j];
 			if ((fd = open(disk_device, type_open)) < 0)
 				fatal(unable_to_open);
-			if (disksize(fd, &size))
-				fatal(ioctl_error);
+			size = disk_get_sectors(fd);
 			close(fd);
 			if (opts == 1)
 				printf("%llu\n", size/2);
diff -Naur util-linux-2.12q.orig/fdisk/fdisksgilabel.c util-linux-2.12q/fdisk/fdisksgilabel.c
--- util-linux-2.12q.orig/fdisk/fdisksgilabel.c	2004-12-18 03:53:45.000000000 +0200
+++ util-linux-2.12q/fdisk/fdisksgilabel.c	2005-06-11 16:00:56.000000000 +0300
@@ -16,6 +16,7 @@
 #include <stdlib.h>		/* exit */
 #include <string.h>             /* strstr */
 #include <unistd.h>             /* write */
-#include <sys/ioctl.h>          /* ioctl */
 #include <sys/stat.h>           /* stat */
 #include <assert.h>             /* assert */
 
@@ -689,15 +687,13 @@
 void
 create_sgilabel(void)
 {
-	struct hd_geometry geometry;
+	struct geom geometry;
 	struct {
 		unsigned int start;
 		unsigned int nsect;
 		int sysid;
 	} old[4];
 	int i=0;
-	unsigned long long llsectors;
-	int res; 		/* the result from the ioctl */
 	int sec_fac; 		/* the sector factor */
 
 	sec_fac = sector_size / 512;	/* determine the sector factor */
@@ -709,28 +705,8 @@
 
 	other_endian = (BYTE_ORDER == LITTLE_ENDIAN);
 
-	res = disksize(fd, &llsectors);
+	get_geometry(fd, &geometry);
 
-	if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
-		heads = geometry.heads;
-		sectors = geometry.sectors;
-		if (res == 0) {
-			/* the get device size ioctl was successful */
-			unsigned long long llcyls;
-			llcyls = llsectors / (heads * sectors * sec_fac);
-			cylinders = llcyls;
-			if (cylinders != llcyls)	/* truncated? */
-				cylinders = ~0;
-		} else {
-			/* otherwise print error and use truncated version */
-			cylinders = geometry.cylinders;
-			fprintf(stderr,
-				_("Warning:  BLKGETSIZE ioctl failed on %s.  "
-				  "Using geometry cylinder value of %d.\n"
-				  "This value may be truncated for devices"
-				  " > 33.8 GB.\n"), disk_device, cylinders);
-		}
-	}
 	for (i = 0; i < 4; i++) {
 		old[i].sysid = 0;
 		if (valid_part_table_flag(MBRbuffer)) {
diff -Naur util-linux-2.12q.orig/fdisk/fdisksunlabel.c util-linux-2.12q/fdisk/fdisksunlabel.c
--- util-linux-2.12q.orig/fdisk/fdisksunlabel.c	2004-12-22 17:36:24.000000000 +0200
+++ util-linux-2.12q/fdisk/fdisksunlabel.c	2005-06-11 16:00:56.000000000 +0300
@@ -249,7 +255,7 @@
 
 void create_sunlabel(void)
 {
-	struct hd_geometry geometry;
+	struct geom geometry;
 	unsigned int ndiv;
 	int i;
 	unsigned char c;
@@ -296,15 +302,8 @@
 	    }
 	}
 	if (!p || floppy) {
-	    if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
-	        heads = geometry.heads;
-	        sectors = geometry.sectors;
-	        cylinders = geometry.cylinders;
-	    } else {
-	        heads = 0;
-	        sectors = 0;
-	        cylinders = 0;
-	    }
+	    get_geometry(fd, &geometry);
+
 	    if (floppy) {
 	        sunlabel->nacyl = 0;
 	        sunlabel->pcylcount = SSWAP16(cylinders);
diff -Naur util-linux-2.12q.orig/fdisk/Makefile util-linux-2.12q/fdisk/Makefile
--- util-linux-2.12q.orig/fdisk/Makefile	2004-09-06 23:28:58.000000000 +0300
+++ util-linux-2.12q/fdisk/Makefile	2005-06-11 17:10:59.000000000 +0300
@@ -39,7 +39,8 @@
 endif
 endif
 
-cfdisk: cfdisk.o llseek.o disksize.o i386_sys_types.o $(LIB)/xstrncpy.o
+cfdisk: cfdisk.o llseek.o i386_sys_types.o $(LIB)/xstrncpy.o \
+		$(LIB)/disk_size.o $(LIB)/disk_geom.o
 ifeq "$(HAVE_SLANG)" "yes"
 	$(CC) $(LDFLAGS) $^ -o $@ $(LIBSLANG)
 else
@@ -55,15 +56,17 @@
 	rm -f activate
 	ln -s sfdisk activate
 
-fdisk: fdisk.o llseek.o disksize.o fdiskbsdlabel.o fdisksgilabel.o \
-	fdisksunlabel.o fdiskaixlabel.o i386_sys_types.o partname.o
+fdisk: fdisk.o llseek.o fdiskbsdlabel.o fdisksgilabel.o fdisksunlabel.o \
+	fdiskaixlabel.o i386_sys_types.o partname.o \
+	$(LIB)/disk_geom.o $(LIB)/disk_size.o
 fdisk.o: fdisk.c fdisk.h
 fdiskbsdlabel.o: fdiskbsdlabel.c fdisk.h fdiskbsdlabel.h
 fdisksunlabel.o: fdisksunlabel.c fdisksunlabel.h fdisk.h
 fdiskaixlabel.o: fdiskaixlabel.c fdiskaixlabel.h fdisk.h
 fdisk.o cfdisk.o sfdisk.o fdiskbsdlabel.o fdisksunlabel.o \
 	fdisksgilabel.o fdiskaixlabel.o i386_sys_types.o partname.o: common.h
-sfdisk: sfdisk.o disksize.o i386_sys_types.o partname.o
+sfdisk: sfdisk.o i386_sys_types.o partname.o \
+	llseek.o $(LIB)/disk_size.o $(LIB)/disk_geom.o
 
 install: all
 	$(INSTALLDIR) $(SBINDIR)
diff -Naur util-linux-2.12q.orig/fdisk/README.fdisk util-linux-2.12q/fdisk/README.fdisk
--- util-linux-2.12q.orig/fdisk/README.fdisk	2002-04-22 02:57:13.000000000 +0300
+++ util-linux-2.12q/fdisk/README.fdisk	2005-06-11 16:00:56.000000000 +0300
@@ -414,7 +414,7 @@
 precaution.  After giving the Write command, you will see this message:
 
      The partition table has been altered!
-     Calling ioctl() to re-read partition table.
+     Asking the kernel to to re-read partition table.
      Syncing disks.
 
 If there are no further messages, the kernel has successfully copied
diff -Naur util-linux-2.12q.orig/fdisk/sfdisk.8 util-linux-2.12q/fdisk/sfdisk.8
--- util-linux-2.12q.orig/fdisk/sfdisk.8	2004-12-31 17:17:55.000000000 +0200
+++ util-linux-2.12q/fdisk/sfdisk.8	2005-06-11 16:00:56.000000000 +0300
@@ -292,9 +292,9 @@
 Go through all the motions, but do not actually write to disk.
 .TP
 .B \-R
-Only execute the BLKRRPART ioctl (to make the kernel re-read
+Only execute the disk_reread_partition_table (to make the kernel re-read
 the partition table). This can be useful for checking in advance
-that the final BLKRRPART will be successful, and also when you
+that the final call to this function will be successful, and also when you
 changed the partition table `by hand' (e.g., using dd from a backup).
 If the kernel complains (`device busy for revalidation (usage = 2)')
 then something still uses the device, and you still have to unmount
diff -Naur util-linux-2.12q.orig/fdisk/sfdisk.c util-linux-2.12q/fdisk/sfdisk.c
--- util-linux-2.12q.orig/fdisk/sfdisk.c	2005-01-05 00:31:57.000000000 +0200
+++ util-linux-2.12q/fdisk/sfdisk.c	2005-06-11 16:59:10.000000000 +0300
@@ -45,13 +45,14 @@
 #include <string.h>		/* index() */
 #include <ctype.h>
 #include <getopt.h>
-#include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <sys/utsname.h>
 #include <linux/unistd.h>	/* _syscall */
 #include "nls.h"
+#include "disk_geom.h"
+#include "disk_size.h"
 #include "common.h"
 
 #define SIZE(a)	(sizeof(a)/sizeof(a[0]))
 
 /*
@@ -78,7 +84,7 @@
 int dump = 0;           /* 1: list in a format suitable for later input */
 int verify = 0;         /* 1: check that listed partition is reasonable */
 int no_write = 0;	/* 1: do not actually write to disk */
-int no_reread = 0;	/* 1: skip the BLKRRPART ioctl test at startup */
+int no_reread = 0;	/* 1: skip the reread partition test at startup */
 int leave_last = 0;	/* 1: don't allocate the last cylinder */
 int opt_list = 0;
 char *save_sector_file = NULL;
@@ -414,18 +406,6 @@
  */
 
 /*
- * <linux/hdreg.h> defines HDIO_GETGEO and
- * struct hd_geometry {
- *      unsigned char heads;
- *      unsigned char sectors;
- *      unsigned short cylinders;
- *      unsigned long start;
- * };
- *
- * For large disks g.cylinders is truncated, so we use BLKGETSIZE.
- */
-
-/*
  * We consider several geometries for a disk:
  * B - the BIOS geometry, gotten from the kernel via HDIO_GETGEO
  * F - the fdisk geometry
@@ -442,25 +422,25 @@
 
 static struct geometry
 get_geometry(char *dev, int fd, int silent) {
-    struct hd_geometry g;
+    struct disk_geom g;
     unsigned long cyls;
     unsigned long long sectors;
     struct geometry R;
 
-    if (ioctl(fd, HDIO_GETGEO, &g)) {
-	g.heads = g.sectors = g.cylinders = g.start = 0;
+    if (disk_get_geometry(fd, &g)) {
+	R.heads = g.heads;
+	R.sectors = g.sectors;
+	R.cylindersize = R.heads * R.sectors;
+	R.cylinders = 0;
+	R.start = g.start;
+    } else {
+	R.heads = R.sectors = R.cylindersize = R.cylinders = R.start = 0;
 	if (!silent)
 	    do_warn(_("Disk %s: cannot get geometry\n"), dev);
     }
 
-    R.start = g.start;
-    R.heads = g.heads;
-    R.sectors = g.sectors;
-    R.cylindersize = R.heads * R.sectors;
-    R.cylinders = 0;
-    R.total_size = 0;
-
-    if (disksize(fd, &sectors)) {
+    sectors = disk_get_sectors(fd);
+    if (!sectors) {
 	/* maybe an ordinary file */
 	struct stat s;
 
@@ -788,19 +768,6 @@
     }
 }
 
-/* tell the kernel to reread the partition tables */
-static int
-reread_ioctl(int fd) {
-    if (ioctl(fd, BLKRRPART)) {
-	perror("BLKRRPART");
-
-	/* 2.6.8 returns EIO for a zero table */
-	if (errno == EBUSY)
-		return -1;
-    }
-    return 0;
-}
-
 static int
 is_blockdev(int fd) {
     struct stat statbuf;
@@ -816,7 +783,7 @@
     sync();
     sleep(3);			/* superfluous since 1.3.20 */
 
-    if (reread_ioctl(fd) && is_blockdev(fd))
+    if (disk_reread_partition_table(fd) && is_blockdev(fd))
       do_warn(_("The command to re-read the partition table failed\n"
 	     "Reboot your system now, before using mkfs\n"));
 
@@ -2436,15 +2409,15 @@
 
 static int
 is_probably_full_disk(char *name) {
-	struct hd_geometry geometry;
-	int fd, i = 0;
+	struct disk_geom geometry;
+	int fd;
 
 	fd = open(name, O_RDONLY);
 	if (fd >= 0) {
-		i = ioctl(fd, HDIO_GETGEO, &geometry);
+		disk_get_geometry(fd, &geometry);
 		close(fd);
 	}
-	return (fd >= 0 && i == 0 && geometry.start == 0);
+	return (fd >= 0 && geometry.start == 0);
 }
 
 #define PROC_PARTITIONS	"/proc/partitions"
@@ -2801,7 +2774,8 @@
     if (fd < 0)
 	return;
 
-    if (disksize(fd, &size)) {
+    size = disk_get_sectors(fd);
+    if (!size) {
 	if (!silent) {
 	    perror(dev);
 	    fatal(_("Cannot get size of %s\n"), dev);
@@ -2994,7 +2968,7 @@
     int fd;
 
     fd = my_open(dev, 0, 0);
-    if (reread_ioctl(fd))
+    if (disk_reread_partition_table(fd))
       do_warn(_("This disk is currently in use.\n"));
 }
 
@@ -3022,7 +2996,7 @@
 
     if (!no_write && !no_reread) {
 	warn(_("Checking that no-one is using this disk right now ...\n"));
-	if (reread_ioctl(fd)) {
+	if (disk_reread_partition_table(fd)) {
 	    do_warn(_("\nThis disk is currently in use - repartitioning is probably a bad idea.\n"
 		   "Umount all file systems, and swapoff all swap partitions on this disk.\n"
 		   "Use the --no-reread flag to suppress this check.\n"));
diff -Naur util-linux-2.12q.orig/fdisk/sfdisk.examples util-linux-2.12q/fdisk/sfdisk.examples
--- util-linux-2.12q.orig/fdisk/sfdisk.examples	1999-07-09 05:56:35.000000000 +0300
+++ util-linux-2.12q/fdisk/sfdisk.examples	2005-06-11 16:00:56.000000000 +0300
@@ -4,9 +4,9 @@
 
 Before doing anything with a disk, make sure it is not in use;
 unmount all its file systems, and say swapoff to its swap partitions.
-(The final BLKRRPART ioctl will fail if anything else still uses
-the disk, and you will have to reboot. It is easier to first make
-sure that nothing uses the disk, e.g., by testing:
+(The function disk_reread_partition_table will fail if anything else
+still uses the disk, and you will have to reboot. It is easier to first
+make sure that nothing uses the disk, e.g., by testing:
 	% umount /dev/sdb1
 	% sfdisk -R /dev/sdb
 	BLKRRPART: Device or resource busy
diff -Naur util-linux-2.12q.orig/lib/disk_geom.c util-linux-2.12q/lib/disk_geom.c
--- util-linux-2.12q.orig/lib/disk_geom.c	1970-01-01 02:00:00.000000000 +0200
+++ util-linux-2.12q/lib/disk_geom.c	2005-06-11 18:01:08.438487192 +0300
@@ -0,0 +1,114 @@
+#include "disk_geom.h"
+
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <unistd.h>
+
+#ifdef __linux__
+
+/* including <linux/fs.h> fails */
+#define BLKRRPART    _IO(0x12,95)	/* re-read partition table */
+#define BLKFLSBUF    _IO(0x12,97)	/* flush buffer cache */
+#define BLKGETSIZE64 _IOR(0x12,114,8)	/* 8 = sizeof(u64) */
+
+/*
+ * For large disks g.cylinders is truncated, so we use BLKGETSIZE.
+ */
+
+/* including <linux/hdreg.h> also fails */
+struct hd_geometry {
+      unsigned char heads;
+      unsigned char sectors;
+      unsigned short cylinders;
+      unsigned long start;
+};
+
+#define HDIO_GETGEO		0x0301	/* get device geometry */
+
+#elif defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__NetBSD__)
+#include <sys/disklabel.h>
+#endif
+
+
+int
+disk_get_geometry(int fd, struct disk_geom *geometry)
+{
+	int error = 0;
+#ifdef __linux__
+	struct hd_geometry linux_geom;
+
+	if (!ioctl(fd, HDIO_GETGEO, &linux_geom)) {
+		geometry->cylinders = linux_geom.cylinders;
+		geometry->heads = linux_geom.heads;
+		geometry->sectors = linux_geom.sectors;
+		geometry->start = linux_geom.start;
+		error = 1;
+	}
+#elif defined(__FreeBSD_kernel__)
+	struct disklabel dlabel;
+
+	if (!ioctl(fd, DIOCGDINFO, &dlabel)) {
+		geometry->cylinders = dlabel.d_ncylinders;
+		geometry->heads = dlabel.d_ntracks;
+		geometry->sectors = dlabel.d_nsectors;
+		geometry->start = 0;
+		error = 1;
+	}
+#endif
+
+	return error;
+}
+
+int
+disk_flush_cache(int fd)
+{
+#ifdef __linux__
+	/*
+	 * Blocks are visible in more than one way:
+	 * e.g. as block on /dev/hda and as block on /dev/hda3
+	 * By a bug in the Linux buffer cache, we will see the old
+	 * contents of /dev/hda when the change was made to /dev/hda3.
+	 * In order to avoid this, discard all blocks on /dev/hda.
+	 * Note that partition table blocks do not live in /dev/hdaN,
+	 * so this only plays a role if we want to show volume labels.
+	 */
+	ioctl(fd, BLKFLSBUF);	/* ignore errors */
+				/* e.g. Permission Denied */
+#else
+	sync();
+#endif
+
+	return 0;
+}
+
+int
+disk_reread_partition_table(int fd)
+{
+	int error = 0;
+
+#ifdef __linux__
+	sync();
+	sleep(2);
+	error = ioctl(fd,BLKRRPART);
+	if (error != 0)
+		error = errno;
+	else {
+		/* Some kernel versions (1.2.x) seem to have trouble
+		 * rereading the partition table, but if asked to do it
+		 * twice, the second time works.  -- biro@yggdrasil.com
+		 */
+		sync();
+		sleep(2);
+		error = ioctl(fd, BLKRRPART);
+		if (error != 0)
+			error = errno;
+        }
+	sync();
+	sleep(4);
+#else
+	error = ENOSYS;
+#endif
+
+	return error;
+}
+
diff -Naur util-linux-2.12q.orig/lib/disk_geom.h util-linux-2.12q/lib/disk_geom.h
--- util-linux-2.12q.orig/lib/disk_geom.h	1970-01-01 02:00:00.000000000 +0200
+++ util-linux-2.12q/lib/disk_geom.h	2005-06-11 16:00:56.000000000 +0300
@@ -0,0 +1,18 @@
+#ifndef DISK_GEOM_H
+#define DISK_GEOM_H
+
+#include <sys/types.h>
+
+struct disk_geom {
+	unsigned int heads;
+	unsigned int sectors;
+	unsigned int cylinders;
+	off_t start;
+};
+
+extern int disk_get_geometry(int fd, struct disk_geom *geometry);
+extern int disk_reread_partition_table(int fd);
+extern int disk_flush_cache(int fd);
+
+#endif
+
diff -Naur util-linux-2.12q.orig/lib/disk_size.c util-linux-2.12q/lib/disk_size.c
--- util-linux-2.12q.orig/lib/disk_size.c	1970-01-01 02:00:00.000000000 +0200
+++ util-linux-2.12q/lib/disk_size.c	2005-06-11 18:03:31.844686136 +0300
@@ -0,0 +1,161 @@
+/*
+ * unsigned long disk_get_sectors (int fd)
+ *
+ * 	returns the number of 512-byte sectors of fd
+ *
+ * Most code ripped from:
+ * 
+ * 	mkswap.c
+ * 	mkfs.bfs.c
+ * 	mkfs.minix.c
+ *
+ * by Guillem Jover <guillem@debian.org>
+ * 
+ */
+
+#include "../defines.h"
+#include "disk_size.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __linux__
+/* cannot #include <linux/fs.h>, because it uses u64... */
+#ifndef BLKGETSIZE
+/* return device size */
+#ifndef _IO
+/* pre-1.3.45 */
+#define BLKGETSIZE 0x1260
+#else
+/* same on i386, m68k, arm; different on alpha, mips, sparc, ppc */
+#define BLKGETSIZE	_IO(0x12,96)	/* return device size */
+#define BLKSSZGET	_IO(0x12,104)	/* get block device sector size */
+#define BLKGETSIZE64	_IOR(0x12,114,size_t)	/* size in bytes */
+#endif
+#endif
+#elif defined(__FreeBSD_kernel__)
+#define DIOCGMEDIASIZE	_IOR('d', 129, off_t)
+#define DIOCGSECTORSIZE	_IOR('d', 128, u_int)
+#endif
+
+static int
+valid_offset (int fd, off_t offset)
+{
+	char ch;
+
+	if (lseek (fd, offset, 0) < 0)
+		return 0;
+	if (read (fd, &ch, 1) < 1)
+		return 0;
+	return 1;
+}
+
+static off_t
+count_sectors (int fd)
+{
+	off_t high, low, sectors;
+
+	low = 0;
+	for (high = 1; high > 0 && valid_offset (fd, high); high *= 2)
+		low = high;
+	while (low < high - 1) {
+		const off_t mid = (low + high) / 2;
+
+		if (valid_offset (fd, mid))
+			low = mid;
+		else
+			high = mid;
+	}
+	sectors = (low + 1) / 512;
+	return sectors;
+}
+
+off_t
+disk_get_sectors (int fd)
+{
+	struct stat st;
+	off_t sectors = 0;
+
+#ifdef __linux__
+	{
+		unsigned long ioctl_sectors;
+		off_t bytes;
+
+		if (ioctl(fd, BLKGETSIZE, &ioctl_sectors))
+			ioctl_sectors = 0;
+		if (ioctl(fd, BLKGETSIZE64, &bytes))
+			bytes = 0;
+
+		/*
+		 * If BLKGETSIZE64 was unknown or broken, use sectors.
+		 * (Kernels 2.4.15-2.4.17 had a broken BLKGETSIZE64
+		 * that returns sectors instead of bytes.)
+		 */
+		if (bytes != 0 && ioctl_sectors != 0) {
+			if (bytes == ioctl_sectors)
+				sectors = ioctl_sectors;
+			else
+				sectors = bytes >> 9;
+		} else if (bytes != 0) {
+			sectors = bytes >> 9;
+		} else if (ioctl_sectors != 0) {
+			sectors = ioctl_sectors;
+		}
+
+		return sectors;
+	}
+#elif defined(__FreeBSD_kernel__)
+	{
+		ioctl(fd, DIOCGMEDIASIZE, &sectors);
+		return sectors;
+	}
+#endif
+
+	if (fstat(fd, &st) == 0)
+		return st.st_size / 512;
+
+	return count_sectors(fd);
+}
+
+#ifdef __linux__
+#include <sys/utsname.h>
+#define MAKE_VERSION(p,q,r)     (65536*(p) + 256*(q) + (r))
+
+static int
+linux_version_code(void) {
+	static int kernel_version = 0;
+	struct utsname my_utsname;
+	int p, q, r;
+
+	if (!kernel_version && uname(&my_utsname) == 0) {
+		p = atoi(strtok(my_utsname.release, "."));
+		q = atoi(strtok(NULL, "."));
+		r = atoi(strtok(NULL, "."));
+		kernel_version = MAKE_VERSION(p,q,r);
+	}
+	return kernel_version;
+}
+#endif
+
+int
+disk_get_sector_size (int fd)
+{
+	int sector_size = 512;
+
+#ifdef __linux__
+	if (linux_version_code() >= MAKE_VERSION(2,3,3)) {
+		int arg;
+
+		if (ioctl(fd, BLKSSZGET, &arg) == 0)
+			sector_size = arg;
+	}
+#elif defined(__FreeBSD_kernel__)
+	ioctl(fd, DIOCGSECTORSIZE, &sector_size);
+#endif
+
+	return sector_size;
+}
+
diff -Naur util-linux-2.12q.orig/lib/disk_size.h util-linux-2.12q/lib/disk_size.h
--- util-linux-2.12q.orig/lib/disk_size.h	1970-01-01 02:00:00.000000000 +0200
+++ util-linux-2.12q/lib/disk_size.h	2005-06-11 16:00:56.000000000 +0300
@@ -0,0 +1,10 @@
+#ifndef DISK_SIZE_H
+#define DISK_SIZE_H
+
+#include <sys/types.h>
+
+extern off_t disk_get_sectors (int fd);
+extern int disk_get_sector_size (int fd);
+
+#endif
+
diff -Naur util-linux-2.12q.orig/lib/Makefile util-linux-2.12q/lib/Makefile
--- util-linux-2.12q.orig/lib/Makefile	2002-11-02 15:51:26.000000000 +0200
+++ util-linux-2.12q/lib/Makefile	2005-06-11 16:00:56.000000000 +0300
@@ -1,7 +1,9 @@
 include ../make_include
 include ../MCONFIG
 
-all: err.o my_reboot.o setproctitle.o env.o carefulputc.o xstrncpy.o md5.o
+all: err.o my_reboot.o setproctitle.o env.o carefulputc.o md5.o \
+	xstrncpy.o disk_geom.o disk_size.o
 
 err.o: err.c
 
@@ -15,6 +16,10 @@
 
 xstrncpy.o: xstrncpy.h
 
+disk_geom.o: disk_geom.h
+
+disk_size.o: disk_size.h
+
 md5.o: md5.c md5.h
 
 .PHONY: clean
diff -Naur util-linux-2.12q.orig/mount/linux_fs.h util-linux-2.12q/mount/linux_fs.h
--- util-linux-2.12q.orig/mount/linux_fs.h	2004-12-21 19:04:08.000000000 +0200
+++ util-linux-2.12q/mount/linux_fs.h	2005-06-11 16:00:56.000000000 +0300
@@ -3,16 +3,6 @@
    only designed to be able to check a magic number
    in case no filesystem type was given. */
 
-#ifndef BLKGETSIZE
-#ifndef _IO
-/* pre-1.3.45 */
-#define BLKGETSIZE 0x1260		   /* return device size */
-#else
-/* same on i386, m68k, arm; different on alpha, mips, sparc, ppc */
-#define BLKGETSIZE _IO(0x12,96)
-#endif
-#endif
-
 #define MINIX_SUPER_MAGIC   0x137F         /* minix v1, 14 char names */
 #define MINIX_SUPER_MAGIC2  0x138F         /* minix v1, 30 char names */
 #define MINIX2_SUPER_MAGIC  0x2468	   /* minix v2, 14 char names */
diff -Naur util-linux-2.12q.orig/mount/Makefile util-linux-2.12q/mount/Makefile
--- util-linux-2.12q.orig/mount/Makefile	2004-12-22 11:32:08.000000000 +0200
+++ util-linux-2.12q/mount/Makefile	2005-06-11 16:00:56.000000000 +0300
@@ -49,7 +51,8 @@
 
 mount: mount.o fstab.o sundries.o xmalloc.o realpath.o mntent.o version.o \
        get_label_uuid.o mount_by_label.o mount_blkid.o mount_guess_fstype.o \
-       getusername.o $(LIB)/setproctitle.o $(LIB)/env.o $(NFS_OBJS) $(LO_OBJS)
+       getusername.o $(LIB)/setproctitle.o $(LIB)/env.o $(LIB)/disk_size.o \
+       $(NFS_OBJS) $(LO_OBJS)
 	$(LINK) $^ -o $@ $(BLKID_LIB)
 
 umount: umount.o fstab.o sundries.o xmalloc.o realpath.o mntent.o \
diff -Naur util-linux-2.12q.orig/mount/mount.c util-linux-2.12q/mount/mount.c
--- util-linux-2.12q.orig/mount/mount.c	2004-12-22 00:00:36.000000000 +0200
+++ util-linux-2.12q/mount/mount.c	2005-06-11 16:00:56.000000000 +0300
@@ -29,7 +29,7 @@
 #include "fstab.h"
 #include "lomount.h"
 #include "loop.h"
-#include "linux_fs.h"		/* for BLKGETSIZE */
+#include "disk_size.h"
 #include "mount_guess_rootdev.h"
 #include "mount_guess_fstype.h"
 #include "mount_by_label.h"
@@ -969,21 +969,20 @@
 
 	if (stat(spec, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)
 	   && (fd = open(spec, O_RDONLY | O_NONBLOCK)) >= 0) {
-	  if (ioctl(fd, BLKGETSIZE, &size) == 0) {
-	    if (size == 0 && !loop) {
-	      warned++;
-	      error(_(
+	  size = disk_get_sectors(fd);
+	  if (size == 0 && !loop) {
+	    warned++;
+	    error(_(
 		 "       (could this be the IDE device where you in fact use\n"
 		 "       ide-scsi so that sr0 or sda or so is needed?)"));
-	    }
-	    if (size && size <= 2) {
-	      warned++;
-	      error(_(
+	  }
+	  if (size && size <= 2) {
+	    warned++;
+	    error(_(
 		  "       (aren't you trying to mount an extended partition,\n"
 		  "       instead of some logical partition inside?)"));
-	    }
-	  close(fd);
 	  }
+	  close(fd);
 #if 0
 	  /* 0xf for SCSI, 0x3f for IDE. One might check /proc/partitions
 	     to see whether this thing really is partitioned.
