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