svn commit: r224608 -
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Martin Matuska
mm at FreeBSD.org
Tue Aug 2 11:35:00 UTC 2011
Author: mm
Date: Tue Aug 2 11:34:59 2011
New Revision: 224608
URL: http://svn.freebsd.org/changeset/base/224608
Log:
MFC r224526:
Fix serious bug in ZIL that can lead to pool corruption
in the case of a held dataset during remount.
Detailed description is available at:
https://www.illumos.org/issues/883
illumos-gate revision: 13380:161b964a0e10
Reviewed by: pjd
Obtained from: Illumos (Bug #883)
Modified:
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)
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 Tue Aug 2 11:33:19 2011 (r224607)
+++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c Tue Aug 2 11:34:59 2011 (r224608)
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
*/
/* Portions Copyright 2010 Robert Milkowski */
@@ -567,7 +568,7 @@ zil_destroy(zilog_t *zilog, boolean_t ke
if (!list_is_empty(&zilog->zl_lwb_list)) {
ASSERT(zh->zh_claim_txg == 0);
- ASSERT(!keep_first);
+ VERIFY(!keep_first);
while ((lwb = list_head(&zilog->zl_lwb_list)) != NULL) {
list_remove(&zilog->zl_lwb_list, lwb);
if (lwb->lwb_buf != NULL)
@@ -1668,20 +1669,9 @@ zil_alloc(objset_t *os, zil_header_t *zh
void
zil_free(zilog_t *zilog)
{
- lwb_t *head_lwb;
-
zilog->zl_stop_sync = 1;
- /*
- * After zil_close() there should only be one lwb with a buffer.
- */
- head_lwb = list_head(&zilog->zl_lwb_list);
- if (head_lwb) {
- ASSERT(head_lwb == list_tail(&zilog->zl_lwb_list));
- list_remove(&zilog->zl_lwb_list, head_lwb);
- zio_buf_free(head_lwb->lwb_buf, head_lwb->lwb_sz);
- kmem_cache_free(zil_lwb_cache, head_lwb);
- }
+ ASSERT(list_is_empty(&zilog->zl_lwb_list));
list_destroy(&zilog->zl_lwb_list);
avl_destroy(&zilog->zl_vdev_tree);
@@ -1721,6 +1711,10 @@ zil_open(objset_t *os, zil_get_data_t *g
{
zilog_t *zilog = dmu_objset_zil(os);
+ ASSERT(zilog->zl_clean_taskq == NULL);
+ ASSERT(zilog->zl_get_data == NULL);
+ ASSERT(list_is_empty(&zilog->zl_lwb_list));
+
zilog->zl_get_data = get_data;
zilog->zl_clean_taskq = taskq_create("zil_clean", 1, minclsyspri,
2, 2, TASKQ_PREPOPULATE);
@@ -1734,7 +1728,7 @@ zil_open(objset_t *os, zil_get_data_t *g
void
zil_close(zilog_t *zilog)
{
- lwb_t *tail_lwb;
+ lwb_t *lwb;
uint64_t txg = 0;
zil_commit(zilog, 0); /* commit all itx */
@@ -1746,9 +1740,9 @@ zil_close(zilog_t *zilog)
* destroy the zl_clean_taskq.
*/
mutex_enter(&zilog->zl_lock);
- tail_lwb = list_tail(&zilog->zl_lwb_list);
- if (tail_lwb != NULL)
- txg = tail_lwb->lwb_max_txg;
+ lwb = list_tail(&zilog->zl_lwb_list);
+ if (lwb != NULL)
+ txg = lwb->lwb_max_txg;
mutex_exit(&zilog->zl_lock);
if (txg)
txg_wait_synced(zilog->zl_dmu_pool, txg);
@@ -1756,6 +1750,19 @@ zil_close(zilog_t *zilog)
taskq_destroy(zilog->zl_clean_taskq);
zilog->zl_clean_taskq = NULL;
zilog->zl_get_data = NULL;
+
+ /*
+ * We should have only one LWB left on the list; remove it now.
+ */
+ mutex_enter(&zilog->zl_lock);
+ lwb = list_head(&zilog->zl_lwb_list);
+ if (lwb != NULL) {
+ ASSERT(lwb == list_tail(&zilog->zl_lwb_list));
+ list_remove(&zilog->zl_lwb_list, lwb);
+ zio_buf_free(lwb->lwb_buf, lwb->lwb_sz);
+ kmem_cache_free(zil_lwb_cache, lwb);
+ }
+ mutex_exit(&zilog->zl_lock);
}
/*
More information about the svn-src-stable
mailing list