Skip to content

Commit fb42a49

Browse files
Prakash Suryabehlendorf
authored andcommitted
Illumos 5213 - panic in metaslab_init due to space_map_open returning ENXIO
5213 panic in metaslab_init due to space_map_open returning ENXIO Reviewed by: Matthew Ahrens mahrens@delphix.com Reviewed by: George Wilson george.wilson@delphix.com References: https://www.illumos.org/issues/5213 https://reviews.csiden.org/r/110 Porting notes: For the Linux port, KM_SLEEP was replaced with KM_PUSHPAGE. Ported by: Turbo Fredriksson <turbo@bayour.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #2745
1 parent a82db4e commit fb42a49

File tree

3 files changed

+40
-26
lines changed

3 files changed

+40
-26
lines changed

include/sys/metaslab.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ typedef struct metaslab_ops {
4242

4343
extern metaslab_ops_t *zfs_metaslab_ops;
4444

45-
metaslab_t *metaslab_init(metaslab_group_t *, uint64_t,
46-
uint64_t, uint64_t);
45+
int metaslab_init(metaslab_group_t *, uint64_t, uint64_t, uint64_t,
46+
metaslab_t **);
4747
void metaslab_fini(metaslab_t *);
4848

4949
void metaslab_load_wait(metaslab_t *);

module/zfs/metaslab.c

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,28 +1237,36 @@ metaslab_unload(metaslab_t *msp)
12371237
msp->ms_weight &= ~METASLAB_ACTIVE_MASK;
12381238
}
12391239

1240-
metaslab_t *
1241-
metaslab_init(metaslab_group_t *mg, uint64_t id, uint64_t object, uint64_t txg)
1240+
int
1241+
metaslab_init(metaslab_group_t *mg, uint64_t id, uint64_t object, uint64_t txg,
1242+
metaslab_t **msp)
12421243
{
12431244
vdev_t *vd = mg->mg_vd;
12441245
objset_t *mos = vd->vdev_spa->spa_meta_objset;
1245-
metaslab_t *msp;
1246+
metaslab_t *ms;
1247+
int error;
12461248

1247-
msp = kmem_zalloc(sizeof (metaslab_t), KM_PUSHPAGE);
1248-
mutex_init(&msp->ms_lock, NULL, MUTEX_DEFAULT, NULL);
1249-
cv_init(&msp->ms_load_cv, NULL, CV_DEFAULT, NULL);
1250-
msp->ms_id = id;
1251-
msp->ms_start = id << vd->vdev_ms_shift;
1252-
msp->ms_size = 1ULL << vd->vdev_ms_shift;
1249+
ms = kmem_zalloc(sizeof (metaslab_t), KM_PUSHPAGE);
1250+
mutex_init(&ms->ms_lock, NULL, MUTEX_DEFAULT, NULL);
1251+
cv_init(&ms->ms_load_cv, NULL, CV_DEFAULT, NULL);
1252+
ms->ms_id = id;
1253+
ms->ms_start = id << vd->vdev_ms_shift;
1254+
ms->ms_size = 1ULL << vd->vdev_ms_shift;
12531255

12541256
/*
12551257
* We only open space map objects that already exist. All others
12561258
* will be opened when we finally allocate an object for it.
12571259
*/
12581260
if (object != 0) {
1259-
VERIFY0(space_map_open(&msp->ms_sm, mos, object, msp->ms_start,
1260-
msp->ms_size, vd->vdev_ashift, &msp->ms_lock));
1261-
ASSERT(msp->ms_sm != NULL);
1261+
error = space_map_open(&ms->ms_sm, mos, object, ms->ms_start,
1262+
ms->ms_size, vd->vdev_ashift, &ms->ms_lock);
1263+
1264+
if (error != 0) {
1265+
kmem_free(ms, sizeof (metaslab_t));
1266+
return (error);
1267+
}
1268+
1269+
ASSERT(ms->ms_sm != NULL);
12621270
}
12631271

12641272
/*
@@ -1268,11 +1276,11 @@ metaslab_init(metaslab_group_t *mg, uint64_t id, uint64_t object, uint64_t txg)
12681276
* addition of new space; and for debugging, it ensures that we'd
12691277
* data fault on any attempt to use this metaslab before it's ready.
12701278
*/
1271-
msp->ms_tree = range_tree_create(&metaslab_rt_ops, msp, &msp->ms_lock);
1272-
metaslab_group_add(mg, msp);
1279+
ms->ms_tree = range_tree_create(&metaslab_rt_ops, ms, &ms->ms_lock);
1280+
metaslab_group_add(mg, ms);
12731281

1274-
msp->ms_fragmentation = metaslab_fragmentation(msp);
1275-
msp->ms_ops = mg->mg_class->mc_ops;
1282+
ms->ms_fragmentation = metaslab_fragmentation(ms);
1283+
ms->ms_ops = mg->mg_class->mc_ops;
12761284

12771285
/*
12781286
* If we're opening an existing pool (txg == 0) or creating
@@ -1281,25 +1289,27 @@ metaslab_init(metaslab_group_t *mg, uint64_t id, uint64_t object, uint64_t txg)
12811289
* does not become available until after this txg has synced.
12821290
*/
12831291
if (txg <= TXG_INITIAL)
1284-
metaslab_sync_done(msp, 0);
1292+
metaslab_sync_done(ms, 0);
12851293

12861294
/*
12871295
* If metaslab_debug_load is set and we're initializing a metaslab
12881296
* that has an allocated space_map object then load the its space
12891297
* map so that can verify frees.
12901298
*/
1291-
if (metaslab_debug_load && msp->ms_sm != NULL) {
1292-
mutex_enter(&msp->ms_lock);
1293-
VERIFY0(metaslab_load(msp));
1294-
mutex_exit(&msp->ms_lock);
1299+
if (metaslab_debug_load && ms->ms_sm != NULL) {
1300+
mutex_enter(&ms->ms_lock);
1301+
VERIFY0(metaslab_load(ms));
1302+
mutex_exit(&ms->ms_lock);
12951303
}
12961304

12971305
if (txg != 0) {
12981306
vdev_dirty(vd, 0, NULL, txg);
1299-
vdev_dirty(vd, VDD_METASLAB, msp, txg);
1307+
vdev_dirty(vd, VDD_METASLAB, ms, txg);
13001308
}
13011309

1302-
return (msp);
1310+
*msp = ms;
1311+
1312+
return (0);
13031313
}
13041314

13051315
void

module/zfs/vdev.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -876,7 +876,11 @@ vdev_metaslab_init(vdev_t *vd, uint64_t txg)
876876
if (error)
877877
return (error);
878878
}
879-
vd->vdev_ms[m] = metaslab_init(vd->vdev_mg, m, object, txg);
879+
880+
error = metaslab_init(vd->vdev_mg, m, object, txg,
881+
&(vd->vdev_ms[m]));
882+
if (error)
883+
return (error);
880884
}
881885

882886
if (txg == 0)

0 commit comments

Comments
 (0)