? 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