Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern When writing the disklabel:
details: https://anonhg.NetBSD.org/src/rev/7cf7468b2532
branches: trunk
changeset: 550740:7cf7468b2532
user: dsl <dsl%NetBSD.org@localhost>
date: Tue Aug 19 11:49:24 2003 +0000
description:
When writing the disklabel:
- Write label to all netbsd (type 169) mbr partitions (even if they don't
already have a label).
- Update any label found in sector LABELSECTOR and sector 0.
Latter change makes DIOCWDINFO (etc) work on raidframe (fixing bin/22529).
diffstat:
sys/kern/subr_disk_mbr.c | 129 ++++++++++++++++++++++++++--------------------
1 files changed, 74 insertions(+), 55 deletions(-)
diffs (249 lines):
diff -r e89f6db87340 -r 7cf7468b2532 sys/kern/subr_disk_mbr.c
--- a/sys/kern/subr_disk_mbr.c Tue Aug 19 10:59:26 2003 +0000
+++ b/sys/kern/subr_disk_mbr.c Tue Aug 19 11:49:24 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_disk_mbr.c,v 1.2 2003/08/07 16:31:53 agc Exp $ */
+/* $NetBSD: subr_disk_mbr.c,v 1.3 2003/08/19 11:49:24 dsl Exp $ */
/*
* Copyright (c) 1982, 1986, 1988 Regents of the University of California.
@@ -34,8 +34,9 @@
/*
* Code to find a NetBSD label on a disk that contains an i386 style MBR.
* The first NetBSD label found in the 2nd sector of a NetBSD partition
- * is used. If there isn't a NetBSD partition then a label is faked up
- * from the MBR.
+ * is used.
+ * If we don't find a label searching the MBR, we look at the start of the
+ * disk, if that fails then a label is faked up from the MBR.
*
* If there isn't a disklabel or anything in the MBR then partition a
* is set to cover the whole disk.
@@ -45,13 +46,15 @@
*
* Based on the i386 disksubr.c
*
+ * Since the mbr only has 32bit fields for sector addresses, we do the same.
+ *
* XXX There are potential problems writing labels to disks where there
* is only space for 8 netbsd partitions but this code has been compiled
* with MAXPARTITIONS=16.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_disk_mbr.c,v 1.2 2003/08/07 16:31:53 agc Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_disk_mbr.c,v 1.3 2003/08/19 11:49:24 dsl Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -74,10 +77,13 @@
struct buf *bp;
const char *msg;
int error;
+ int written; /* number of times we wrote label */
+ uint label_sector; /* where we found the label */
} mbr_args_t;
#define READ_LABEL 1
-#define WRITE_LABEL 2
+#define UPDATE_LABEL 2
+#define WRITE_LABEL 3
static int validate_label(mbr_args_t *, uint, int);
static int look_netbsd_part(mbr_args_t *, mbr_partition_t *, int, uint);
static int write_netbsd_label(mbr_args_t *, mbr_partition_t *, int, uint);
@@ -126,10 +132,8 @@
/* Note: Magic number is little-endian. */
mbr = (void *)a->bp->b_data;
- if (mbr->mbr_signature != htole16(MBR_MAGIC)) {
- /* Don't set an error message here.... */
- return SCAN_ERROR;
- }
+ if (mbr->mbr_signature != htole16(MBR_MAGIC))
+ return SCAN_CONTINUE;
/* Copy data out of buffer so action can use bp */
memcpy(ptns, &mbr->mbr_parts, sizeof ptns);
@@ -204,10 +208,9 @@
int i;
mbr_args_t a;
+ memset(&a, 0, sizeof a);
a.lp = lp;
a.strat = strat;
- a.msg = NULL;
- a.error = 0;
/* minimal requirements for architypal disk label */
if (lp->d_secsize == 0)
@@ -244,13 +247,22 @@
else
rval = SCAN_CONTINUE;
- if (rval == SCAN_CONTINUE || (rval == SCAN_ERROR && a.msg == NULL)) {
+ if (rval == SCAN_CONTINUE) {
/* Look at start of disk */
rval = validate_label(&a, LABELSECTOR, READ_LABEL);
if (LABELSECTOR != 0 && rval == SCAN_CONTINUE)
rval = validate_label(&a, 0, READ_LABEL);
}
+#if 0
+ /*
+ * Save sector where we found the label for the 'don't overwrite
+ * the label' check in bounds_check_with_label.
+ */
+ if (rval == SCAN_FOUND)
+ xxx->label_sector = a.label_sector;
+#endif
+
/* Obtain bad sector table if requested and present */
if (rval == SCAN_FOUND && osdep && (lp->d_flags & D_BADSECT)) {
struct dkbad *db;
@@ -354,12 +366,13 @@
static int
validate_label(mbr_args_t *a, uint label_sector, int action)
{
- struct disklabel *dlp, *dlp_lim;
+ struct disklabel *dlp;
+ char *dlp_lim;
int error;
/* Next, dig out disk label */
if (read_sector(a, label_sector)) {
- a->msg = "disk label read failed";
+ a->msg = "disk label read failed";
return SCAN_ERROR;
}
@@ -368,40 +381,51 @@
* XXX (dsl) This search may be a waste of time, a lot of other i386
* code assumes the label is at offset LABELOFFSET (=0) in the sector.
*
- * If we want to support diska from other netbsd ports, then the
+ * If we want to support disks from other netbsd ports, then the
* code should also allow for a shorter label nearer the end of
* the disk sector, and (IIRC) labels within 8k of the disk start.
*/
- dlp_lim = (void *)(a->bp->b_data + a->lp->d_secsize - sizeof(*dlp));
- for (dlp = (void *)a->bp->b_data; dlp <= dlp_lim;
- dlp = (void *)((char *)dlp + sizeof(long))) {
- if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC)
- continue;
- if (dlp->d_npartitions > MAXPARTITIONS || dkcksum(dlp) != 0) {
- a->msg = "disk label corrupted";
- continue;
- }
- switch (action) {
- case READ_LABEL:
- *a->lp = *dlp;
- break;
- case WRITE_LABEL:
- *dlp = *a->lp;
- a->bp->b_flags &= ~(B_READ|B_DONE);
- a->bp->b_flags |= B_WRITE;
- (*a->strat)(a->bp);
- error = biowait(a->bp);
- if (error != 0) {
- a->error = error;
- a->msg = "disk label write failed";
- return SCAN_ERROR;
+ dlp = (void *)a->bp->b_data;
+ if (action != WRITE_LABEL) {
+ dlp_lim = a->bp->b_data + a->lp->d_secsize - sizeof(*dlp);
+ for (;; dlp = (void *)((char *)dlp + sizeof(long))) {
+ if ((char *)dlp > dlp_lim)
+ return SCAN_CONTINUE;
+ if (dlp->d_magic != DISKMAGIC
+ || dlp->d_magic2 != DISKMAGIC)
+ continue;
+ if (dlp->d_npartitions > MAXPARTITIONS
+ || dkcksum(dlp) != 0) {
+ a->msg = "disk label corrupted";
+ continue;
}
break;
}
- return SCAN_FOUND;
}
- return SCAN_CONTINUE;
+ switch (action) {
+ case READ_LABEL:
+ *a->lp = *dlp;
+ a->label_sector = label_sector;
+ return SCAN_FOUND;
+ case UPDATE_LABEL:
+ case WRITE_LABEL:
+ *dlp = *a->lp;
+ a->bp->b_flags &= ~(B_READ|B_DONE);
+ a->bp->b_flags |= B_WRITE;
+ (*a->strat)(a->bp);
+ error = biowait(a->bp);
+ if (error != 0) {
+ a->error = error;
+ a->msg = "disk label write failed";
+ return SCAN_ERROR;
+ }
+ a->written++;
+ /* Write label to all mbr partitions */
+ return SCAN_CONTINUE;
+ default:
+ return SCAN_ERROR;
+ }
}
/*
@@ -470,23 +494,25 @@
struct cpu_disklabel *osdep;
{
mbr_args_t a;
- int rval;
+ memset(&a, 0, sizeof a);
a.lp = lp;
a.strat = strat;
- a.msg = NULL;
- a.error = 0;
/* get a buffer and initialize it */
a.bp = geteblk((int)lp->d_secsize);
a.bp->b_dev = dev;
if (osdep)
- rval = scan_mbr(&a, write_netbsd_label);
- else
- rval = validate_label(&a, LABELSECTOR, WRITE_LABEL);
+ /* Write the label to every netbsd mbr partition */
+ scan_mbr(&a, write_netbsd_label);
- if (rval != SCAN_FOUND && a.error == 0)
+ /* and overwrite any label at the start of the volume */
+ validate_label(&a, LABELSECTOR, UPDATE_LABEL);
+ if (LABELSECTOR != 0)
+ validate_label(&a, 0, UPDATE_LABEL);
+
+ if (a.written == 0 && a.error == 0)
a.error = ESRCH;
brelse(a.bp);
@@ -497,18 +523,11 @@
write_netbsd_label(mbr_args_t *a, mbr_partition_t *dp, int slot, uint ext_base)
{
int ptn_base = ext_base + le32toh(dp->mbrp_start);
- int rval;
if (dp->mbrp_typ != MBR_PTYPE_NETBSD)
return SCAN_CONTINUE;
- rval = validate_label(a, ptn_base + MBR_LABELSECTOR, WRITE_LABEL);
-#ifdef notyet /* because the error reporting is wrong */
- /* write label to all netbsd partitions */
- if (rval == SCAN_FOUND)
- return SCAN_CONTINUE;
-#endif
- return rval;
+ return validate_label(a, ptn_base + MBR_LABELSECTOR, WRITE_LABEL);
}
Home |
Main Index |
Thread Index |
Old Index