d1f35d579f
reading and writing the slice tables and labels. subr_dkbad.c implements everything related to bad sector remapping using the bad144 format.
159 lines
4.9 KiB
C
159 lines
4.9 KiB
C
/*-
|
|
* 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);
|
|
}
|