aboutsummaryrefslogtreecommitdiff
path: root/sys/geom/geom_bsd.c
diff options
context:
space:
mode:
authorPoul-Henning Kamp <phk@FreeBSD.org>2002-09-30 08:59:59 +0000
committerPoul-Henning Kamp <phk@FreeBSD.org>2002-09-30 08:59:59 +0000
commit3a24c28f374847f7c34864b15659aa7c49625451 (patch)
treeb14e645ac2a5ecbca5b90bcb8986801c520a655e /sys/geom/geom_bsd.c
parentf9f1b6f70f806c590a8de67e911963ba25f3a139 (diff)
downloadsrc-3a24c28f374847f7c34864b15659aa7c49625451.tar.gz
src-3a24c28f374847f7c34864b15659aa7c49625451.zip
Don the asbestos underwear and add the code which lets DIOCWDINFO
write modified disklabels back to disk. Sponsored by: DARPA & NAI Labs.
Notes
Notes: svn path=/head/; revision=104197
Diffstat (limited to 'sys/geom/geom_bsd.c')
-rw-r--r--sys/geom/geom_bsd.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/sys/geom/geom_bsd.c b/sys/geom/geom_bsd.c
index f21f6a45a71d..74898c06015c 100644
--- a/sys/geom/geom_bsd.c
+++ b/sys/geom/geom_bsd.c
@@ -139,7 +139,6 @@ g_bsd_ledec_disklabel(u_char *ptr, struct disklabel *d)
g_bsd_ledec_partition(ptr + 148 + 16 * i, &d->d_partitions[i]);
}
-#if 0
static void
g_bsd_leenc_partition(u_char *ptr, struct partition *d)
{
@@ -196,8 +195,6 @@ g_bsd_leenc_disklabel(u_char *ptr, struct disklabel *d)
g_bsd_leenc_partition(ptr + 148 + 16 * i, &d->d_partitions[i]);
}
-#endif
-
/*
* For reasons which were valid and just in their days, FreeBSD/i386 uses
* absolute disk-addresses in disklabels. The way it works is that the
@@ -507,10 +504,29 @@ g_bsd_ioctl(void *arg)
ms->inram = *dl;
inram2ondisk(ms);
- /* XXX: DIOCWDINFO write to disk */
-
- /* return the request */
- g_io_deliver(bp, 0);
+ if (gio->cmd == DIOCSDINFO) {
+ g_io_deliver(bp, 0);
+ return;
+ }
+ KASSERT(gio->cmd == DIOCWDINFO, ("Unknown ioctl in g_bsd_ioctl"));
+ cp = LIST_FIRST(&gp->consumer);
+ /* Get sector size, we need it to read data. */
+ error = g_getattr("GEOM::sectorsize", cp, &secsize);
+ if (error || secsize < 512) {
+ g_io_deliver(bp, error);
+ return;
+ }
+ secoff = ms->labeloffset % secsize;
+ buf = g_read_data(cp, ms->labeloffset - secoff, secsize, &error);
+ if (buf == NULL || error != 0) {
+ g_io_deliver(bp, error);
+ return;
+ }
+ dl = &ms->ondisk;
+ g_bsd_leenc_disklabel(buf + secoff, dl);
+ error = g_write_data(cp, ms->labeloffset - secoff, buf, secsize);
+ g_free(buf);
+ g_io_deliver(bp, error);
return;
}