From owner-freebsd-current@FreeBSD.ORG Thu Oct 15 19:04:00 2009 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 51CAD1065672; Thu, 15 Oct 2009 19:04:00 +0000 (UTC) (envelope-from rnoland@FreeBSD.org) Received: from gizmo.2hip.net (gizmo.2hip.net [64.74.207.195]) by mx1.freebsd.org (Postfix) with ESMTP id 1895D8FC20; Thu, 15 Oct 2009 19:04:00 +0000 (UTC) Received: from [192.168.1.4] (adsl-154-199-198.ard.bellsouth.net [72.154.199.198]) (authenticated bits=0) by gizmo.2hip.net (8.14.3/8.14.3) with ESMTP id n9FJ3uDU033665 (version=TLSv1/SSLv3 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO); Thu, 15 Oct 2009 15:03:56 -0400 (EDT) (envelope-from rnoland@FreeBSD.org) From: Robert Noland To: Radek =?iso-8859-2?Q?Val=E1=B9ek?= In-Reply-To: <4AD710D6.70404@buchlovice.org> References: <4AD710D6.70404@buchlovice.org> Content-Type: multipart/mixed; boundary="=-a2tiU1GGu1eRIpNGphrs" Organization: FreeBSD Date: Thu, 15 Oct 2009 14:03:50 -0500 Message-Id: <1255633430.2175.12.camel@balrog.2hip.net> Mime-Version: 1.0 X-Mailer: Evolution 2.26.3 FreeBSD GNOME Team Port X-Spam-Status: No, score=-1.7 required=5.0 tests=AWL,BAYES_00, RCVD_IN_SORBS_DUL, RDNS_DYNAMIC, SPF_SOFTFAIL autolearn=no version=3.2.5 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on gizmo.2hip.net Cc: freebsd-fs@freebsd.org, freebsd-current@freebsd.org Subject: Re: GPT boot with ZFS RAIDZ "ZFS: i/o error - all block copies unavailable" X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 15 Oct 2009 19:04:00 -0000 --=-a2tiU1GGu1eRIpNGphrs Content-Type: text/plain; charset="iso-8859-2" Content-Transfer-Encoding: 8bit On Thu, 2009-10-15 at 14:08 +0200, Radek Valášek wrote: > Hi, > > I want to ask if there is something new in adding support to > gptzfsboot/zfsboot for reading gang-blocks? Ok, I can't figure out any way to test this... beyond the fact that it builds and doesn't break my currently working setup. Can you give this a try? It should still report if it finds gang blocks, but hopefully now will read them as well. robert. > From Sun's docs: > > Gang blocks > > When there is not enough contiguous space to write a complete block, the ZIO > pipeline will break the I/O up into smaller 'gang blocks' which can later be > assembled transparently to appear as complete blocks. > > Everything works fine for me, until I rewrite kernel/world after system > upgrade to latest one (releng_8). After this am I no longer able to boot > from zfs raidz1 pool with following messages: > > >/ ZFS: i/o error - all block copies unavailable > />/ ZFS: can't read MOS > />/ ZFS: unexpected object set type lld > />/ ZFS: unexpected object set type lld > />/ > />/ FreeBSD/i386 boot > />/ Default: z:/boot/kernel/kernel > />/ boot: > />/ ZFS: unexpected object set type lld > />/ > />/ FreeBSD/i386 boot > />/ Default: tank:/boot/kernel/kernel > />/ boot: > // > /I presume it's the same issue as talked in june-2009 current mailing > list > http://lists.freebsd.org/pipermail/freebsd-current/2009-June/008589.html > > Any success in that matter? > > Thnx for answer. > > vaLin > _______________________________________________ > freebsd-current@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-current > To unsubscribe, send any mail to "freebsd-current-unsubscribe@freebsd.org" -- Robert Noland FreeBSD --=-a2tiU1GGu1eRIpNGphrs Content-Disposition: attachment; filename="zfs-gang-block.patch" Content-Type: text/x-patch; name="zfs-gang-block.patch"; charset="us-ascii" Content-Transfer-Encoding: 7bit diff --git a/sys/boot/zfs/zfsimpl.c b/sys/boot/zfs/zfsimpl.c index ff567a4..6a18b44 100644 --- a/sys/boot/zfs/zfsimpl.c +++ b/sys/boot/zfs/zfsimpl.c @@ -53,6 +53,8 @@ static char *zfs_temp_buf, *zfs_temp_end, *zfs_temp_ptr; #define TEMP_SIZE (1*SPA_MAXBLOCKSIZE) +static int zio_read(spa_t *spa, const blkptr_t *bp, void *buf); + static void zfs_init(void) { @@ -897,6 +899,33 @@ ilog2(int n) } static int +zio_read_gang(spa_t *spa, const blkptr_t *bp, const dva_t *dva, void *buf) +{ + zio_gbh_phys_t zio_gb; + vdev_t *vdev; + int vdevid; + off_t offset; + int i; + + vdevid = DVA_GET_VDEV(dva); + offset = DVA_GET_OFFSET(dva); + STAILQ_FOREACH(vdev, &spa->spa_vdevs, v_childlink) + if (vdev->v_id == vdevid) + break; + if (!vdev || !vdev->v_read) + return (EIO); + if (vdev->v_read(vdev, bp, &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)) + return (EIO); + } + + return (0); +} + +static int zio_read(spa_t *spa, const blkptr_t *bp, void *buf) { int cpfunc = BP_GET_COMPRESS(bp); @@ -920,20 +949,26 @@ zio_read(spa_t *spa, const blkptr_t *bp, void *buf) if (!dva->dva_word[0] && !dva->dva_word[1]) continue; - vdevid = DVA_GET_VDEV(dva); - offset = DVA_GET_OFFSET(dva); - STAILQ_FOREACH(vdev, &spa->spa_vdevs, v_childlink) - if (vdev->v_id == vdevid) - break; - if (!vdev || !vdev->v_read) - continue; - if (vdev->v_read(vdev, bp, pbuf, offset, psize)) - continue; + if (DVA_GET_GANG(dva)) { + printf("ZFS: gang block detected!\n"); + if (zio_read_gang(spa, bp, dva, buf)) + return (EIO); + } else { + vdevid = DVA_GET_VDEV(dva); + offset = DVA_GET_OFFSET(dva); + STAILQ_FOREACH(vdev, &spa->spa_vdevs, v_childlink) + if (vdev->v_id == vdevid) + break; + if (!vdev || !vdev->v_read) + continue; + if (vdev->v_read(vdev, bp, pbuf, offset, psize)) + continue; - if (cpfunc != ZIO_COMPRESS_OFF) { - if (zio_decompress_data(cpfunc, pbuf, psize, - buf, lsize)) - return (EIO); + if (cpfunc != ZIO_COMPRESS_OFF) { + if (zio_decompress_data(cpfunc, pbuf, psize, + buf, lsize)) + return (EIO); + } } return (0); diff --git a/sys/cddl/boot/zfs/zfsimpl.h b/sys/cddl/boot/zfs/zfsimpl.h index a0b7b72..688bb5c 100644 --- a/sys/cddl/boot/zfs/zfsimpl.h +++ b/sys/cddl/boot/zfs/zfsimpl.h @@ -374,6 +374,24 @@ typedef struct vdev_label { #define VDEV_LABEL_END_SIZE (2 * sizeof (vdev_label_t)) #define VDEV_LABELS 4 +/* + * Gang block headers are self-checksumming and contain an array + * of block pointers. + */ +#define SPA_GANGBLOCKSIZE SPA_MINBLOCKSIZE +#define SPA_GBH_NBLKPTRS ((SPA_GANGBLOCKSIZE - \ + sizeof (zio_block_tail_t)) / sizeof (blkptr_t)) +#define SPA_GBH_FILLER ((SPA_GANGBLOCKSIZE - \ + sizeof (zio_block_tail_t) - \ + (SPA_GBH_NBLKPTRS * sizeof (blkptr_t))) /\ + sizeof (uint64_t)) + +typedef struct zio_gbh { + blkptr_t zg_blkptr[SPA_GBH_NBLKPTRS]; + uint64_t zg_filler[SPA_GBH_FILLER]; + zio_block_tail_t zg_tail; +} zio_gbh_phys_t; + enum zio_checksum { ZIO_CHECKSUM_INHERIT = 0, ZIO_CHECKSUM_ON, --=-a2tiU1GGu1eRIpNGphrs--