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