* Log an uncorrectable error to the persistent error log. We add it to the * spa's list of pending errors. The changes are actually synced out to disk * during spa_errlog_sync(). */
| 90 | * during spa_errlog_sync(). |
| 91 | */ |
| 92 | void |
| 93 | spa_log_error(spa_t *spa, const zbookmark_phys_t *zb) |
| 94 | { |
| 95 | spa_error_entry_t search; |
| 96 | spa_error_entry_t *new; |
| 97 | avl_tree_t *tree; |
| 98 | avl_index_t where; |
| 99 | |
| 100 | /* |
| 101 | * If we are trying to import a pool, ignore any errors, as we won't be |
| 102 | * writing to the pool any time soon. |
| 103 | */ |
| 104 | if (spa_load_state(spa) == SPA_LOAD_TRYIMPORT) |
| 105 | return; |
| 106 | |
| 107 | mutex_enter(&spa->spa_errlist_lock); |
| 108 | |
| 109 | /* |
| 110 | * If we have had a request to rotate the log, log it to the next list |
| 111 | * instead of the current one. |
| 112 | */ |
| 113 | if (spa->spa_scrub_active || spa->spa_scrub_finished) |
| 114 | tree = &spa->spa_errlist_scrub; |
| 115 | else |
| 116 | tree = &spa->spa_errlist_last; |
| 117 | |
| 118 | search.se_bookmark = *zb; |
| 119 | if (avl_find(tree, &search, &where) != NULL) { |
| 120 | mutex_exit(&spa->spa_errlist_lock); |
| 121 | return; |
| 122 | } |
| 123 | |
| 124 | new = kmem_zalloc(sizeof (spa_error_entry_t), KM_SLEEP); |
| 125 | new->se_bookmark = *zb; |
| 126 | avl_insert(tree, new, where); |
| 127 | |
| 128 | mutex_exit(&spa->spa_errlist_lock); |
| 129 | } |
| 130 | |
| 131 | /* |
| 132 | * Return the number of errors currently in the error log. This is actually the |
no test coverage detected