Module Name:    src
Committed By:   christos
Date:           Fri Apr  6 20:09:26 UTC 2012

Modified Files:
        src/sbin/fdisk: fdisk.8 fdisk.c

Log Message:
support sector sizes > 512.


To generate a diff of this commit:
cvs rdiff -u -r1.75 -r1.76 src/sbin/fdisk/fdisk.8
cvs rdiff -u -r1.139 -r1.140 src/sbin/fdisk/fdisk.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sbin/fdisk/fdisk.8
diff -u src/sbin/fdisk/fdisk.8:1.75 src/sbin/fdisk/fdisk.8:1.76
--- src/sbin/fdisk/fdisk.8:1.75	Wed Jan  4 05:57:40 2012
+++ src/sbin/fdisk/fdisk.8	Fri Apr  6 16:09:26 2012
@@ -1,6 +1,6 @@
-.\"	$NetBSD: fdisk.8,v 1.75 2012/01/04 10:57:40 wiz Exp $
+.\"	$NetBSD: fdisk.8,v 1.76 2012/04/06 20:09:26 christos Exp $
 .\"
-.Dd December 1, 2011
+.Dd April 6, 2012
 .Dt FDISK 8
 .Os
 .Sh NAME
@@ -34,6 +34,9 @@
 .Op Fl t Ar disktab
 .Ek
 .Bk -words
+.Op Fl z Ar sectorsize
+.Ek
+.Bk -words
 .Op Ar device
 .Ek
 .Nm
@@ -397,6 +400,10 @@ allows the user to change more parameter
 Write the modified partition table to file
 .Ar file
 instead of the disk.
+.It Fl z Ar sectorsize
+Specify a sector size other than 512, for devices that only
+support larger sector sizes.
+The sector size needs to be a power of two greater than 512.
 .El
 .Pp
 When called with no arguments, it prints the partition table.

Index: src/sbin/fdisk/fdisk.c
diff -u src/sbin/fdisk/fdisk.c:1.139 src/sbin/fdisk/fdisk.c:1.140
--- src/sbin/fdisk/fdisk.c:1.139	Wed Mar 14 22:02:21 2012
+++ src/sbin/fdisk/fdisk.c	Fri Apr  6 16:09:26 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: fdisk.c,v 1.139 2012/03/15 02:02:21 joerg Exp $ */
+/*	$NetBSD: fdisk.c,v 1.140 2012/04/06 20:09:26 christos Exp $ */
 
 /*
  * Mach Operating System
@@ -39,7 +39,7 @@
 #include <sys/cdefs.h>
 
 #ifndef lint
-__RCSID("$NetBSD: fdisk.c,v 1.139 2012/03/15 02:02:21 joerg Exp $");
+__RCSID("$NetBSD: fdisk.c,v 1.140 2012/04/06 20:09:26 christos Exp $");
 #endif /* not lint */
 
 #define MBRPTYPENAMES
@@ -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,8 @@ 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 char *iobuf;		/* buffer for non 512 sector I/O */
 static int bootsize;		/* actual size of bootcode */
 static int boot_installed;	/* 1 if we've copied code into the mbr */
 
@@ -279,8 +281,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 +456,19 @@ main(int argc, char *argv[])
 		case 'T':
 			disk_type = optarg;
 			break;
+		case 'z':
+			secsize = atoi(optarg);
+			if (secsize <= 512)
+out:				 errx(EXIT_FAILURE, "Invalid sector size %zd",
+				    secsize);
+			for (ch = secsize; (ch & 1) == 0; ch >>= 1)
+				continue;
+			if (ch != 1)
+				goto out;
+			if ((iobuf = malloc(secsize)) == NULL)
+				err(EXIT_FAILURE, "Cannot allocate %zd buffer",
+				    secsize);
+			break;
 		default:
 			usage();
 		}
@@ -2468,26 +2483,62 @@ open_disk(int update)
 	return (0);
 }
 
-static int
+static ssize_t
 read_disk(daddr_t sector, void *buf)
 {
+	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, iobuf, secsize)) != secsize)
+		return nr;
+
+	memcpy(buf, &iobuf[mod], 512);
+
+	return 512;
+}	
+
+static ssize_t
 write_disk(daddr_t sector, void *buf)
 {
+	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, iobuf, secsize)) != secsize)
+		return nr;
+
+	if (lseek(wfd, rnd, SEEK_SET) == (off_t)-1)
+		return -1;
+
+	memcpy(&iobuf[mod], buf, 512);
+
+	if ((nr = write(wfd, iobuf, secsize)) != secsize)
+		return nr;
+
+	return 512;
 }
 
 static void

Reply via email to