Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Jan 2015 00:44:15 +0000 (UTC)
From:      Xin LI <delphij@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r277553 - in stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs: . sys
Message-ID:  <201501230044.t0N0iFNq020002@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: delphij
Date: Fri Jan 23 00:44:14 2015
New Revision: 277553
URL: https://svnweb.freebsd.org/changeset/base/277553

Log:
  MFC r275594: MFV r275540:
  
  When importing a pool, don't assume that the passed pool configuration
  at vdev_load is always vaild.  It's possible that a stale configuration
  that comes with extra vdevs, where metaslab_init() would fail because
  of lower layer returns error.
  
  Change the code to make metaslab_init() handle and return errors from
  lower layer and pass it back to upper layer and handle it there.
  
  Illumos issue:
      5213 panic in metaslab_init due to space_map_open returning ENXIO

Modified:
  stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c
  stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab.h
  stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c	Fri Jan 23 00:40:43 2015	(r277552)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c	Fri Jan 23 00:44:14 2015	(r277553)
@@ -1318,28 +1318,36 @@ metaslab_unload(metaslab_t *msp)
 	msp->ms_weight &= ~METASLAB_ACTIVE_MASK;
 }
 
-metaslab_t *
-metaslab_init(metaslab_group_t *mg, uint64_t id, uint64_t object, uint64_t txg)
+int
+metaslab_init(metaslab_group_t *mg, uint64_t id, uint64_t object, uint64_t txg,
+    metaslab_t **msp)
 {
 	vdev_t *vd = mg->mg_vd;
 	objset_t *mos = vd->vdev_spa->spa_meta_objset;
-	metaslab_t *msp;
+	metaslab_t *ms;
+	int error;
 
-	msp = kmem_zalloc(sizeof (metaslab_t), KM_SLEEP);
-	mutex_init(&msp->ms_lock, NULL, MUTEX_DEFAULT, NULL);
-	cv_init(&msp->ms_load_cv, NULL, CV_DEFAULT, NULL);
-	msp->ms_id = id;
-	msp->ms_start = id << vd->vdev_ms_shift;
-	msp->ms_size = 1ULL << vd->vdev_ms_shift;
+	ms = kmem_zalloc(sizeof (metaslab_t), KM_SLEEP);
+	mutex_init(&ms->ms_lock, NULL, MUTEX_DEFAULT, NULL);
+	cv_init(&ms->ms_load_cv, NULL, CV_DEFAULT, NULL);
+	ms->ms_id = id;
+	ms->ms_start = id << vd->vdev_ms_shift;
+	ms->ms_size = 1ULL << vd->vdev_ms_shift;
 
 	/*
 	 * We only open space map objects that already exist. All others
 	 * will be opened when we finally allocate an object for it.
 	 */
 	if (object != 0) {
-		VERIFY0(space_map_open(&msp->ms_sm, mos, object, msp->ms_start,
-		    msp->ms_size, vd->vdev_ashift, &msp->ms_lock));
-		ASSERT(msp->ms_sm != NULL);
+		error = space_map_open(&ms->ms_sm, mos, object, ms->ms_start,
+		    ms->ms_size, vd->vdev_ashift, &ms->ms_lock);
+
+		if (error != 0) {
+			kmem_free(ms, sizeof (metaslab_t));
+			return (error);
+		}
+
+		ASSERT(ms->ms_sm != NULL);
 	}
 
 	/*
@@ -1349,11 +1357,11 @@ metaslab_init(metaslab_group_t *mg, uint
 	 * addition of new space; and for debugging, it ensures that we'd
 	 * data fault on any attempt to use this metaslab before it's ready.
 	 */
-	msp->ms_tree = range_tree_create(&metaslab_rt_ops, msp, &msp->ms_lock);
-	metaslab_group_add(mg, msp);
+	ms->ms_tree = range_tree_create(&metaslab_rt_ops, ms, &ms->ms_lock);
+	metaslab_group_add(mg, ms);
 
-	msp->ms_fragmentation = metaslab_fragmentation(msp);
-	msp->ms_ops = mg->mg_class->mc_ops;
+	ms->ms_fragmentation = metaslab_fragmentation(ms);
+	ms->ms_ops = mg->mg_class->mc_ops;
 
 	/*
 	 * If we're opening an existing pool (txg == 0) or creating
@@ -1362,25 +1370,27 @@ metaslab_init(metaslab_group_t *mg, uint
 	 * does not become available until after this txg has synced.
 	 */
 	if (txg <= TXG_INITIAL)
-		metaslab_sync_done(msp, 0);
+		metaslab_sync_done(ms, 0);
 
 	/*
 	 * If metaslab_debug_load is set and we're initializing a metaslab
 	 * that has an allocated space_map object then load the its space
 	 * map so that can verify frees.
 	 */
-	if (metaslab_debug_load && msp->ms_sm != NULL) {
-		mutex_enter(&msp->ms_lock);
-		VERIFY0(metaslab_load(msp));
-		mutex_exit(&msp->ms_lock);
+	if (metaslab_debug_load && ms->ms_sm != NULL) {
+		mutex_enter(&ms->ms_lock);
+		VERIFY0(metaslab_load(ms));
+		mutex_exit(&ms->ms_lock);
 	}
 
 	if (txg != 0) {
 		vdev_dirty(vd, 0, NULL, txg);
-		vdev_dirty(vd, VDD_METASLAB, msp, txg);
+		vdev_dirty(vd, VDD_METASLAB, ms, txg);
 	}
 
-	return (msp);
+	*msp = ms;
+
+	return (0);
 }
 
 void

Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab.h
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab.h	Fri Jan 23 00:40:43 2015	(r277552)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab.h	Fri Jan 23 00:44:14 2015	(r277553)
@@ -42,8 +42,8 @@ typedef struct metaslab_ops {
 
 extern metaslab_ops_t *zfs_metaslab_ops;
 
-metaslab_t *metaslab_init(metaslab_group_t *, uint64_t,
-    uint64_t, uint64_t);
+int metaslab_init(metaslab_group_t *, uint64_t, uint64_t, uint64_t,
+    metaslab_t **);
 void metaslab_fini(metaslab_t *);
 
 void metaslab_load_wait(metaslab_t *);

Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c	Fri Jan 23 00:40:43 2015	(r277552)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c	Fri Jan 23 00:44:14 2015	(r277553)
@@ -955,7 +955,11 @@ vdev_metaslab_init(vdev_t *vd, uint64_t 
 			if (error)
 				return (error);
 		}
-		vd->vdev_ms[m] = metaslab_init(vd->vdev_mg, m, object, txg);
+
+		error = metaslab_init(vd->vdev_mg, m, object, txg,
+		    &(vd->vdev_ms[m]));
+		if (error)
+			return (error);
 	}
 
 	if (txg == 0)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201501230044.t0N0iFNq020002>