diff options
author | bde <bde@FreeBSD.org> | 1994-12-12 00:20:34 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1994-12-12 00:20:34 +0000 |
commit | dd76f9af02622d9347c51336425ad4e6dce911fc (patch) | |
tree | 375982913ca3e2bd0f6e35559076e797fc9c0ef3 /sys/kern/subr_dkbad.c | |
parent | fd51fdacb58a497e43b785003bd005be84c1e926 (diff) | |
download | FreeBSD-src-dd76f9af02622d9347c51336425ad4e6dce911fc.zip FreeBSD-src-dd76f9af02622d9347c51336425ad4e6dce911fc.tar.gz |
subr_diskslice.c implements everything related to slices and labels except
reading and writing the slice tables and labels.
subr_dkbad.c implements everything related to bad sector remapping using
the bad144 format.
Diffstat (limited to 'sys/kern/subr_dkbad.c')
-rw-r--r-- | sys/kern/subr_dkbad.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/sys/kern/subr_dkbad.c b/sys/kern/subr_dkbad.c new file mode 100644 index 0000000..e685abf --- /dev/null +++ b/sys/kern/subr_dkbad.c @@ -0,0 +1,158 @@ +/*- + * Copyright (c) 1994 Bruce D. Evans. + * All rights reserved. + * + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Copyright (c) 1982, 1986, 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)wd.c 7.2 (Berkeley) 5/9/91 + * from: wd.c,v 1.55 1994/10/22 01:57:12 phk Exp $ + * from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 + * from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $ + * $Id: + */ + +#include <sys/param.h> +#include <sys/buf.h> +#include <sys/disklabel.h> +#include <sys/dkbad.h> +#include <sys/malloc.h> + +/* + * Internalize the bad sector table. + * TODO: + * o Fix types. + * Type long should be daddr_t since we compare with blkno's. + * Sentinel -1 should be ((daddr_t)-1). + * o Can remove explicit test for sentinel if it is a positive + * (unsigned or not) value larger than all possible blkno's. + * o Check that the table is sorted. + * o Use faster searches. + * o Use the internal table in wddump(). + * o Don't duplicate so much code. + * o Do all bad block handing in a driver-independent file. + * o Remove limit of 126 spare sectors. + */ +struct dkbad_intern * +internbad144(btp, lp) + struct dkbad *btp; + struct disklabel *lp; +{ + struct dkbad_intern *bip; + int i; + + bip = malloc(sizeof *bip, M_DEVBUF, M_WAITOK); + /* + * Spare sectors are allocated beginning with the last sector of + * the second last track of the disk (the last track is used for + * the bad sector list). + */ + bip->bi_maxspare = lp->d_secperunit - lp->d_nsectors - 1; + bip->bi_nbad = DKBAD_MAXBAD; + i = 0; + for (; i < DKBAD_MAXBAD && btp->bt_bad[i].bt_cyl != DKBAD_NOCYL; i++) + bip->bi_bad[i] = btp->bt_bad[i].bt_cyl * lp->d_secpercyl + + (btp->bt_bad[i].bt_trksec >> 8) + * lp->d_nsectors + + (btp->bt_bad[i].bt_trksec & 0x00ff); + bip->bi_bad[i] = -1; + return (bip); +} + +char * +readbad144(dev, strat, lp, bdp) + dev_t dev; + d_strategy_t *strat; + struct disklabel *lp; + struct dkbad *bdp; +{ + struct buf *bp; + struct dkbad *db; + int i; + char *msg; + + bp = geteblk((int)lp->d_secsize); + i = 0; + do { + /* Read a bad sector table. */ + bp->b_dev = dev; + bp->b_blkno = lp->d_secperunit - lp->d_nsectors + i; + if (lp->d_secsize > DEV_BSIZE) + bp->b_blkno *= lp->d_secsize / DEV_BSIZE; + else + bp->b_blkno /= DEV_BSIZE / lp->d_secsize; + bp->b_bcount = lp->d_secsize; + bp->b_flags = B_BUSY | B_READ; + (*strat)(bp); + + /* If successful, validate, otherwise try another. */ + if (biowait(bp) == 0) { + db = (struct dkbad *)(bp->b_un.b_addr); + if (db->bt_mbz == 0 && db->bt_flag == DKBAD_MAGIC) { + msg = NULL; + *bdp = *db; + break; + } + msg = "bad sector table corrupted"; + } else + msg = "bad sector table I/O error"; + } while ((bp->b_flags & B_ERROR) && (i += 2) < 10 && + i < lp->d_nsectors); + bp->b_flags = B_INVAL | B_AGE; + brelse(bp); + return (msg); +} + +daddr_t +transbad144(bip, blkno) + struct dkbad_intern *bip; + daddr_t blkno; +{ + int i; + + /* + * List is sorted, so the search can terminate when it is past our + * sector. + */ + for (i = 0; bip->bi_bad[i] != -1 && bip->bi_bad[i] <= blkno; i++) + if (bip->bi_bad[i] == blkno) + /* + * Spare sectors are allocated in decreasing order. + */ + return (bip->bi_maxspare - i); + return (blkno); +} |