usr/src/uts/common/fs/zfs/vdev_label.c
changeset 1544 938876158511
parent 1485 e971e58d18f6
child 1601 438b928f80c7
equal deleted inserted replaced
1543:a02daabdf1b3 1544:938876158511
   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));