diff options
author | avg <avg@FreeBSD.org> | 2010-05-28 07:34:20 +0000 |
---|---|---|
committer | avg <avg@FreeBSD.org> | 2010-05-28 07:34:20 +0000 |
commit | 5a45693652bd02bd14cc859665103d8813190d26 (patch) | |
tree | 7a985b03fea778ea15497f2a9ba0a820423799cb /sys/boot/zfs | |
parent | f89998ed7146d90bbe92b6abc6c786edb7fcae52 (diff) | |
download | FreeBSD-src-5a45693652bd02bd14cc859665103d8813190d26.zip FreeBSD-src-5a45693652bd02bd14cc859665103d8813190d26.tar.gz |
boot/zfs: fix gang block reading code
- use correct size (512) while reading a gang block
- skip holes while reading child blocks
- advance buffer pointer while reading child blocks
PR: 144214
MFC after: 10 days
Diffstat (limited to 'sys/boot/zfs')
-rw-r--r-- | sys/boot/zfs/zfsimpl.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/sys/boot/zfs/zfsimpl.c b/sys/boot/zfs/zfsimpl.c index 1407eb5..5be7afa 100644 --- a/sys/boot/zfs/zfsimpl.c +++ b/sys/boot/zfs/zfsimpl.c @@ -958,12 +958,17 @@ zio_read_gang(spa_t *spa, const blkptr_t *bp, const dva_t *dva, void *buf) break; if (!vdev || !vdev->v_read) return (EIO); - if (vdev->v_read(vdev, bp, &zio_gb, offset, SPA_GANGBLOCKSIZE)) + if (vdev->v_read(vdev, NULL, &zio_gb, offset, SPA_GANGBLOCKSIZE)) return (EIO); for (i = 0; i < SPA_GBH_NBLKPTRS; i++) { - if (zio_read(spa, &zio_gb.zg_blkptr[i], buf)) + blkptr_t *gbp = &zio_gb.zg_blkptr[i]; + + if (BP_IS_HOLE(gbp)) + continue; + if (zio_read(spa, gbp, buf)) return (EIO); + buf = (char*)buf + BP_GET_PSIZE(gbp); } return (0); @@ -994,9 +999,8 @@ zio_read(spa_t *spa, const blkptr_t *bp, void *buf) continue; if (DVA_GET_GANG(dva)) { - printf("ZFS: gang block detected!\n"); if (zio_read_gang(spa, bp, dva, buf)) - return (EIO); + continue; } else { vdevid = DVA_GET_VDEV(dva); offset = DVA_GET_OFFSET(dva); |