loader: rewrite zfs vdev initialization
In some cases the pool discovery will get stuck in infinite loop while setting up the vdev children. To fix, we split the vdev setup into two parts, first we create vdevs based on configuration we do get from pool label, then, we process pool config from MOS and update the pool config if needed. Testing done: confirm previously hung loader is not hung any more. MFC after: 1 week
This commit is contained in:
parent
506c867c6e
commit
c29918a860
File diff suppressed because it is too large
Load Diff
@ -760,6 +760,7 @@ typedef enum {
|
||||
#define ZPOOL_CONFIG_IS_LOG "is_log"
|
||||
#define ZPOOL_CONFIG_TIMESTAMP "timestamp" /* not stored on disk */
|
||||
#define ZPOOL_CONFIG_FEATURES_FOR_READ "features_for_read"
|
||||
#define ZPOOL_CONFIG_VDEV_CHILDREN "vdev_children"
|
||||
|
||||
/*
|
||||
* The persistent vdev state is stored as separate values rather than a single
|
||||
@ -1173,6 +1174,8 @@ typedef enum dmu_objset_type {
|
||||
DMU_OST_NUMTYPES
|
||||
} dmu_objset_type_t;
|
||||
|
||||
#define ZAP_MAXVALUELEN (1024 * 8)
|
||||
|
||||
/*
|
||||
* header for all bonus and spill buffers.
|
||||
* The header has a fixed portion with a variable number
|
||||
@ -1755,13 +1758,13 @@ typedef struct vdev {
|
||||
int v_ashift; /* offset to block shift */
|
||||
int v_nparity; /* # parity for raidz */
|
||||
struct vdev *v_top; /* parent vdev */
|
||||
int v_nchildren; /* # children */
|
||||
size_t v_nchildren; /* # children */
|
||||
vdev_state_t v_state; /* current state */
|
||||
vdev_phys_read_t *v_phys_read; /* read from raw leaf vdev */
|
||||
vdev_read_t *v_read; /* read from vdev */
|
||||
void *v_read_priv; /* private data for read function */
|
||||
boolean_t v_islog;
|
||||
struct spa *spa; /* link to spa */
|
||||
struct spa *v_spa; /* link to spa */
|
||||
/*
|
||||
* Values stored in the config for an indirect or removing vdev.
|
||||
*/
|
||||
@ -1780,11 +1783,10 @@ typedef struct spa {
|
||||
uint64_t spa_guid; /* pool guid */
|
||||
uint64_t spa_txg; /* most recent transaction */
|
||||
struct uberblock spa_uberblock; /* best uberblock so far */
|
||||
vdev_list_t spa_vdevs; /* list of all toplevel vdevs */
|
||||
vdev_t *spa_root_vdev; /* toplevel vdev container */
|
||||
objset_phys_t spa_mos; /* MOS for this pool */
|
||||
zio_cksum_salt_t spa_cksum_salt; /* secret salt for cksum */
|
||||
void *spa_cksum_tmpls[ZIO_CHECKSUM_FUNCTIONS];
|
||||
int spa_inited; /* initialized */
|
||||
boolean_t spa_with_log; /* this pool has log */
|
||||
} spa_t;
|
||||
|
||||
|
@ -1637,8 +1637,11 @@ vdev_raidz_read(vdev_t *vd, const blkptr_t *bp, void *data,
|
||||
* any errors.
|
||||
*/
|
||||
if (total_errors <= rm->rm_firstdatacol - parity_untried) {
|
||||
int rv;
|
||||
|
||||
if (data_errors == 0) {
|
||||
if (raidz_checksum_verify(vd->spa, bp, data, bytes) == 0) {
|
||||
rv = raidz_checksum_verify(vd->v_spa, bp, data, bytes);
|
||||
if (rv == 0) {
|
||||
/*
|
||||
* If we read parity information (unnecessarily
|
||||
* as it happens since no reconstruction was
|
||||
@ -1683,7 +1686,8 @@ vdev_raidz_read(vdev_t *vd, const blkptr_t *bp, void *data,
|
||||
|
||||
code = vdev_raidz_reconstruct(rm, tgts, n);
|
||||
|
||||
if (raidz_checksum_verify(vd->spa, bp, data, bytes) == 0) {
|
||||
rv = raidz_checksum_verify(vd->v_spa, bp, data, bytes);
|
||||
if (rv == 0) {
|
||||
/*
|
||||
* If we read more parity disks than were used
|
||||
* for reconstruction, confirm that the other
|
||||
@ -1757,7 +1761,7 @@ vdev_raidz_read(vdev_t *vd, const blkptr_t *bp, void *data,
|
||||
if (total_errors > rm->rm_firstdatacol) {
|
||||
error = EIO;
|
||||
} else if (total_errors < rm->rm_firstdatacol &&
|
||||
(code = vdev_raidz_combrec(vd->spa, rm, bp, data, offset, bytes,
|
||||
(code = vdev_raidz_combrec(vd->v_spa, rm, bp, data, offset, bytes,
|
||||
total_errors, data_errors)) != 0) {
|
||||
/*
|
||||
* If we didn't use all the available parity for the
|
||||
|
Loading…
Reference in New Issue
Block a user