? fdisk.diff
Index: fdisk.c
===================================================================
RCS file: /cvsroot/src/sbin/fdisk/fdisk.c,v
retrieving revision 1.139
diff -u -p -u -r1.139 fdisk.c
--- fdisk.c	15 Mar 2012 02:02:21 -0000	1.139
+++ fdisk.c	6 Apr 2012 19:32:44 -0000
@@ -155,7 +155,7 @@ static char *boot_path = NULL;			/* name
 #define BOOTSEL_OPTIONS	
 #define change_part(e, p, id, st, sz, bm) change__part(e, p, id, st, sz)
 #endif
-#define OPTIONS	BOOTSEL_OPTIONS "0123FSafiIluvA:b:c:E:r:s:w:"
+#define OPTIONS	BOOTSEL_OPTIONS "0123FSafiIluvA:b:c:E:r:s:w:z:"
 
 /*
  * Disk geometry and partition alignment.
@@ -245,6 +245,7 @@ static int F_flag = 1;
 static struct gpt_hdr gpt1, gpt2;	/* GUID partition tables */
 
 static struct mbr_sector bootcode[8192 / sizeof (struct mbr_sector)];
+static ssize_t secsize = 512;	/* sector size */
 static int bootsize;		/* actual size of bootcode */
 static int boot_installed;	/* 1 if we've copied code into the mbr */
 
@@ -279,8 +280,8 @@ static void	change_active(int);
 static void	change_bios_geometry(void);
 static void	dos(int, unsigned char *, unsigned char *, unsigned char *);
 static int	open_disk(int);
-static int	read_disk(daddr_t, void *);
-static int	write_disk(daddr_t, void *);
+static ssize_t	read_disk(daddr_t, void *);
+static ssize_t	write_disk(daddr_t, void *);
 static int	get_params(void);
 static int	read_s0(daddr_t, struct mbr_sector *);
 static int	write_mbr(void);
@@ -454,6 +455,19 @@ main(int argc, char *argv[])
 		case 'T':
 			disk_type = optarg;
 			break;
+		case 'z':
+			switch (secsize = atoi(optarg)) {
+			case 512:
+			case 1024:
+			case 2048:
+			case 4096:
+			case 8192:
+				break;
+			default:
+				errx(EXIT_FAILURE, "invalid sector size %zd",
+				    secsize);
+			}
+			break;
 		default:
 			usage();
 		}
@@ -2468,26 +2482,64 @@ open_disk(int update)
 	return (0);
 }
 
-static int
+static ssize_t
 read_disk(daddr_t sector, void *buf)
 {
+	char ibuf[8192];
+	ssize_t nr;
 
 	if (*rfd == -1)
 		errx(1, "read_disk(); fd == -1");
-	if (lseek(*rfd, sector * (off_t)512, 0) == -1)
-		return (-1);
-	return (read(*rfd, buf, 512));
-}
 
-static int
+	off_t offs = sector * (off_t)512;
+	off_t mod = offs & (secsize - 1);
+	off_t rnd = offs & ~(secsize - 1);
+
+	if (lseek(*rfd, rnd, SEEK_SET) == (off_t)-1)
+		return -1;
+
+	if (secsize == 512)
+		return read(*rfd, buf, 512);
+
+	if ((nr = read(*rfd, ibuf, secsize)) != secsize)
+		return nr;
+
+	memcpy(buf, &ibuf[mod], 512);
+
+	return 512;
+}	
+
+static ssize_t
 write_disk(daddr_t sector, void *buf)
 {
+	char obuf[8192];
+	ssize_t nr;
 
 	if (wfd == -1)
 		errx(1, "write_disk(); wfd == -1");
-	if (lseek(wfd, sector * (off_t)512, 0) == -1)
-		return (-1);
-	return (write(wfd, buf, 512));
+
+	off_t offs = sector * (off_t)512;
+	off_t mod = offs & (secsize - 1);
+	off_t rnd = offs & ~(secsize - 1);
+
+	if (lseek(wfd, rnd, SEEK_SET) == (off_t)-1)
+		return -1;
+
+	if (secsize == 512)
+		return write(wfd, buf, 512);
+
+	if ((nr = read(wfd, obuf, secsize)) != secsize)
+		return nr;
+
+	if (lseek(wfd, rnd, SEEK_SET) == (off_t)-1)
+		return -1;
+
+	memcpy(&obuf[mod], buf, 512);
+
+	if ((nr = write(wfd, obuf, secsize)) != secsize)
+		return nr;
+
+	return 512;
 }
 
 static void