FreeBSD ZFS
The Zettabyte File System
|
Routines to manage the on-disk persistent error log. More...
#include <sys/dmu_tx.h>
#include <sys/spa.h>
#include <sys/spa_impl.h>
#include <sys/zap.h>
#include <sys/zio.h>
Go to the source code of this file.
Functions | |
static void | bookmark_to_name (zbookmark_t *zb, char *buf, size_t len) |
Convert a bookmark to a string. | |
static void | name_to_bookmark (char *buf, zbookmark_t *zb) |
Convert a string to a bookmark. | |
void | spa_log_error (spa_t *spa, zio_t *zio) |
Log an uncorrectable error to the persistent error log. | |
uint64_t | spa_get_errlog_size (spa_t *spa) |
Return the number of errors currently in the error log. | |
static int | process_error_log (spa_t *spa, uint64_t obj, void *addr, size_t *count) |
static int | process_error_list (avl_tree_t *list, void *addr, size_t *count) |
int | spa_get_errlog (spa_t *spa, void *uaddr, size_t *count) |
Copy all known errors to userland as an array of bookmarks. | |
void | spa_errlog_rotate (spa_t *spa) |
Called when a scrub completes. | |
void | spa_errlog_drain (spa_t *spa) |
Discard any pending errors from the spa_t. | |
static void | sync_error_list (spa_t *spa, avl_tree_t *t, uint64_t *obj, dmu_tx_t *tx) |
Process a list of errors into the current on-disk log. | |
void | spa_errlog_sync (spa_t *spa, uint64_t txg) |
Sync the error log out to disk. |
Routines to manage the on-disk persistent error log.
Each pool stores a log of all logical data errors seen during normal operation. This is actually the union of two distinct logs: the last log, and the current log. All errors seen are logged to the current log. When a scrub completes, the current log becomes the last log, the last log is thrown out, and the current log is reinitialized. This way, if an error is somehow corrected, a new scrub will show that that it no longer exists, and will be deleted from the log when the scrub completes.
The log is stored using a ZAP object whose key is a string form of the zbookmark tuple (objset, object, level, blkid), and whose contents is an optional 'objset:object' human-readable string describing the data. When an error is first logged, this string will be empty, indicating that no name is known. This prevents us from having to issue a potentially large amount of I/O to discover the object name during an error path. Instead, we do the calculation when the data is requested, storing the result so future queries will be faster.
This log is then shipped into an nvlist where the key is the dataset name and the value is the object name. Userland is then responsible for uniquifying this list and displaying it to the user.
Definition in file spa_errlog.c.
static void bookmark_to_name | ( | zbookmark_t * | zb, |
char * | buf, | ||
size_t | len | ||
) | [static] |
Convert a bookmark to a string.
Definition at line 62 of file spa_errlog.c.
static void name_to_bookmark | ( | char * | buf, |
zbookmark_t * | zb | ||
) | [static] |
Convert a string to a bookmark.
Definition at line 74 of file spa_errlog.c.
static int process_error_list | ( | avl_tree_t * | list, |
void * | addr, | ||
size_t * | count | ||
) | [static] |
Definition at line 198 of file spa_errlog.c.
static int process_error_log | ( | spa_t * | spa, |
uint64_t | obj, | ||
void * | addr, | ||
size_t * | count | ||
) | [static] |
Definition at line 164 of file spa_errlog.c.
void spa_errlog_drain | ( | spa_t * | spa | ) |
Discard any pending errors from the spa_t.
Called when unloading a faulted pool, as the errors encountered during the open cannot be synced to disk.
Definition at line 277 of file spa_errlog.c.
void spa_errlog_rotate | ( | spa_t * | spa | ) |
Called when a scrub completes.
This simply set a bit which tells which AVL tree to add new errors. spa_errlog_sync() is responsible for actually syncing the changes to the underlying objects.
Definition at line 265 of file spa_errlog.c.
void spa_errlog_sync | ( | spa_t * | spa, |
uint64_t | txg | ||
) |
Sync the error log out to disk.
This is a little tricky because the act of writing the error log requires the spa_errlist_lock. So, we need to lock the error lists, take a copy of the lists, and then reinitialize them. Then, we drop the error list lock and take the error log lock, at which point we do the errlog processing. Then, if we encounter an I/O error during this process, we can successfully add the error to the list. Note that this will result in the perpetual recycling of errors, but it is an unlikely situation and not a performance critical operation.
Definition at line 341 of file spa_errlog.c.
int spa_get_errlog | ( | spa_t * | spa, |
void * | uaddr, | ||
size_t * | count | ||
) |
Copy all known errors to userland as an array of bookmarks.
This is actually a union of the on-disk last log and current log, as well as any pending error requests.
Because the act of reading the on-disk log could cause errors to be generated, we have two separate locks: one for the error log and one for the in-core error lists. We only need the error list lock to log and error, so we grab the error log lock while we read the on-disk logs, and only pick up the error list lock when we are finished.
Definition at line 231 of file spa_errlog.c.
uint64_t spa_get_errlog_size | ( | spa_t * | spa | ) |
Return the number of errors currently in the error log.
This is actually the sum of both the last log and the current log, since we don't know the union of these logs until we reach userland.
Definition at line 138 of file spa_errlog.c.
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().
Definition at line 93 of file spa_errlog.c.
Process a list of errors into the current on-disk log.
Definition at line 300 of file spa_errlog.c.