summaryrefslogtreecommitdiffstats
path: root/sbin/geom
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2008-11-18 00:03:30 +0000
committermarcel <marcel@FreeBSD.org>2008-11-18 00:03:30 +0000
commita439cdd8d408dfb0b2c406486aa8c13b9ef61770 (patch)
tree330f9280063a49e9c0d96331c3858536d468e894 /sbin/geom
parent256094d468d2d7dce899e9f78283e381132e7c24 (diff)
downloadFreeBSD-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.c17
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");
OpenPOWER on IntegriCloud