163 ASSERT(vd->vdev_children == 0); |
163 ASSERT(vd->vdev_children == 0); |
164 |
164 |
165 zio_nowait(zio_read_phys(zio, vd, |
165 zio_nowait(zio_read_phys(zio, vd, |
166 vdev_label_offset(vd->vdev_psize, l, offset), |
166 vdev_label_offset(vd->vdev_psize, l, offset), |
167 size, buf, ZIO_CHECKSUM_LABEL, done, private, |
167 size, buf, ZIO_CHECKSUM_LABEL, done, private, |
168 ZIO_PRIORITY_SYNC_READ, ZIO_FLAG_SPECULATIVE | |
168 ZIO_PRIORITY_SYNC_READ, |
169 ZIO_FLAG_CANFAIL | ZIO_FLAG_CONFIG_HELD | ZIO_FLAG_DONT_RETRY)); |
169 ZIO_FLAG_CONFIG_HELD | ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE)); |
170 } |
170 } |
171 |
171 |
172 static void |
172 static void |
173 vdev_label_write(zio_t *zio, vdev_t *vd, int l, void *buf, uint64_t offset, |
173 vdev_label_write(zio_t *zio, vdev_t *vd, int l, void *buf, uint64_t offset, |
174 uint64_t size, zio_done_func_t *done, void *private) |
174 uint64_t size, zio_done_func_t *done, void *private) |
176 ASSERT(vd->vdev_children == 0); |
176 ASSERT(vd->vdev_children == 0); |
177 |
177 |
178 zio_nowait(zio_write_phys(zio, vd, |
178 zio_nowait(zio_write_phys(zio, vd, |
179 vdev_label_offset(vd->vdev_psize, l, offset), |
179 vdev_label_offset(vd->vdev_psize, l, offset), |
180 size, buf, ZIO_CHECKSUM_LABEL, done, private, |
180 size, buf, ZIO_CHECKSUM_LABEL, done, private, |
181 ZIO_PRIORITY_SYNC_WRITE, |
181 ZIO_PRIORITY_SYNC_WRITE, ZIO_FLAG_CONFIG_HELD | ZIO_FLAG_CANFAIL)); |
182 ZIO_FLAG_CANFAIL | ZIO_FLAG_CONFIG_HELD | ZIO_FLAG_DONT_RETRY)); |
|
183 } |
182 } |
184 |
183 |
185 /* |
184 /* |
186 * Generate the nvlist representing this vdev's config. |
185 * Generate the nvlist representing this vdev's config. |
187 */ |
186 */ |
188 nvlist_t * |
187 nvlist_t * |
189 vdev_config_generate(vdev_t *vd, int getstats) |
188 vdev_config_generate(vdev_t *vd, int getstats) |
190 { |
189 { |
191 nvlist_t *nv = NULL; |
190 nvlist_t *nv = NULL; |
192 |
191 |
193 VERIFY(nvlist_alloc(&nv, NV_UNIQUE_NAME, 0) == 0); |
192 VERIFY(nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) == 0); |
194 |
193 |
195 VERIFY(nvlist_add_string(nv, ZPOOL_CONFIG_TYPE, |
194 VERIFY(nvlist_add_string(nv, ZPOOL_CONFIG_TYPE, |
196 vd->vdev_ops->vdev_op_type) == 0); |
195 vd->vdev_ops->vdev_op_type) == 0); |
197 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_ID, vd->vdev_id) == 0); |
196 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_ID, vd->vdev_id) == 0); |
198 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_GUID, vd->vdev_guid) == 0); |
197 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_GUID, vd->vdev_guid) == 0); |
206 vd->vdev_devid) == 0); |
205 vd->vdev_devid) == 0); |
207 |
206 |
208 if (vd->vdev_wholedisk != -1ULL) |
207 if (vd->vdev_wholedisk != -1ULL) |
209 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, |
208 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, |
210 vd->vdev_wholedisk) == 0); |
209 vd->vdev_wholedisk) == 0); |
|
210 |
|
211 if (vd->vdev_not_present) |
|
212 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, 1) == 0); |
211 |
213 |
212 if (vd == vd->vdev_top) { |
214 if (vd == vd->vdev_top) { |
213 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_METASLAB_ARRAY, |
215 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_METASLAB_ARRAY, |
214 vd->vdev_ms_array) == 0); |
216 vd->vdev_ms_array) == 0); |
215 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_METASLAB_SHIFT, |
217 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_METASLAB_SHIFT, |
267 nvlist_t * |
269 nvlist_t * |
268 vdev_label_read_config(vdev_t *vd) |
270 vdev_label_read_config(vdev_t *vd) |
269 { |
271 { |
270 nvlist_t *config = NULL; |
272 nvlist_t *config = NULL; |
271 vdev_phys_t *vp; |
273 vdev_phys_t *vp; |
272 uint64_t version; |
|
273 zio_t *zio; |
274 zio_t *zio; |
274 int l; |
275 int l; |
275 |
276 |
276 if (vdev_is_dead(vd)) |
277 if (vdev_is_dead(vd)) |
277 return (NULL); |
278 return (NULL); |
278 |
279 |
279 vp = zio_buf_alloc(sizeof (vdev_phys_t)); |
280 vp = zio_buf_alloc(sizeof (vdev_phys_t)); |
280 |
281 |
281 for (l = 0; l < VDEV_LABELS; l++) { |
282 for (l = 0; l < VDEV_LABELS; l++) { |
282 |
283 |
283 zio = zio_root(vd->vdev_spa, NULL, NULL, |
284 zio = zio_root(vd->vdev_spa, NULL, NULL, ZIO_FLAG_CANFAIL | |
284 ZIO_FLAG_CANFAIL | ZIO_FLAG_CONFIG_HELD); |
285 ZIO_FLAG_SPECULATIVE | ZIO_FLAG_CONFIG_HELD); |
285 |
286 |
286 vdev_label_read(zio, vd, l, vp, |
287 vdev_label_read(zio, vd, l, vp, |
287 offsetof(vdev_label_t, vl_vdev_phys), |
288 offsetof(vdev_label_t, vl_vdev_phys), |
288 sizeof (vdev_phys_t), NULL, NULL); |
289 sizeof (vdev_phys_t), NULL, NULL); |
289 |
290 |
290 if (zio_wait(zio) == 0 && |
291 if (zio_wait(zio) == 0 && |
291 nvlist_unpack(vp->vp_nvlist, sizeof (vp->vp_nvlist), |
292 nvlist_unpack(vp->vp_nvlist, sizeof (vp->vp_nvlist), |
292 &config, 0) == 0 && |
293 &config, 0) == 0) |
293 nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, |
|
294 &version) == 0 && |
|
295 version == UBERBLOCK_VERSION) |
|
296 break; |
294 break; |
297 |
295 |
298 if (config != NULL) { |
296 if (config != NULL) { |
299 nvlist_free(config); |
297 nvlist_free(config); |
300 config = NULL; |
298 config = NULL; |
339 |
337 |
340 /* |
338 /* |
341 * Check whether this device is already in use. |
339 * Check whether this device is already in use. |
342 * Ignore the check if crtxg == 0, which we use for device removal. |
340 * Ignore the check if crtxg == 0, which we use for device removal. |
343 */ |
341 */ |
344 if (crtxg != 0 && (label = vdev_label_read_config(vd)) != NULL) { |
342 if (crtxg != 0 && |
345 uint64_t version, state, pool_guid, device_guid, txg; |
343 (label = vdev_label_read_config(vd)) != NULL) { |
|
344 uint64_t state, pool_guid, device_guid, txg; |
346 uint64_t mycrtxg = 0; |
345 uint64_t mycrtxg = 0; |
347 |
346 |
348 (void) nvlist_lookup_uint64(label, ZPOOL_CONFIG_CREATE_TXG, |
347 (void) nvlist_lookup_uint64(label, ZPOOL_CONFIG_CREATE_TXG, |
349 &mycrtxg); |
348 &mycrtxg); |
350 |
349 |
351 if (nvlist_lookup_uint64(label, ZPOOL_CONFIG_VERSION, |
350 if (nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_STATE, |
352 &version) == 0 && version == UBERBLOCK_VERSION && |
|
353 nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_STATE, |
|
354 &state) == 0 && state == POOL_STATE_ACTIVE && |
351 &state) == 0 && state == POOL_STATE_ACTIVE && |
355 nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_GUID, |
352 nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_GUID, |
356 &pool_guid) == 0 && |
353 &pool_guid) == 0 && |
357 nvlist_lookup_uint64(label, ZPOOL_CONFIG_GUID, |
354 nvlist_lookup_uint64(label, ZPOOL_CONFIG_GUID, |
358 &device_guid) == 0 && |
355 &device_guid) == 0 && |
388 VERIFY(nvlist_add_uint64(label, ZPOOL_CONFIG_CREATE_TXG, crtxg) == 0); |
385 VERIFY(nvlist_add_uint64(label, ZPOOL_CONFIG_CREATE_TXG, crtxg) == 0); |
389 |
386 |
390 buf = vp->vp_nvlist; |
387 buf = vp->vp_nvlist; |
391 buflen = sizeof (vp->vp_nvlist); |
388 buflen = sizeof (vp->vp_nvlist); |
392 |
389 |
393 if (nvlist_pack(label, &buf, &buflen, NV_ENCODE_XDR, 0) != 0) { |
390 if (nvlist_pack(label, &buf, &buflen, NV_ENCODE_XDR, KM_SLEEP) != 0) { |
394 nvlist_free(label); |
391 nvlist_free(label); |
395 zio_buf_free(vp, sizeof (vdev_phys_t)); |
392 zio_buf_free(vp, sizeof (vdev_phys_t)); |
396 return (EINVAL); |
393 return (EINVAL); |
397 } |
394 } |
398 |
395 |
489 uberblock_t *ubbest = zio->io_private; |
486 uberblock_t *ubbest = zio->io_private; |
490 spa_t *spa = zio->io_spa; |
487 spa_t *spa = zio->io_spa; |
491 |
488 |
492 ASSERT3U(zio->io_size, ==, sizeof (uberblock_phys_t)); |
489 ASSERT3U(zio->io_size, ==, sizeof (uberblock_phys_t)); |
493 |
490 |
494 if (uberblock_verify(ub) == 0) { |
491 if (zio->io_error == 0 && uberblock_verify(ub) == 0) { |
495 mutex_enter(&spa->spa_uberblock_lock); |
492 mutex_enter(&spa->spa_uberblock_lock); |
496 if (vdev_uberblock_compare(ub, ubbest) > 0) |
493 if (vdev_uberblock_compare(ub, ubbest) > 0) |
497 *ubbest = *ub; |
494 *ubbest = *ub; |
498 mutex_exit(&spa->spa_uberblock_lock); |
495 mutex_exit(&spa->spa_uberblock_lock); |
499 } |
496 } |
643 bzero(vp, sizeof (vdev_phys_t)); |
640 bzero(vp, sizeof (vdev_phys_t)); |
644 |
641 |
645 buf = vp->vp_nvlist; |
642 buf = vp->vp_nvlist; |
646 buflen = sizeof (vp->vp_nvlist); |
643 buflen = sizeof (vp->vp_nvlist); |
647 |
644 |
648 if (nvlist_pack(label, &buf, &buflen, NV_ENCODE_XDR, 0) == 0) |
645 if (nvlist_pack(label, &buf, &buflen, NV_ENCODE_XDR, KM_SLEEP) == 0) |
649 vdev_label_write(zio, vd, l, vp, |
646 vdev_label_write(zio, vd, l, vp, |
650 offsetof(vdev_label_t, vl_vdev_phys), sizeof (vdev_phys_t), |
647 offsetof(vdev_label_t, vl_vdev_phys), sizeof (vdev_phys_t), |
651 vdev_sync_label_done, NULL); |
648 vdev_sync_label_done, NULL); |
652 |
649 |
653 zio_buf_free(vp, sizeof (vdev_phys_t)); |
650 zio_buf_free(vp, sizeof (vdev_phys_t)); |