FreeBSD ZFS
The Zettabyte File System
|
Virtual device management. More...
#include <sys/zfs_context.h>
#include <sys/fm/fs/zfs.h>
#include <sys/spa.h>
#include <sys/spa_impl.h>
#include <sys/dmu.h>
#include <sys/dmu_tx.h>
#include <sys/vdev_impl.h>
#include <sys/uberblock_impl.h>
#include <sys/metaslab.h>
#include <sys/metaslab_impl.h>
#include <sys/space_map.h>
#include <sys/zio.h>
#include <sys/zap.h>
#include <sys/fs/zfs.h>
#include <sys/arc.h>
#include <sys/zil.h>
#include <sys/dsl_scan.h>
#include <sys/trim_map.h>
Go to the source code of this file.
Data Structures | |
struct | vdev_probe_stats |
Typedefs | |
typedef struct vdev_probe_stats | vdev_probe_stats_t |
Functions | |
SYSCTL_DECL (_vfs_zfs) | |
SYSCTL_NODE (_vfs_zfs, OID_AUTO, vdev, CTLFLAG_RW, 0,"ZFS VDEV") | |
static vdev_ops_t * | vdev_getops (const char *type) |
Given a vdev type, return the appropriate ops vector. | |
uint64_t | vdev_default_asize (vdev_t *vd, uint64_t psize) |
Default asize function. | |
uint64_t | vdev_get_min_asize (vdev_t *vd) |
Get the minimum allocatable size. | |
void | vdev_set_min_asize (vdev_t *vd) |
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_add_child (vdev_t *pvd, vdev_t *cvd) |
void | vdev_remove_child (vdev_t *pvd, vdev_t *cvd) |
void | vdev_compact_children (vdev_t *pvd) |
Remove any holes in the child array. | |
vdev_t * | vdev_alloc_common (spa_t *spa, uint_t id, uint64_t guid, vdev_ops_t *ops) |
Allocate and minimally initialize a vdev_t. | |
int | vdev_alloc (spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent, uint_t id, int alloctype) |
Allocate a new vdev. | |
void | vdev_free (vdev_t *vd) |
static void | vdev_top_transfer (vdev_t *svd, vdev_t *tvd) |
Transfer top-level vdev state from svd to tvd. | |
static void | vdev_top_update (vdev_t *tvd, vdev_t *vd) |
vdev_t * | vdev_add_parent (vdev_t *cvd, vdev_ops_t *ops) |
Add a mirror/replacing vdev above an existing vdev. | |
void | vdev_remove_parent (vdev_t *cvd) |
Remove a 1-way mirror/replacing vdev from the tree. | |
int | vdev_metaslab_init (vdev_t *vd, uint64_t txg) |
void | vdev_metaslab_fini (vdev_t *vd) |
static void | vdev_probe_done (zio_t *zio) |
zio_t * | vdev_probe (vdev_t *vd, zio_t *zio) |
Determine whether this device is accessible. | |
static void | vdev_open_child (void *arg) |
boolean_t | vdev_uses_zvols (vdev_t *vd) |
void | vdev_open_children (vdev_t *vd) |
int | vdev_open (vdev_t *vd) |
Prepare a virtual device for access. | |
int | vdev_validate (vdev_t *vd, boolean_t strict) |
Validates vdev label contents. | |
void | vdev_close (vdev_t *vd) |
Close a virtual device. | |
void | vdev_hold (vdev_t *vd) |
void | vdev_rele (vdev_t *vd) |
void | vdev_reopen (vdev_t *vd) |
Reopen all interior vdevs and any unopened leaves. | |
int | vdev_create (vdev_t *vd, uint64_t txg, boolean_t isreplacing) |
void | vdev_metaslab_set_size (vdev_t *vd) |
void | vdev_dirty (vdev_t *vd, int flags, void *arg, uint64_t txg) |
void | vdev_dtl_dirty (vdev_t *vd, vdev_dtl_type_t t, uint64_t txg, uint64_t size) |
boolean_t | vdev_dtl_contains (vdev_t *vd, vdev_dtl_type_t t, uint64_t txg, uint64_t size) |
boolean_t | vdev_dtl_empty (vdev_t *vd, vdev_dtl_type_t t) |
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. | |
static int | vdev_dtl_load (vdev_t *vd) |
void | vdev_dtl_sync (vdev_t *vd, uint64_t txg) |
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_load (vdev_t *vd) |
int | vdev_validate_aux (vdev_t *vd) |
The special vdev case is used for hot spares and l2cache devices. | |
void | vdev_remove (vdev_t *vd, uint64_t txg) |
void | vdev_sync_done (vdev_t *vd, uint64_t txg) |
void | vdev_sync (vdev_t *vd, uint64_t txg) |
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 *newstate) |
Online the given vdev. | |
static int | vdev_offline_locked (spa_t *spa, uint64_t guid, uint64_t flags) |
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_get_stats (vdev_t *vd, vdev_stat_t *vs) |
void | vdev_clear_stats (vdev_t *vd) |
void | vdev_scan_stat_init (vdev_t *vd) |
void | vdev_stat_update (zio_t *zio, uint64_t psize) |
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. | |
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) |
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_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. | |
boolean_t | vdev_is_bootable (vdev_t *vd) |
Check the vdev configuration to ensure that it's capable of supporting a root pool. | |
void | vdev_load_log_state (vdev_t *nvd, vdev_t *ovd) |
Load the state from the original vdev tree (ovd) which we've retrieved from the MOS config object. | |
boolean_t | vdev_log_state_valid (vdev_t *vd) |
Determine if a log device has valid content. | |
void | vdev_expand (vdev_t *vd, uint64_t txg) |
Expand a vdev if possible. | |
void | vdev_split (vdev_t *vd) |
Split a vdev. | |
Variables | |
static vdev_ops_t * | vdev_ops_table [] |
Virtual device management.
Definition in file vdev.c.
typedef struct vdev_probe_stats vdev_probe_stats_t |
SYSCTL_DECL | ( | _vfs_zfs | ) |
SYSCTL_NODE | ( | _vfs_zfs | , |
OID_AUTO | , | ||
vdev | , | ||
CTLFLAG_RW | , | ||
0 | , | ||
"ZFS VDEV" | |||
) |
vdev_t* vdev_add_parent | ( | vdev_t * | cvd, |
vdev_ops_t * | ops | ||
) |
vdev_t* vdev_alloc_common | ( | spa_t * | spa, |
uint_t | id, | ||
uint64_t | guid, | ||
vdev_ops_t * | ops | ||
) |
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_compact_children | ( | vdev_t * | pvd | ) |
void vdev_config_dirty | ( | vdev_t * | vd | ) |
int vdev_create | ( | vdev_t * | vd, |
uint64_t | txg, | ||
boolean_t | isreplacing | ||
) |
uint64_t vdev_default_asize | ( | vdev_t * | vd, |
uint64_t | psize | ||
) |
int vdev_degrade | ( | spa_t * | spa, |
uint64_t | guid, | ||
vdev_aux_t | aux | ||
) |
void vdev_dirty | ( | vdev_t * | vd, |
int | flags, | ||
void * | arg, | ||
uint64_t | txg | ||
) |
boolean_t vdev_dtl_contains | ( | vdev_t * | vd, |
vdev_dtl_type_t | t, | ||
uint64_t | txg, | ||
uint64_t | size | ||
) |
void vdev_dtl_dirty | ( | vdev_t * | vd, |
vdev_dtl_type_t | t, | ||
uint64_t | txg, | ||
uint64_t | size | ||
) |
boolean_t vdev_dtl_empty | ( | vdev_t * | vd, |
vdev_dtl_type_t | t | ||
) |
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 | ||
) |
uint64_t vdev_get_min_asize | ( | vdev_t * | vd | ) |
static vdev_ops_t* vdev_getops | ( | const char * | type | ) | [static] |
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.
boolean_t vdev_log_state_valid | ( | vdev_t * | vd | ) |
int vdev_offline | ( | spa_t * | spa, |
uint64_t | guid, | ||
uint64_t | flags | ||
) |
static int vdev_offline_locked | ( | spa_t * | spa, |
uint64_t | guid, | ||
uint64_t | flags | ||
) | [static] |
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 * | vd | ) |
void vdev_propagate_state | ( | vdev_t * | vd | ) |
uint64_t vdev_psize_to_asize | ( | vdev_t * | vd, |
uint64_t | psize | ||
) |
void vdev_remove_parent | ( | vdev_t * | cvd | ) |
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.
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.
vdev_ops_t* vdev_ops_table[] [static] |
{ &vdev_root_ops, &vdev_raidz_ops, &vdev_mirror_ops, &vdev_replacing_ops, &vdev_spare_ops, &vdev_geom_ops, &vdev_file_ops, &vdev_missing_ops, &vdev_hole_ops, NULL }