Deleted Added
sdiff udiff text old ( 116196 ) new ( 119660 )
full compact
1/*-
2 * Copyright (c) 2002 Poul-Henning Kamp
3 * Copyright (c) 2002 Networks Associates Technology, Inc.
4 * All rights reserved.
5 *
6 * This software was developed for the FreeBSD Project by Poul-Henning Kamp
7 * and NAI Labs, the Security Research Division of Network Associates, Inc.
8 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the

--- 24 unchanged lines hidden (view full) ---

33 * SUCH DAMAGE.
34 *
35 * This is the method for dealing with BSD disklabels. It has been
36 * extensively (by my standards at least) commented, in the vain hope that
37 * it will serve as the source in future copy&paste operations.
38 */
39
40#include <sys/cdefs.h>
41__FBSDID("$FreeBSD: head/sys/geom/geom_bsd.c 119660 2003-09-01 20:45:32Z phk $");
42
43#include <sys/param.h>
44#include <sys/endian.h>
45#include <sys/systm.h>
46#include <sys/kernel.h>
47#include <sys/conf.h>
48#include <sys/bio.h>
49#include <sys/malloc.h>

--- 212 unchanged lines hidden (view full) ---

262 error = g_write_data(cp, ms->labeloffset - secoff, buf, secsize);
263 g_free(buf);
264 } else {
265 error = g_write_data(cp, 0, bootcode, BBSIZE);
266 }
267 return(error);
268}
269
270/*
271 * If the user tries to overwrite our disklabel through an open partition
272 * or via a magicwrite config call, we end up here and try to prevent
273 * footshooting as best we can.
274 */
275static void
276g_bsd_hotwrite(void *arg, int flag)
277{
278 struct bio *bp;

--- 30 unchanged lines hidden (view full) ---

309 * trivial ones are handled autonomously by the slice code.
310 * For requests we handle here, we must call the g_io_deliver() on the
311 * bio, and return non-zero to indicate to the slice code that we did so.
312 * This code executes in the "DOWN" I/O path, this means:
313 * * No sleeping.
314 * * Don't grab the topology lock.
315 * * Don't call biowait, g_getattr(), g_setattr() or g_read_data()
316 */
317static int
318g_bsd_ioctl(struct g_provider *pp, u_long cmd, void * data, struct thread *td)
319{
320 struct g_geom *gp;
321 struct g_bsd_softc *ms;
322 struct g_slicer *gsp;
323 u_char *label;
324 int error;
325
326 gp = pp->geom;
327 gsp = gp->softc;
328 ms = gsp->softc;
329
330 switch(cmd) {
331 case DIOCGDINFO:
332 /* Return a copy of the disklabel to userland. */
333 bsd_disklabel_le_dec(ms->label, data, MAXPARTITIONS);
334 return(0);
335 case DIOCBSDBB: {
336 struct g_consumer *cp;
337 u_char *buf;
338 void *p;
339 int error, i;
340 uint64_t sum;
341
342 /* The disklabel to set is the ioctl argument. */
343 buf = g_malloc(BBSIZE, M_WAITOK);
344 p = *(void **)data;
345 error = copyin(p, buf, BBSIZE);
346 if (!error) {
347 /* XXX: Rude, but supposedly safe */
348 DROP_GIANT();
349 g_topology_lock();
350 /* Validate and modify our slice instance to match. */
351 error = g_bsd_modify(gp, buf + ms->labeloffset);
352 if (!error) {
353 cp = LIST_FIRST(&gp->consumer);
354 if (ms->labeloffset == ALPHA_LABEL_OFFSET) {
355 sum = 0;
356 for (i = 0; i < 63; i++)
357 sum += le64dec(buf + i * 8);
358 le64enc(buf + 504, sum);
359 }
360 error = g_write_data(cp, 0, buf, BBSIZE);
361 }
362 g_topology_unlock();
363 PICKUP_GIANT();
364 }
365 g_free(buf);
366 return (error);
367 }
368 case DIOCSDINFO:
369 case DIOCWDINFO: {
370 label = g_malloc(LABELSIZE, M_WAITOK);
371
372 /* The disklabel to set is the ioctl argument. */
373 bsd_disklabel_le_enc(label, data);
374
375 DROP_GIANT();
376 g_topology_lock();
377 /* Validate and modify our slice instance to match. */
378 error = g_bsd_modify(gp, label);
379 if (error == 0 && cmd == DIOCWDINFO)
380 error = g_bsd_writelabel(gp, NULL);
381 g_topology_unlock();
382 PICKUP_GIANT();
383 g_free(label);
384 return(error);
385 }
386 default:
387 return (ENOIOCTL);
388 }
389}
390
391static int
392g_bsd_start(struct bio *bp)
393{
394 struct g_geom *gp;
395 struct g_bsd_softc *ms;
396 struct g_slicer *gsp;
397
398 gp = bp->bio_to->geom;
399 gsp = gp->softc;
400 ms = gsp->softc;
401 if (bp->bio_cmd == BIO_GETATTR) {
402 if (g_handleattr(bp, "BSD::labelsum", ms->labelsum,
403 sizeof(ms->labelsum)))
404 return (1);
405 }
406 return (0);
407}
408
409/*
410 * Dump configuration information in XML format.
411 * Notice that the function is called once for the geom and once for each
412 * consumer and provider. We let g_slice_dumpconf() do most of the work.
413 */
414static void
415g_bsd_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, struct g_consumer *cp, struct g_provider *pp)
416{

--- 73 unchanged lines hidden (view full) ---

490 if (gp == NULL)
491 return (NULL);
492
493 /*
494 * Fill in the optional details, in our case we have a dumpconf
495 * routine which the "slice" code should call at the right time
496 */
497 gp->dumpconf = g_bsd_dumpconf;
498 gp->ioctl = g_bsd_ioctl;
499
500 /* Get the geom_slicer softc from the geom. */
501 gsp = gp->softc;
502
503 /*
504 * The do...while loop here allows us to have multiple escapes
505 * using a simple "break". This improves code clarity without
506 * ending up in deep nesting and without using goto or come from.

--- 170 unchanged lines hidden ---