diff options
author | marcel <marcel@FreeBSD.org> | 2008-11-18 00:03:30 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2008-11-18 00:03:30 +0000 |
commit | a439cdd8d408dfb0b2c406486aa8c13b9ef61770 (patch) | |
tree | 330f9280063a49e9c0d96331c3858536d468e894 /sbin/geom | |
parent | 256094d468d2d7dce899e9f78283e381132e7c24 (diff) | |
download | FreeBSD-src-a439cdd8d408dfb0b2c406486aa8c13b9ef61770.zip FreeBSD-src-a439cdd8d408dfb0b2c406486aa8c13b9ef61770.tar.gz |
Pad the bootcode we write to the partition to a multiple of the
sector size.
Submitted by: Alexey Shuvaev <shuvaev@physik.uni-wuerzburg.de>
Prompted by: delphij
MFC after: 3 days
Diffstat (limited to 'sbin/geom')
-rw-r--r-- | sbin/geom/class/part/geom_part.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/sbin/geom/class/part/geom_part.c b/sbin/geom/class/part/geom_part.c index 2d03ae1..316f7e5 100644 --- a/sbin/geom/class/part/geom_part.c +++ b/sbin/geom/class/part/geom_part.c @@ -393,6 +393,8 @@ gpart_write_partcode(struct gctl_req *req, int idx, void *code, ssize_t size) struct ggeom *gp; struct gprovider *pp; const char *s; + char *buf; + off_t bsize; int error, fd; s = gctl_get_ascii(req, "class"); @@ -428,8 +430,21 @@ gpart_write_partcode(struct gctl_req *req, int idx, void *code, ssize_t size) errx(EXIT_FAILURE, "%s: not enough space", dsf); if (lseek(fd, 0, SEEK_SET) != 0) err(EXIT_FAILURE, "%s", dsf); - if (write(fd, code, size) != size) + + /* + * When writing to a disk device, the write must be + * sector aligned and not write to any partial sectors, + * so round up the buffer size to the next sector and zero it. + */ + bsize = (size + pp->lg_sectorsize - 1) / + pp->lg_sectorsize * pp->lg_sectorsize; + buf = calloc(1, bsize); + if (buf == NULL) + err(EXIT_FAILURE, "%s", dsf); + bcopy(code, buf, size); + if (write(fd, buf, bsize) != bsize) err(EXIT_FAILURE, "%s", dsf); + free(buf); close(fd); } else errx(EXIT_FAILURE, "invalid partition index"); |