svn commit: r318931 - in vendor-sys/illumos/dist/uts/common/fs/zfs: . sys

Andriy Gapon avg at FreeBSD.org
Fri May 26 11:35:36 UTC 2017


Author: avg
Date: Fri May 26 11:35:34 2017
New Revision: 318931
URL: https://svnweb.freebsd.org/changeset/base/318931

Log:
  8063 verify that we do not attempt to access inactive txg
  
  illumos/illumos-gate at b7b2590dd9f11b12a0b4878db3886068cce176af
  https://github.com/illumos/illumos-gate/commit/b7b2590dd9f11b12a0b4878db3886068cce176af
  
  https://www.illumos.org/issues/8063
    A standard practice in ZFS is to keep track of "per-txg" state. Any of
    the 3 active TXG's (open, quiescing, syncing) can have different values
    for this state. We should assert that we do not attempt to modify other
    (inactive) TXG's.
  
  Reviewed by: Serapheim Dimitropoulos <serapheim at delphix.com>
  Reviewed by: Pavel Zakharov <pavel.zakharov at delphix.com>
  Approved by: Robert Mustacchi <rm at joyent.com>
  Author: Matthew Ahrens <mahrens at delphix.com>

Modified:
  vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_tx.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_pool.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/spa.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/sys/txg.h
  vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zil.h
  vendor-sys/illumos/dist/uts/common/fs/zfs/txg.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/vdev.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/zil.c

Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_tx.c
==============================================================================
--- vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_tx.c	Fri May 26 11:33:34 2017	(r318930)
+++ vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_tx.c	Fri May 26 11:35:34 2017	(r318931)
@@ -21,7 +21,7 @@
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
- * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
  * Copyright (c) 2014 Integros [integros.com]
  */
 
@@ -72,7 +72,7 @@ dmu_tx_create_assigned(struct dsl_pool *
 {
 	dmu_tx_t *tx = dmu_tx_create_dd(NULL);
 
-	ASSERT3U(txg, <=, dp->dp_tx.tx_open_txg);
+	txg_verify(dp->dp_spa, txg);
 	tx->tx_pool = dp;
 	tx->tx_txg = txg;
 	tx->tx_anyobj = TRUE;

Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_pool.c
==============================================================================
--- vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_pool.c	Fri May 26 11:33:34 2017	(r318930)
+++ vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_pool.c	Fri May 26 11:35:34 2017	(r318931)
@@ -159,13 +159,13 @@ dsl_pool_open_impl(spa_t *spa, uint64_t 
 	rrw_init(&dp->dp_config_rwlock, B_TRUE);
 	txg_init(dp, txg);
 
-	txg_list_create(&dp->dp_dirty_datasets,
+	txg_list_create(&dp->dp_dirty_datasets, spa,
 	    offsetof(dsl_dataset_t, ds_dirty_link));
-	txg_list_create(&dp->dp_dirty_zilogs,
+	txg_list_create(&dp->dp_dirty_zilogs, spa,
 	    offsetof(zilog_t, zl_dirty_link));
-	txg_list_create(&dp->dp_dirty_dirs,
+	txg_list_create(&dp->dp_dirty_dirs, spa,
 	    offsetof(dsl_dir_t, dd_dirty_link));
-	txg_list_create(&dp->dp_sync_tasks,
+	txg_list_create(&dp->dp_sync_tasks, spa,
 	    offsetof(dsl_sync_task_t, dst_node));
 
 	dp->dp_sync_taskq = taskq_create("dp_sync_taskq",

Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/spa.c
==============================================================================
--- vendor-sys/illumos/dist/uts/common/fs/zfs/spa.c	Fri May 26 11:33:34 2017	(r318930)
+++ vendor-sys/illumos/dist/uts/common/fs/zfs/spa.c	Fri May 26 11:35:34 2017	(r318931)
@@ -21,7 +21,7 @@
 
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
  * Copyright (c) 2015, Nexenta Systems, Inc.  All rights reserved.
  * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
  * Copyright 2013 Saso Kiselkov. All rights reserved.
@@ -1090,7 +1090,7 @@ spa_activate(spa_t *spa, int mode)
 	list_create(&spa->spa_state_dirty_list, sizeof (vdev_t),
 	    offsetof(vdev_t, vdev_state_dirty_node));
 
-	txg_list_create(&spa->spa_vdev_txg_list,
+	txg_list_create(&spa->spa_vdev_txg_list, spa,
 	    offsetof(struct vdev, vdev_txg_node));
 
 	avl_create(&spa->spa_errlist_scrub,

Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/sys/txg.h
==============================================================================
--- vendor-sys/illumos/dist/uts/common/fs/zfs/sys/txg.h	Fri May 26 11:33:34 2017	(r318930)
+++ vendor-sys/illumos/dist/uts/common/fs/zfs/sys/txg.h	Fri May 26 11:35:34 2017	(r318931)
@@ -23,7 +23,7 @@
  * Use is subject to license terms.
  */
 /*
- * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
  */
 
 #ifndef _SYS_TXG_H
@@ -60,6 +60,7 @@ typedef struct txg_node {
 typedef struct txg_list {
 	kmutex_t	tl_lock;
 	size_t		tl_offset;
+	spa_t		*tl_spa;
 	txg_node_t	*tl_head[TXG_SIZE];
 } txg_list_t;
 
@@ -103,13 +104,15 @@ extern boolean_t txg_stalled(struct dsl_
 /* returns TRUE if someone is waiting for the next txg to sync */
 extern boolean_t txg_sync_waiting(struct dsl_pool *dp);
 
+extern void txg_verify(spa_t *spa, uint64_t txg);
+
 /*
  * Per-txg object lists.
  */
 
 #define	TXG_CLEAN(txg)	((txg) - 1)
 
-extern void txg_list_create(txg_list_t *tl, size_t offset);
+extern void txg_list_create(txg_list_t *tl, spa_t *spa, size_t offset);
 extern void txg_list_destroy(txg_list_t *tl);
 extern boolean_t txg_list_empty(txg_list_t *tl, uint64_t txg);
 extern boolean_t txg_all_lists_empty(txg_list_t *tl);

Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zil.h
==============================================================================
--- vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zil.h	Fri May 26 11:33:34 2017	(r318930)
+++ vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zil.h	Fri May 26 11:35:34 2017	(r318931)
@@ -20,7 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
  * Copyright (c) 2014 Integros [integros.com]
  */
 
@@ -96,6 +96,15 @@ typedef struct zil_chain {
 #define	ZIL_MIN_BLKSZ	4096ULL
 
 /*
+ * ziltest is by and large an ugly hack, but very useful in
+ * checking replay without tedious work.
+ * When running ziltest we want to keep all itx's and so maintain
+ * a single list in the zl_itxg[] that uses a high txg: ZILTEST_TXG
+ * We subtract TXG_CONCURRENT_STATES to allow for common code.
+ */
+#define	ZILTEST_TXG (UINT64_MAX - TXG_CONCURRENT_STATES)
+
+/*
  * The words of a log block checksum.
  */
 #define	ZIL_ZC_GUID_0	0

Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/txg.c
==============================================================================
--- vendor-sys/illumos/dist/uts/common/fs/zfs/txg.c	Fri May 26 11:33:34 2017	(r318930)
+++ vendor-sys/illumos/dist/uts/common/fs/zfs/txg.c	Fri May 26 11:35:34 2017	(r318931)
@@ -21,7 +21,7 @@
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Portions Copyright 2011 Martin Matuska
- * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
  */
 
 #include <sys/zfs_context.h>
@@ -30,6 +30,7 @@
 #include <sys/dmu_tx.h>
 #include <sys/dsl_pool.h>
 #include <sys/dsl_scan.h>
+#include <sys/zil.h>
 #include <sys/callb.h>
 
 /*
@@ -685,16 +686,32 @@ txg_sync_waiting(dsl_pool_t *dp)
 }
 
 /*
+ * Verify that this txg is active (open, quiescing, syncing).  Non-active
+ * txg's should not be manipulated.
+ */
+void
+txg_verify(spa_t *spa, uint64_t txg)
+{
+	dsl_pool_t *dp = spa_get_dsl(spa);
+	if (txg <= TXG_INITIAL || txg == ZILTEST_TXG)
+		return;
+	ASSERT3U(txg, <=, dp->dp_tx.tx_open_txg);
+	ASSERT3U(txg, >=, dp->dp_tx.tx_synced_txg);
+	ASSERT3U(txg, >=, dp->dp_tx.tx_open_txg - TXG_CONCURRENT_STATES);
+}
+
+/*
  * Per-txg object lists.
  */
 void
-txg_list_create(txg_list_t *tl, size_t offset)
+txg_list_create(txg_list_t *tl, spa_t *spa, size_t offset)
 {
 	int t;
 
 	mutex_init(&tl->tl_lock, NULL, MUTEX_DEFAULT, NULL);
 
 	tl->tl_offset = offset;
+	tl->tl_spa = spa;
 
 	for (t = 0; t < TXG_SIZE; t++)
 		tl->tl_head[t] = NULL;
@@ -714,15 +731,16 @@ txg_list_destroy(txg_list_t *tl)
 boolean_t
 txg_list_empty(txg_list_t *tl, uint64_t txg)
 {
+	txg_verify(tl->tl_spa, txg);
 	return (tl->tl_head[txg & TXG_MASK] == NULL);
 }
 
 /*
  * Returns true if all txg lists are empty.
  *
- * Warning: this is inherently racy (an item could be added immediately after this
- * function returns). We don't bother with the lock because it wouldn't change the
- * semantics.
+ * Warning: this is inherently racy (an item could be added immediately
+ * after this function returns). We don't bother with the lock because
+ * it wouldn't change the semantics.
  */
 boolean_t
 txg_all_lists_empty(txg_list_t *tl)
@@ -746,6 +764,7 @@ txg_list_add(txg_list_t *tl, void *p, ui
 	txg_node_t *tn = (txg_node_t *)((char *)p + tl->tl_offset);
 	boolean_t add;
 
+	txg_verify(tl->tl_spa, txg);
 	mutex_enter(&tl->tl_lock);
 	add = (tn->tn_member[t] == 0);
 	if (add) {
@@ -770,6 +789,7 @@ txg_list_add_tail(txg_list_t *tl, void *
 	txg_node_t *tn = (txg_node_t *)((char *)p + tl->tl_offset);
 	boolean_t add;
 
+	txg_verify(tl->tl_spa, txg);
 	mutex_enter(&tl->tl_lock);
 	add = (tn->tn_member[t] == 0);
 	if (add) {
@@ -797,6 +817,7 @@ txg_list_remove(txg_list_t *tl, uint64_t
 	txg_node_t *tn;
 	void *p = NULL;
 
+	txg_verify(tl->tl_spa, txg);
 	mutex_enter(&tl->tl_lock);
 	if ((tn = tl->tl_head[t]) != NULL) {
 		p = (char *)tn - tl->tl_offset;
@@ -818,6 +839,7 @@ txg_list_remove_this(txg_list_t *tl, voi
 	int t = txg & TXG_MASK;
 	txg_node_t *tn, **tp;
 
+	txg_verify(tl->tl_spa, txg);
 	mutex_enter(&tl->tl_lock);
 
 	for (tp = &tl->tl_head[t]; (tn = *tp) != NULL; tp = &tn->tn_next[t]) {
@@ -841,6 +863,7 @@ txg_list_member(txg_list_t *tl, void *p,
 	int t = txg & TXG_MASK;
 	txg_node_t *tn = (txg_node_t *)((char *)p + tl->tl_offset);
 
+	txg_verify(tl->tl_spa, txg);
 	return (tn->tn_member[t] != 0);
 }
 
@@ -853,6 +876,7 @@ txg_list_head(txg_list_t *tl, uint64_t t
 	int t = txg & TXG_MASK;
 	txg_node_t *tn = tl->tl_head[t];
 
+	txg_verify(tl->tl_spa, txg);
 	return (tn == NULL ? NULL : (char *)tn - tl->tl_offset);
 }
 
@@ -862,6 +886,7 @@ txg_list_next(txg_list_t *tl, void *p, u
 	int t = txg & TXG_MASK;
 	txg_node_t *tn = (txg_node_t *)((char *)p + tl->tl_offset);
 
+	txg_verify(tl->tl_spa, txg);
 	tn = tn->tn_next[t];
 
 	return (tn == NULL ? NULL : (char *)tn - tl->tl_offset);

Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/vdev.c
==============================================================================
--- vendor-sys/illumos/dist/uts/common/fs/zfs/vdev.c	Fri May 26 11:33:34 2017	(r318930)
+++ vendor-sys/illumos/dist/uts/common/fs/zfs/vdev.c	Fri May 26 11:35:34 2017	(r318931)
@@ -354,9 +354,9 @@ vdev_alloc_common(spa_t *spa, uint_t id,
 		vd->vdev_dtl[t] = range_tree_create(NULL, NULL,
 		    &vd->vdev_dtl_lock);
 	}
-	txg_list_create(&vd->vdev_ms_list,
+	txg_list_create(&vd->vdev_ms_list, spa,
 	    offsetof(struct metaslab, ms_txg_node));
-	txg_list_create(&vd->vdev_dtl_list,
+	txg_list_create(&vd->vdev_dtl_list, spa,
 	    offsetof(struct vdev, vdev_dtl_node));
 	vd->vdev_stat.vs_timestamp = gethrtime();
 	vdev_queue_init(vd);

Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/zil.c
==============================================================================
--- vendor-sys/illumos/dist/uts/common/fs/zfs/zil.c	Fri May 26 11:33:34 2017	(r318930)
+++ vendor-sys/illumos/dist/uts/common/fs/zfs/zil.c	Fri May 26 11:35:34 2017	(r318931)
@@ -20,7 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
  * Copyright (c) 2014 Integros [integros.com]
  */
 
@@ -85,16 +85,6 @@ static void zil_async_to_sync(zilog_t *z
 #define	LWB_EMPTY(lwb) ((BP_GET_LSIZE(&lwb->lwb_blk) - \
     sizeof (zil_chain_t)) == (lwb->lwb_sz - lwb->lwb_nused))
 
-
-/*
- * ziltest is by and large an ugly hack, but very useful in
- * checking replay without tedious work.
- * When running ziltest we want to keep all itx's and so maintain
- * a single list in the zl_itxg[] that uses a high txg: ZILTEST_TXG
- * We subtract TXG_CONCURRENT_STATES to allow for common code.
- */
-#define	ZILTEST_TXG (UINT64_MAX - TXG_CONCURRENT_STATES)
-
 static int
 zil_bp_compare(const void *x1, const void *x2)
 {


More information about the svn-src-all mailing list