409 if ((error = spa_reset(name)) != 0)
410 return (error);
411
412 if (!(flags & ZINJECT_NULL)) {
413 /*
414 * spa_inject_ref() will add an injection reference, which will
415 * prevent the pool from being removed from the namespace while
416 * still allowing it to be unloaded.
417 */
418 if ((spa = spa_inject_addref(name)) == NULL)
419 return (SET_ERROR(ENOENT));
420
421 handler = kmem_alloc(sizeof (inject_handler_t), KM_SLEEP);
422
423 rw_enter(&inject_lock, RW_WRITER);
424
425 *id = handler->zi_id = inject_next_id++;
426 handler->zi_spa = spa;
427 handler->zi_record = *record;
428 list_insert_tail(&inject_handlers, handler);
429 atomic_add_32(&zio_injection_enabled, 1);
430
431 rw_exit(&inject_lock);
432 }
433
434 /*
435 * Flush the ARC, so that any attempts to read this data will end up
436 * going to the ZIO layer. Note that this is a little overkill, but
437 * we don't have the necessary ARC interfaces to do anything else, and
438 * fault injection isn't a performance critical path.
439 */
440 if (flags & ZINJECT_FLUSH_ARC)
441 arc_flush(NULL);
442
443 return (0);
444 }
445
446 /*
447 * Returns the next record with an ID greater than that supplied to the
448 * function. Used to iterate over all handlers in the system.
449 */
486 {
487 inject_handler_t *handler;
488
489 rw_enter(&inject_lock, RW_WRITER);
490
491 for (handler = list_head(&inject_handlers); handler != NULL;
492 handler = list_next(&inject_handlers, handler))
493 if (handler->zi_id == id)
494 break;
495
496 if (handler == NULL) {
497 rw_exit(&inject_lock);
498 return (SET_ERROR(ENOENT));
499 }
500
501 list_remove(&inject_handlers, handler);
502 rw_exit(&inject_lock);
503
504 spa_inject_delref(handler->zi_spa);
505 kmem_free(handler, sizeof (inject_handler_t));
506 atomic_add_32(&zio_injection_enabled, -1);
507
508 return (0);
509 }
510
511 void
512 zio_inject_init(void)
513 {
514 rw_init(&inject_lock, NULL, RW_DEFAULT, NULL);
515 list_create(&inject_handlers, sizeof (inject_handler_t),
516 offsetof(inject_handler_t, zi_link));
517 }
518
519 void
520 zio_inject_fini(void)
521 {
522 list_destroy(&inject_handlers);
523 rw_destroy(&inject_lock);
524 }
|
409 if ((error = spa_reset(name)) != 0)
410 return (error);
411
412 if (!(flags & ZINJECT_NULL)) {
413 /*
414 * spa_inject_ref() will add an injection reference, which will
415 * prevent the pool from being removed from the namespace while
416 * still allowing it to be unloaded.
417 */
418 if ((spa = spa_inject_addref(name)) == NULL)
419 return (SET_ERROR(ENOENT));
420
421 handler = kmem_alloc(sizeof (inject_handler_t), KM_SLEEP);
422
423 rw_enter(&inject_lock, RW_WRITER);
424
425 *id = handler->zi_id = inject_next_id++;
426 handler->zi_spa = spa;
427 handler->zi_record = *record;
428 list_insert_tail(&inject_handlers, handler);
429 atomic_inc_32(&zio_injection_enabled);
430
431 rw_exit(&inject_lock);
432 }
433
434 /*
435 * Flush the ARC, so that any attempts to read this data will end up
436 * going to the ZIO layer. Note that this is a little overkill, but
437 * we don't have the necessary ARC interfaces to do anything else, and
438 * fault injection isn't a performance critical path.
439 */
440 if (flags & ZINJECT_FLUSH_ARC)
441 arc_flush(NULL);
442
443 return (0);
444 }
445
446 /*
447 * Returns the next record with an ID greater than that supplied to the
448 * function. Used to iterate over all handlers in the system.
449 */
486 {
487 inject_handler_t *handler;
488
489 rw_enter(&inject_lock, RW_WRITER);
490
491 for (handler = list_head(&inject_handlers); handler != NULL;
492 handler = list_next(&inject_handlers, handler))
493 if (handler->zi_id == id)
494 break;
495
496 if (handler == NULL) {
497 rw_exit(&inject_lock);
498 return (SET_ERROR(ENOENT));
499 }
500
501 list_remove(&inject_handlers, handler);
502 rw_exit(&inject_lock);
503
504 spa_inject_delref(handler->zi_spa);
505 kmem_free(handler, sizeof (inject_handler_t));
506 atomic_dec_32(&zio_injection_enabled);
507
508 return (0);
509 }
510
511 void
512 zio_inject_init(void)
513 {
514 rw_init(&inject_lock, NULL, RW_DEFAULT, NULL);
515 list_create(&inject_handlers, sizeof (inject_handler_t),
516 offsetof(inject_handler_t, zi_link));
517 }
518
519 void
520 zio_inject_fini(void)
521 {
522 list_destroy(&inject_handlers);
523 rw_destroy(&inject_lock);
524 }
|