FreeBSD ZFS
The Zettabyte File System
|
#include <sys/spa.h>
#include <sys/zio.h>
#include <sys/dmu.h>
#include <sys/space_map.h>
#include <sys/fs/zfs.h>
#include <sys/space_map.h>
Go to the source code of this file.
Typedefs | |
typedef enum vdev_dtl_type | vdev_dtl_type_t |
typedef enum vdev_config_flag | vdev_config_flag_t |
Enumerations | |
enum | vdev_dtl_type { DTL_MISSING, DTL_PARTIAL, DTL_SCRUB, DTL_OUTAGE, DTL_TYPES } |
enum | vdev_config_flag { VDEV_CONFIG_SPARE = 1 << 0, VDEV_CONFIG_L2CACHE = 1 << 1, VDEV_CONFIG_REMOVING = 1 << 2 } |
enum | vdev_labeltype_t { VDEV_LABEL_CREATE, VDEV_LABEL_REPLACE, VDEV_LABEL_SPARE, VDEV_LABEL_REMOVE, VDEV_LABEL_L2CACHE, VDEV_LABEL_SPLIT } |
Functions | |
int | vdev_open (vdev_t *) |
Prepare a virtual device for access. | |
void | vdev_open_children (vdev_t *) |
boolean_t | vdev_uses_zvols (vdev_t *) |
int | vdev_validate (vdev_t *, boolean_t) |
Validates vdev label contents. | |
void | vdev_close (vdev_t *) |
Close a virtual device. | |
int | vdev_create (vdev_t *, uint64_t txg, boolean_t isreplace) |
void | vdev_reopen (vdev_t *) |
Reopen all interior vdevs and any unopened leaves. | |
int | vdev_validate_aux (vdev_t *vd) |
The special vdev case is used for hot spares and l2cache devices. | |
zio_t * | vdev_probe (vdev_t *vd, zio_t *pio) |
Determine whether this device is accessible. | |
boolean_t | vdev_is_bootable (vdev_t *vd) |
Check the vdev configuration to ensure that it's capable of supporting a root pool. | |
vdev_t * | vdev_lookup_top (spa_t *spa, uint64_t vdev) |
vdev_t * | vdev_lookup_by_guid (vdev_t *vd, uint64_t guid) |
void | vdev_dtl_dirty (vdev_t *vd, vdev_dtl_type_t d, uint64_t txg, uint64_t size) |
boolean_t | vdev_dtl_contains (vdev_t *vd, vdev_dtl_type_t d, uint64_t txg, uint64_t size) |
boolean_t | vdev_dtl_empty (vdev_t *vd, vdev_dtl_type_t d) |
void | vdev_dtl_reassess (vdev_t *vd, uint64_t txg, uint64_t scrub_txg, int scrub_done) |
Reassess DTLs after a config change or scrub completion. | |
boolean_t | vdev_dtl_required (vdev_t *vd) |
Determine whether the specified vdev can be offlined/detached/removed without losing data. | |
boolean_t | vdev_resilver_needed (vdev_t *vd, uint64_t *minp, uint64_t *maxp) |
Determine if resilver is needed, and if so the txg range. | |
void | vdev_hold (vdev_t *) |
void | vdev_rele (vdev_t *) |
int | vdev_metaslab_init (vdev_t *vd, uint64_t txg) |
void | vdev_metaslab_fini (vdev_t *vd) |
void | vdev_metaslab_set_size (vdev_t *) |
void | vdev_expand (vdev_t *vd, uint64_t txg) |
Expand a vdev if possible. | |
void | vdev_split (vdev_t *vd) |
Split a vdev. | |
void | vdev_get_stats (vdev_t *vd, vdev_stat_t *vs) |
void | vdev_clear_stats (vdev_t *vd) |
void | vdev_stat_update (zio_t *zio, uint64_t psize) |
void | vdev_scan_stat_init (vdev_t *vd) |
void | vdev_propagate_state (vdev_t *vd) |
Propagate vdev state up from children to parent. | |
void | vdev_set_state (vdev_t *vd, boolean_t isopen, vdev_state_t state, vdev_aux_t aux) |
Set a vdev's state. | |
void | vdev_space_update (vdev_t *vd, int64_t alloc_delta, int64_t defer_delta, int64_t space_delta) |
Update the in-core space usage stats for this vdev, its metaslab class, and the root vdev. | |
uint64_t | vdev_psize_to_asize (vdev_t *vd, uint64_t psize) |
int | vdev_fault (spa_t *spa, uint64_t guid, vdev_aux_t aux) |
Mark the given vdev faulted. | |
int | vdev_degrade (spa_t *spa, uint64_t guid, vdev_aux_t aux) |
Mark the given vdev degraded. | |
int | vdev_online (spa_t *spa, uint64_t guid, uint64_t flags, vdev_state_t *) |
Online the given vdev. | |
int | vdev_offline (spa_t *spa, uint64_t guid, uint64_t flags) |
void | vdev_clear (spa_t *spa, vdev_t *vd) |
Clear the error counts associated with this vdev. | |
boolean_t | vdev_is_dead (vdev_t *vd) |
boolean_t | vdev_readable (vdev_t *vd) |
boolean_t | vdev_writeable (vdev_t *vd) |
boolean_t | vdev_allocatable (vdev_t *vd) |
boolean_t | vdev_accessible (vdev_t *vd, zio_t *zio) |
void | vdev_cache_init (vdev_t *vd) |
void | vdev_cache_fini (vdev_t *vd) |
int | vdev_cache_read (zio_t *zio) |
Read data from the cache. | |
void | vdev_cache_write (zio_t *zio) |
Update cache contents upon write completion. | |
void | vdev_cache_purge (vdev_t *vd) |
void | vdev_queue_init (vdev_t *vd) |
void | vdev_queue_fini (vdev_t *vd) |
zio_t * | vdev_queue_io (zio_t *zio) |
void | vdev_queue_io_done (zio_t *zio) |
void | vdev_config_dirty (vdev_t *vd) |
Mark a top-level vdev's config as dirty, placing it on the dirty list so that it will be written out next time the vdev configuration is synced. | |
void | vdev_config_clean (vdev_t *vd) |
int | vdev_config_sync (vdev_t **svd, int svdcount, uint64_t txg, boolean_t) |
Sync the uberblock and any changes to the vdev configuration. | |
void | vdev_state_dirty (vdev_t *vd) |
Mark a top-level vdev's state as dirty, so that the next pass of spa_sync() can convert this into vdev_config_dirty(). | |
void | vdev_state_clean (vdev_t *vd) |
void | vdev_top_config_generate (spa_t *spa, nvlist_t *config) |
Generate a view of the top-level vdevs. | |
nvlist_t * | vdev_config_generate (spa_t *spa, vdev_t *vd, boolean_t getstats, vdev_config_flag_t flags) |
Generate the nvlist representing this vdev's config. | |
uint64_t | vdev_label_offset (uint64_t psize, int l, uint64_t offset) |
Basic routines to read and write from a vdev label. | |
int | vdev_label_number (uint64_t psise, uint64_t offset) |
Returns back the vdev label associated with the passed in offset. | |
nvlist_t * | vdev_label_read_config (vdev_t *vd, uint64_t txg) |
Returns the configuration from the label of the given vdev. | |
void | vdev_uberblock_load (vdev_t *, struct uberblock *, nvlist_t **) |
Reads the 'best' uberblock from disk along with its associated configuration. | |
int | vdev_label_init (vdev_t *vd, uint64_t txg, vdev_labeltype_t reason) |
Initialize a vdev label. | |
Variables | |
boolean_t | zfs_nocacheflush |
Tunable parameter for debugging or performance analysis. | |
boolean_t | zfs_notrim |
typedef enum vdev_config_flag vdev_config_flag_t |
typedef enum vdev_dtl_type vdev_dtl_type_t |
enum vdev_config_flag |
enum vdev_dtl_type |
enum vdev_labeltype_t |
void vdev_cache_fini | ( | vdev_t * | vd | ) |
Definition at line 412 of file vdev_cache.c.
void vdev_cache_init | ( | vdev_t * | vd | ) |
Definition at line 396 of file vdev_cache.c.
void vdev_cache_purge | ( | vdev_t * | vd | ) |
Definition at line 384 of file vdev_cache.c.
int vdev_cache_read | ( | zio_t * | zio | ) |
Read data from the cache.
Definition at line 271 of file vdev_cache.c.
void vdev_cache_write | ( | zio_t * | zio | ) |
Update cache contents upon write completion.
Definition at line 348 of file vdev_cache.c.
Clear the error counts associated with this vdev.
Unlike vdev_online() and vdev_offline(), we assume the spa config is locked. We also clear all children. If 'vd' is NULL, then the user wants to clear all vdevs.
void vdev_config_dirty | ( | vdev_t * | vd | ) |
nvlist_t* vdev_config_generate | ( | spa_t * | spa, |
vdev_t * | vd, | ||
boolean_t | getstats, | ||
vdev_config_flag_t | flags | ||
) |
Generate the nvlist representing this vdev's config.
Definition at line 212 of file vdev_label.c.
int vdev_config_sync | ( | vdev_t ** | svd, |
int | svdcount, | ||
uint64_t | txg, | ||
boolean_t | tryhard | ||
) |
Sync the uberblock and any changes to the vdev configuration.
The order of operations is carefully crafted to ensure that if the system panics or loses power at any time, the state on disk is still transactionally consistent. The in-line comments below describe the failure semantics at each stage.
Moreover, vdev_config_sync() is designed to be idempotent: if it fails at any time, you can just call it again, and it will resume its work.
Definition at line 1205 of file vdev_label.c.
int vdev_create | ( | vdev_t * | , |
uint64_t | txg, | ||
boolean_t | isreplace | ||
) |
int vdev_degrade | ( | spa_t * | spa, |
uint64_t | guid, | ||
vdev_aux_t | aux | ||
) |
boolean_t vdev_dtl_contains | ( | vdev_t * | vd, |
vdev_dtl_type_t | d, | ||
uint64_t | txg, | ||
uint64_t | size | ||
) |
void vdev_dtl_dirty | ( | vdev_t * | vd, |
vdev_dtl_type_t | d, | ||
uint64_t | txg, | ||
uint64_t | size | ||
) |
boolean_t vdev_dtl_empty | ( | vdev_t * | vd, |
vdev_dtl_type_t | d | ||
) |
void vdev_dtl_reassess | ( | vdev_t * | vd, |
uint64_t | txg, | ||
uint64_t | scrub_txg, | ||
int | scrub_done | ||
) |
boolean_t vdev_dtl_required | ( | vdev_t * | vd | ) |
void vdev_expand | ( | vdev_t * | vd, |
uint64_t | txg | ||
) |
int vdev_fault | ( | spa_t * | spa, |
uint64_t | guid, | ||
vdev_aux_t | aux | ||
) |
boolean_t vdev_is_bootable | ( | vdev_t * | vd | ) |
Check the vdev configuration to ensure that it's capable of supporting a root pool.
On Solaris, we do not support RAID-Z or partial configuration. In addition, only a single top-level vdev is allowed and none of the leaves can be wholedisks.
For FreeBSD, we can boot from any configuration. There is a limitation that the boot filesystem must be either uncompressed or compresses with lzjb compression but I'm not sure how to enforce that here.
int vdev_label_init | ( | vdev_t * | vd, |
uint64_t | crtxg, | ||
vdev_labeltype_t | reason | ||
) |
Initialize a vdev label.
We check to make sure each leaf device is not in use, and writable. We put down an initial label which we will later overwrite with a complete label. Note that it's important to do this sequentially, not in parallel, so that we catch cases of multiple use of the same leaf vdev in the vdev we're creating -- e.g. mirroring a disk with itself.
Definition at line 633 of file vdev_label.c.
int vdev_label_number | ( | uint64_t | psise, |
uint64_t | offset | ||
) |
Returns back the vdev label associated with the passed in offset.
Definition at line 166 of file vdev_label.c.
uint64_t vdev_label_offset | ( | uint64_t | psize, |
int | l, | ||
uint64_t | offset | ||
) |
Basic routines to read and write from a vdev label.
Used throughout the rest of this file.
Definition at line 153 of file vdev_label.c.
nvlist_t* vdev_label_read_config | ( | vdev_t * | vd, |
uint64_t | txg | ||
) |
Returns the configuration from the label of the given vdev.
For vdevs which don't have a txg value stored on their label (i.e. spares/cache) or have not been completely initialized (txg = 0) just return the configuration from the first valid label we find. Otherwise, find the most up-to-date label that does not exceed the specified 'txg' value.
Definition at line 442 of file vdev_label.c.
int vdev_offline | ( | spa_t * | spa, |
uint64_t | guid, | ||
uint64_t | flags | ||
) |
int vdev_online | ( | spa_t * | spa, |
uint64_t | guid, | ||
uint64_t | flags, | ||
vdev_state_t * | newstate | ||
) |
Online the given vdev.
If 'ZFS_ONLINE_UNSPARE' is set, it implies two things. First, any attached spare device should be detached when the device finishes resilvering. Second, the online should be treated like a 'test' online case, so no FMA events are generated if the device fails to open.
int vdev_open | ( | vdev_t * | ) |
void vdev_propagate_state | ( | vdev_t * | vd | ) |
uint64_t vdev_psize_to_asize | ( | vdev_t * | vd, |
uint64_t | psize | ||
) |
void vdev_queue_fini | ( | vdev_t * | vd | ) |
Definition at line 158 of file vdev_queue.c.
void vdev_queue_init | ( | vdev_t * | vd | ) |
Definition at line 138 of file vdev_queue.c.
Definition at line 375 of file vdev_queue.c.
void vdev_queue_io_done | ( | zio_t * | zio | ) |
Definition at line 415 of file vdev_queue.c.
void vdev_reopen | ( | vdev_t * | vd | ) |
Reopen all interior vdevs and any unopened leaves.
We don't actually reopen leaf vdevs which had previously been opened as they might deadlock on the spa_config_lock. Instead we only obtain the leaf's physical size. If the leaf has never been opened then open it, as usual.
boolean_t vdev_resilver_needed | ( | vdev_t * | vd, |
uint64_t * | minp, | ||
uint64_t * | maxp | ||
) |
void vdev_set_state | ( | vdev_t * | vd, |
boolean_t | isopen, | ||
vdev_state_t | state, | ||
vdev_aux_t | aux | ||
) |
Set a vdev's state.
If this is during an open, we don't update the parent state, because we're in the process of opening children depth-first. Otherwise, we propagate the change to the parent.
If this routine places a device in a faulted state, an appropriate ereport is generated.
void vdev_space_update | ( | vdev_t * | vd, |
int64_t | alloc_delta, | ||
int64_t | defer_delta, | ||
int64_t | space_delta | ||
) |
void vdev_state_dirty | ( | vdev_t * | vd | ) |
Mark a top-level vdev's state as dirty, so that the next pass of spa_sync() can convert this into vdev_config_dirty().
We distinguish the state changes from larger config changes because they require much less locking, and are often needed for administrative actions.
void vdev_top_config_generate | ( | spa_t * | spa, |
nvlist_t * | config | ||
) |
Generate a view of the top-level vdevs.
If we currently have holes in the namespace, then generate an array which contains a list of holey vdevs. Additionally, add the number of top-level children that currently exist.
Definition at line 407 of file vdev_label.c.
void vdev_uberblock_load | ( | vdev_t * | rvd, |
uberblock_t * | ub, | ||
nvlist_t ** | config | ||
) |
Reads the 'best' uberblock from disk along with its associated configuration.
First, we read the uberblock array of each label of each vdev, keeping track of the uberblock with the highest txg in each array. Then, we read the configuration from the same vdev as the best uberblock.
Definition at line 960 of file vdev_label.c.
int vdev_validate | ( | vdev_t * | vd, |
boolean_t | strict | ||
) |
Validates vdev label contents.
Called once the vdevs are all opened, this routine validates the label contents. This needs to be done before vdev_load() so that we don't inadvertently do repair I/Os to the wrong device.
If 'strict' is false ignore the spa guid check. This is necessary because if the machine crashed during a re-guid the new guid might have been written to all of the vdev labels, but not the cached config. The strict check will be performed when the pool is opened again using the mos config.
This function will only return failure if one of the vdevs indicates that it has since been destroyed or exported. This is only possible if /etc/zfs/zpool.cache was readonly at the time. Otherwise, the vdev state will be updated but the function will return 0.
int vdev_validate_aux | ( | vdev_t * | vd | ) |
The special vdev case is used for hot spares and l2cache devices.
Its sole purpose it to set the vdev state for the associated vdev. To do this, we make sure that we can open the underlying device, then try to read the label, and make sure that the label is sane and that it hasn't been repurposed to another pool.
boolean_t zfs_notrim |