diff options
| author | mlelstv <mlelstv@NetBSD.org> | 2018-01-07 11:37:30 +0000 |
|---|---|---|
| committer | mlelstv <mlelstv@NetBSD.org> | 2018-01-07 11:37:30 +0000 |
| commit | e755c7e68880ef01ed5c0e9d9398fb576cfdfd46 (patch) | |
| tree | 568f4b763cf2ace46dd4ae1832b9872f52a24d04 /sys/dev/ata | |
| parent | 342f94af5d7f1e8817c343d69a459cebb8e070bc (diff) | |
Fix block address calculation for bad sectors.
Diffstat (limited to 'sys/dev/ata')
| -rw-r--r-- | sys/dev/ata/wd.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/sys/dev/ata/wd.c b/sys/dev/ata/wd.c index bf766c4b5d5..81629a7fa3b 100644 --- a/sys/dev/ata/wd.c +++ b/sys/dev/ata/wd.c @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.437 2017/12/13 10:24:31 pgoyette Exp $ */ +/* $NetBSD: wd.c,v 1.438 2018/01/07 11:37:30 mlelstv Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.437 2017/12/13 10:24:31 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.438 2018/01/07 11:37:30 mlelstv Exp $"); #include "opt_ata.h" #include "opt_wd.h" @@ -585,9 +585,18 @@ wdstrategy(struct buf *bp) * up failing again. */ if (__predict_false(!SLIST_EMPTY(&wd->sc_bslist))) { + struct disklabel *lp = dksc->sc_dkdev.dk_label; struct disk_badsectors *dbs; - daddr_t maxblk = bp->b_rawblkno + - (bp->b_bcount / wd->sc_blksize) - 1; + daddr_t blkno, maxblk; + + /* convert the block number to absolute */ + if (lp->d_secsize >= DEV_BSIZE) + blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE); + else + blkno = bp->b_blkno * (DEV_BSIZE / lp->d_secsize); + if (WDPART(bp->b_dev) != RAW_PART) + blkno += lp->d_partitions[WDPART(bp->b_dev)].p_offset; + maxblk = blkno + (bp->b_bcount / wd->sc_blksize) - 1; mutex_enter(&wd->sc_lock); SLIST_FOREACH(dbs, &wd->sc_bslist, dbs_next) |
