Date: Thu, 20 May 2010 09:35:31 +0000 (UTC) From: Martin Matuska <mm@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r208343 - stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs Message-ID: <201005200935.o4K9ZVlY054653@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mm Date: Thu May 20 09:35:31 2010 New Revision: 208343 URL: http://svn.freebsd.org/changeset/base/208343 Log: MFC r208050: Fix ZIL-related panic on zfs rollback. OpenSolaris onnv-revision: 8746:e1d96ca6808c Approved by: pjd, delphij (mentor) Obtained from: OpenSolaris (Bug ID 6796377) Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scrub.c stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) stable/8/sys/geom/sched/ (props changed) Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c ============================================================================== --- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c Thu May 20 09:00:11 2010 (r208342) +++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c Thu May 20 09:35:31 2010 (r208343) @@ -1915,7 +1915,6 @@ dbuf_sync_leaf(dbuf_dirty_record_t *dr, dnode_t *dn = db->db_dnode; objset_impl_t *os = dn->dn_objset; uint64_t txg = tx->tx_txg; - int blksz; ASSERT(dmu_tx_is_syncing(tx)); @@ -2025,23 +2024,24 @@ dbuf_sync_leaf(dbuf_dirty_record_t *dr, return; } - blksz = arc_buf_size(*datap); - - if (dn->dn_object != DMU_META_DNODE_OBJECT) { + if (dn->dn_object != DMU_META_DNODE_OBJECT && + refcount_count(&db->db_holds) > 1 && + *datap == db->db_buf) { /* - * If this buffer is currently "in use" (i.e., there are - * active holds and db_data still references it), then make - * a copy before we start the write so that any modifications - * from the open txg will not leak into this write. + * If this buffer is currently "in use" (i.e., there + * are active holds and db_data still references it), + * then make a copy before we start the write so that + * any modifications from the open txg will not leak + * into this write. * - * NOTE: this copy does not need to be made for objects only - * modified in the syncing context (e.g. DNONE_DNODE blocks). + * NOTE: this copy does not need to be made for + * objects only modified in the syncing context (e.g. + * DNONE_DNODE blocks). */ - if (refcount_count(&db->db_holds) > 1 && *datap == db->db_buf) { - arc_buf_contents_t type = DBUF_GET_BUFC_TYPE(db); - *datap = arc_buf_alloc(os->os_spa, blksz, db, type); - bcopy(db->db.db_data, (*datap)->b_data, blksz); - } + int blksz = arc_buf_size(*datap); + arc_buf_contents_t type = DBUF_GET_BUFC_TYPE(db); + *datap = arc_buf_alloc(os->os_spa, blksz, db, type); + bcopy(db->db.db_data, (*datap)->b_data, blksz); } ASSERT(*datap != NULL); Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c ============================================================================== --- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c Thu May 20 09:00:11 2010 (r208342) +++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c Thu May 20 09:35:31 2010 (r208343) @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -226,10 +226,6 @@ traverse_visitbp(struct traverse_data *t return (err); osp = buf->b_data; - /* - * traverse_zil is just here for zdb's leak checking. - * For other consumers, there will be no ZIL blocks. - */ traverse_zil(td, &osp->os_zil_header); for (j = 0; j < osp->os_meta_dnode.dn_nblkptr; j++) { Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c ============================================================================== --- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c Thu May 20 09:00:11 2010 (r208342) +++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c Thu May 20 09:35:31 2010 (r208343) @@ -1171,8 +1171,18 @@ kill_blkptr(spa_t *spa, blkptr_t *bp, co if (bp == NULL) return (0); - ASSERT3U(bp->blk_birth, >, ka->ds->ds_phys->ds_prev_snap_txg); - (void) dsl_dataset_block_kill(ka->ds, bp, ka->zio, ka->tx); + if ((zb->zb_level == -1ULL && zb->zb_blkid != 0) || + (zb->zb_object != 0 && dnp == NULL)) { + /* + * It's a block in the intent log. It has no + * accounting, so just free it. + */ + VERIFY3U(0, ==, dsl_free(ka->zio, ka->tx->tx_pool, + ka->tx->tx_txg, bp, NULL, NULL, ARC_NOWAIT)); + } else { + ASSERT3U(bp->blk_birth, >, ka->ds->ds_phys->ds_prev_snap_txg); + (void) dsl_dataset_block_kill(ka->ds, bp, ka->zio, ka->tx); + } return (0); } @@ -1216,13 +1226,7 @@ dsl_dataset_rollback_sync(void *arg1, vo dmu_buf_will_dirty(ds->ds_dbuf, tx); - /* - * Before the roll back destroy the zil. - */ if (ds->ds_user_ptr != NULL) { - zil_rollback_destroy( - ((objset_impl_t *)ds->ds_user_ptr)->os_zil, tx); - /* * We need to make sure that the objset_impl_t is reopened after * we do the rollback, otherwise it will have the wrong @@ -1255,7 +1259,10 @@ dsl_dataset_rollback_sync(void *arg1, vo ds->ds_phys->ds_deadlist_obj)); { - /* Free blkptrs that we gave birth to */ + /* + * Free blkptrs that we gave birth to - this covers + * claimed but not played log blocks too. + */ zio_t *zio; struct killarg ka; Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scrub.c ============================================================================== --- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scrub.c Thu May 20 09:00:11 2010 (r208342) +++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scrub.c Thu May 20 09:35:31 2010 (r208343) @@ -344,6 +344,12 @@ traverse_zil_block(zilog_t *zilog, blkpt if (bp->blk_birth <= dp->dp_scrub_min_txg) return; + /* + * One block ("stumpy") can be allocated a long time ago; we + * want to visit that one because it has been allocated + * (on-disk) even if it hasn't been claimed (even though for + * plain scrub there's nothing to do to it). + */ if (claim_txg == 0 && bp->blk_birth >= spa_first_txg(dp->dp_spa)) return; @@ -369,6 +375,11 @@ traverse_zil_record(zilog_t *zilog, lr_t if (bp->blk_birth <= dp->dp_scrub_min_txg) return; + /* + * birth can be < claim_txg if this record's txg is + * already txg sync'ed (but this log block contains + * other records that are not synced) + */ if (claim_txg == 0 || bp->blk_birth < claim_txg) return; Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c ============================================================================== --- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c Thu May 20 09:00:11 2010 (r208342) +++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c Thu May 20 09:35:31 2010 (r208343) @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -478,37 +478,6 @@ zil_destroy(zilog_t *zilog, boolean_t ke } /* - * zil_rollback_destroy() is only called by the rollback code. - * We already have a syncing tx. Rollback has exclusive access to the - * dataset, so we don't have to worry about concurrent zil access. - * The actual freeing of any log blocks occurs in zil_sync() later in - * this txg syncing phase. - */ -void -zil_rollback_destroy(zilog_t *zilog, dmu_tx_t *tx) -{ - const zil_header_t *zh = zilog->zl_header; - uint64_t txg; - - if (BP_IS_HOLE(&zh->zh_log)) - return; - - txg = dmu_tx_get_txg(tx); - ASSERT3U(zilog->zl_destroy_txg, <, txg); - zilog->zl_destroy_txg = txg; - zilog->zl_keep_first = B_FALSE; - - /* - * Ensure there's no outstanding ZIL IO. No lwbs or just the - * unused one that allocated in advance is ok. - */ - ASSERT(zilog->zl_lwb_list.list_head.list_next == - zilog->zl_lwb_list.list_head.list_prev); - (void) zil_parse(zilog, zil_free_log_block, zil_free_log_record, - tx, zh->zh_claim_txg); -} - -/* * return true if the initial log block is not valid */ static boolean_t
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201005200935.o4K9ZVlY054653>