mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-23 19:04:45 +03:00
Import vdev ashift optimization from FreeBSD
Many modern devices use physical allocation units that are much
larger than the minimum logical allocation size accessible by
external commands. Two prevalent examples of this are 512e disk
drives (512b logical sector, 4K physical sector) and flash devices
(512b logical sector, 4K or larger allocation block size, and 128k
or larger erase block size). Operations that modify less than the
physical sector size result in a costly read-modify-write or garbage
collection sequence on these devices.
Simply exporting the true physical sector of the device to ZFS would
yield optimal performance, but has two serious drawbacks:
1. Existing pools created with devices that have different logical
and physical block sizes, but were configured to use the logical
block size (e.g. because the OS version used for pool construction
reported the logical block size instead of the physical block
size) will suddenly find that the vdev allocation size has
increased. This can be easily tolerated for active members of
the array, but ZFS would prevent replacement of a vdev with
another identical device because it now appears that the smaller
allocation size required by the pool is not supported by the new
device.
2. The device's physical block size may be too large to be supported
by ZFS. The optimal allocation size for the vdev may be quite
large. For example, a RAID controller may export a vdev that
requires read-modify-write cycles unless accessed using 64k
aligned/sized requests. ZFS currently has an 8k minimum block
size limit.
Reporting both the logical and physical allocation sizes for vdevs
solves these problems. A device may be used so long as the logical
block size is compatible with the configuration. By comparing the
logical and physical block sizes, new configurations can be optimized
and administrators can be notified of any existing pools that are
sub-optimal.
Reviewed-by: Ryan Moeller <ryan@iXsystems.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Co-authored-by: Matthew Macy <mmacy@freebsd.org>
Signed-off-by: Matt Macy <mmacy@FreeBSD.org>
Closes #10619
This commit is contained in:
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/spa.h>
|
||||
#include <sys/spa_impl.h>
|
||||
#include <sys/vdev.h>
|
||||
#include <sys/vdev_impl.h>
|
||||
#include <sys/dmu.h>
|
||||
#include <sys/dsl_dir.h>
|
||||
#include <sys/dsl_dataset.h>
|
||||
@@ -518,56 +519,53 @@ SYSCTL_INT(_vfs_zfs, OID_AUTO, space_map_ibs, CTLFLAG_RWTUN,
|
||||
|
||||
|
||||
/* vdev.c */
|
||||
#ifdef notyet
|
||||
extern uint64_t zfs_max_auto_ashift;
|
||||
extern uint64_t zfs_min_auto_ashift;
|
||||
|
||||
static int
|
||||
sysctl_vfs_zfs_max_auto_ashift(SYSCTL_HANDLER_ARGS)
|
||||
int
|
||||
param_set_min_auto_ashift(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
uint64_t val;
|
||||
int err;
|
||||
|
||||
val = zfs_max_auto_ashift;
|
||||
val = zfs_vdev_min_auto_ashift;
|
||||
err = sysctl_handle_64(oidp, &val, 0, req);
|
||||
if (err != 0 || req->newptr == NULL)
|
||||
return (err);
|
||||
return (SET_ERROR(err));
|
||||
|
||||
if (val > ASHIFT_MAX || val < zfs_min_auto_ashift)
|
||||
return (EINVAL);
|
||||
if (val < ASHIFT_MIN || val > zfs_vdev_max_auto_ashift)
|
||||
return (SET_ERROR(EINVAL));
|
||||
|
||||
zfs_max_auto_ashift = val;
|
||||
zfs_vdev_min_auto_ashift = val;
|
||||
|
||||
return (0);
|
||||
}
|
||||
SYSCTL_PROC(_vfs_zfs, OID_AUTO, max_auto_ashift,
|
||||
CTLTYPE_U64 | CTLFLAG_MPSAFE | CTLFLAG_RW, 0, sizeof (uint64_t),
|
||||
sysctl_vfs_zfs_max_auto_ashift, "QU",
|
||||
"Max ashift used when optimising for logical -> physical sectors size on "
|
||||
"new top-level vdevs.");
|
||||
static int
|
||||
sysctl_vfs_zfs_min_auto_ashift(SYSCTL_HANDLER_ARGS)
|
||||
|
||||
int
|
||||
param_set_max_auto_ashift(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
uint64_t val;
|
||||
int err;
|
||||
|
||||
val = zfs_min_auto_ashift;
|
||||
val = zfs_vdev_max_auto_ashift;
|
||||
err = sysctl_handle_64(oidp, &val, 0, req);
|
||||
if (err != 0 || req->newptr == NULL)
|
||||
return (err);
|
||||
return (SET_ERROR(err));
|
||||
|
||||
if (val < ASHIFT_MIN || val > zfs_max_auto_ashift)
|
||||
return (EINVAL);
|
||||
if (val > ASHIFT_MAX || val < zfs_vdev_min_auto_ashift)
|
||||
return (SET_ERROR(EINVAL));
|
||||
|
||||
zfs_min_auto_ashift = val;
|
||||
zfs_vdev_max_auto_ashift = val;
|
||||
|
||||
return (0);
|
||||
}
|
||||
SYSCTL_PROC(_vfs_zfs, OID_AUTO, min_auto_ashift,
|
||||
CTLTYPE_U64 | CTLFLAG_MPSAFE | CTLFLAG_RW, 0, sizeof (uint64_t),
|
||||
sysctl_vfs_zfs_min_auto_ashift, "QU",
|
||||
"Min ashift used when creating new top-level vdevs.");
|
||||
#endif
|
||||
|
||||
SYSCTL_PROC(_vfs_zfs, OID_AUTO, min_auto_ashift, CTLTYPE_U64 | CTLFLAG_RWTUN,
|
||||
&zfs_vdev_min_auto_ashift, sizeof (zfs_vdev_min_auto_ashift),
|
||||
param_set_min_auto_ashift, "QU",
|
||||
"Min ashift used when creating new top-level vdev. (LEGACY)");
|
||||
SYSCTL_PROC(_vfs_zfs, OID_AUTO, max_auto_ashift, CTLTYPE_U64 | CTLFLAG_RWTUN,
|
||||
&zfs_vdev_max_auto_ashift, sizeof (zfs_vdev_max_auto_ashift),
|
||||
param_set_max_auto_ashift, "QU",
|
||||
"Max ashift used when optimizing for logical -> physical sector size on "
|
||||
"new top-level vdevs. (LEGACY)");
|
||||
|
||||
/*
|
||||
* Since the DTL space map of a vdev is not expected to have a lot of
|
||||
|
||||
@@ -83,7 +83,7 @@ vdev_file_open_mode(spa_mode_t spa_mode)
|
||||
|
||||
static int
|
||||
vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
|
||||
uint64_t *ashift)
|
||||
uint64_t *logical_ashift, uint64_t *physical_ashift)
|
||||
{
|
||||
vdev_file_t *vf;
|
||||
zfs_file_t *fp;
|
||||
@@ -167,7 +167,8 @@ skip_open:
|
||||
}
|
||||
|
||||
*max_psize = *psize = zfa.zfa_size;
|
||||
*ashift = SPA_MINBLOCKSHIFT;
|
||||
*logical_ashift = SPA_MINBLOCKSHIFT;
|
||||
*physical_ashift = SPA_MINBLOCKSHIFT;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -802,7 +802,7 @@ vdev_geom_open_by_path(vdev_t *vd, int check_guid)
|
||||
|
||||
static int
|
||||
vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
|
||||
uint64_t *logical_ashift)
|
||||
uint64_t *logical_ashift, uint64_t *physical_ashift)
|
||||
{
|
||||
struct g_provider *pp;
|
||||
struct g_consumer *cp;
|
||||
@@ -949,11 +949,12 @@ skip_open:
|
||||
* transfer size.
|
||||
*/
|
||||
*logical_ashift = highbit(MAX(pp->sectorsize, SPA_MINBLOCKSIZE)) - 1;
|
||||
#ifdef notyet
|
||||
if (pp->stripesize > (1 << *logical_ashift) && ISP2(pp->stripesize) &&
|
||||
pp->stripesize <= (1 << ASHIFT_MAX) && pp->stripeoffset == 0)
|
||||
*physical_ashift = 0;
|
||||
if (pp->stripesize && pp->stripesize > (1 << *logical_ashift) &&
|
||||
ISP2(pp->stripesize) && pp->stripesize <= (1 << ASHIFT_MAX) &&
|
||||
pp->stripeoffset == 0)
|
||||
*physical_ashift = highbit(pp->stripesize) - 1;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Clear the nowritecache settings, so that on a vdev_reopen()
|
||||
* we will try again.
|
||||
|
||||
@@ -159,7 +159,7 @@ vdev_disk_error(zio_t *zio)
|
||||
|
||||
static int
|
||||
vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
|
||||
uint64_t *ashift)
|
||||
uint64_t *logical_ashift, uint64_t *physical_ashift)
|
||||
{
|
||||
struct block_device *bdev;
|
||||
fmode_t mode = vdev_bdev_mode(spa_mode(v->vdev_spa));
|
||||
@@ -270,7 +270,10 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
|
||||
struct request_queue *q = bdev_get_queue(vd->vd_bdev);
|
||||
|
||||
/* Determine the physical block size */
|
||||
int block_size = bdev_physical_block_size(vd->vd_bdev);
|
||||
int physical_block_size = bdev_physical_block_size(vd->vd_bdev);
|
||||
|
||||
/* Determine the logical block size */
|
||||
int logical_block_size = bdev_logical_block_size(vd->vd_bdev);
|
||||
|
||||
/* Clear the nowritecache bit, causes vdev_reopen() to try again. */
|
||||
v->vdev_nowritecache = B_FALSE;
|
||||
@@ -291,7 +294,11 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
|
||||
*max_psize = bdev_max_capacity(vd->vd_bdev, v->vdev_wholedisk);
|
||||
|
||||
/* Based on the minimum sector size set the block size */
|
||||
*ashift = highbit64(MAX(block_size, SPA_MINBLOCKSIZE)) - 1;
|
||||
*physical_ashift = highbit64(MAX(physical_block_size,
|
||||
SPA_MINBLOCKSIZE)) - 1;
|
||||
|
||||
*logical_ashift = highbit64(MAX(logical_block_size,
|
||||
SPA_MINBLOCKSIZE)) - 1;
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -824,3 +831,43 @@ char *zfs_vdev_scheduler = "unused";
|
||||
module_param_call(zfs_vdev_scheduler, param_set_vdev_scheduler,
|
||||
param_get_charp, &zfs_vdev_scheduler, 0644);
|
||||
MODULE_PARM_DESC(zfs_vdev_scheduler, "I/O scheduler");
|
||||
|
||||
int
|
||||
param_set_min_auto_ashift(const char *buf, zfs_kernel_param_t *kp)
|
||||
{
|
||||
uint64_t val;
|
||||
int error;
|
||||
|
||||
error = kstrtoull(buf, 0, &val);
|
||||
if (error < 0)
|
||||
return (SET_ERROR(error));
|
||||
|
||||
if (val < ASHIFT_MIN || val > zfs_vdev_max_auto_ashift)
|
||||
return (SET_ERROR(-EINVAL));
|
||||
|
||||
error = param_set_ulong(buf, kp);
|
||||
if (error < 0)
|
||||
return (SET_ERROR(error));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
param_set_max_auto_ashift(const char *buf, zfs_kernel_param_t *kp)
|
||||
{
|
||||
uint64_t val;
|
||||
int error;
|
||||
|
||||
error = kstrtoull(buf, 0, &val);
|
||||
if (error < 0)
|
||||
return (SET_ERROR(error));
|
||||
|
||||
if (val > ASHIFT_MAX || val < zfs_vdev_min_auto_ashift)
|
||||
return (SET_ERROR(-EINVAL));
|
||||
|
||||
error = param_set_ulong(buf, kp);
|
||||
if (error < 0)
|
||||
return (SET_ERROR(error));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ vdev_file_open_mode(spa_mode_t spa_mode)
|
||||
|
||||
static int
|
||||
vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
|
||||
uint64_t *ashift)
|
||||
uint64_t *logical_ashift, uint64_t *physical_ashift)
|
||||
{
|
||||
vdev_file_t *vf;
|
||||
zfs_file_t *fp;
|
||||
@@ -159,7 +159,8 @@ skip_open:
|
||||
}
|
||||
|
||||
*max_psize = *psize = zfa.zfa_size;
|
||||
*ashift = SPA_MINBLOCKSHIFT;
|
||||
*logical_ashift = SPA_MINBLOCKSHIFT;
|
||||
*physical_ashift = SPA_MINBLOCKSHIFT;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -9283,6 +9283,8 @@ l2arc_add_vdev(spa_t *spa, vdev_t *vd)
|
||||
|
||||
ASSERT(!l2arc_vdev_present(vd));
|
||||
|
||||
vdev_ashift_optimize(vd);
|
||||
|
||||
/*
|
||||
* Create a new l2arc device entry.
|
||||
*/
|
||||
|
||||
@@ -5747,6 +5747,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
|
||||
for (int c = 0; error == 0 && c < rvd->vdev_children; c++) {
|
||||
vdev_t *vd = rvd->vdev_child[c];
|
||||
|
||||
vdev_ashift_optimize(vd);
|
||||
vdev_metaslab_set_size(vd);
|
||||
vdev_expand(vd, txg);
|
||||
}
|
||||
|
||||
@@ -576,8 +576,10 @@ spa_config_update(spa_t *spa, int what)
|
||||
(tvd->vdev_islog && tvd->vdev_removing))
|
||||
continue;
|
||||
|
||||
if (tvd->vdev_ms_array == 0)
|
||||
if (tvd->vdev_ms_array == 0) {
|
||||
vdev_ashift_optimize(tvd);
|
||||
vdev_metaslab_set_size(tvd);
|
||||
}
|
||||
vdev_expand(tvd, txg);
|
||||
}
|
||||
}
|
||||
|
||||
+71
-12
@@ -110,6 +110,9 @@ int zfs_vdev_standard_sm_blksz = (1 << 17);
|
||||
*/
|
||||
int zfs_nocacheflush = 0;
|
||||
|
||||
uint64_t zfs_vdev_max_auto_ashift = ASHIFT_MAX;
|
||||
uint64_t zfs_vdev_min_auto_ashift = ASHIFT_MIN;
|
||||
|
||||
/*PRINTFLIKE2*/
|
||||
void
|
||||
vdev_dbgmsg(vdev_t *vd, const char *fmt, ...)
|
||||
@@ -1176,6 +1179,8 @@ vdev_add_parent(vdev_t *cvd, vdev_ops_t *ops)
|
||||
mvd->vdev_max_asize = cvd->vdev_max_asize;
|
||||
mvd->vdev_psize = cvd->vdev_psize;
|
||||
mvd->vdev_ashift = cvd->vdev_ashift;
|
||||
mvd->vdev_logical_ashift = cvd->vdev_logical_ashift;
|
||||
mvd->vdev_physical_ashift = cvd->vdev_physical_ashift;
|
||||
mvd->vdev_state = cvd->vdev_state;
|
||||
mvd->vdev_crtxg = cvd->vdev_crtxg;
|
||||
|
||||
@@ -1207,7 +1212,8 @@ vdev_remove_parent(vdev_t *cvd)
|
||||
mvd->vdev_ops == &vdev_replacing_ops ||
|
||||
mvd->vdev_ops == &vdev_spare_ops);
|
||||
cvd->vdev_ashift = mvd->vdev_ashift;
|
||||
|
||||
cvd->vdev_logical_ashift = mvd->vdev_logical_ashift;
|
||||
cvd->vdev_physical_ashift = mvd->vdev_physical_ashift;
|
||||
vdev_remove_child(mvd, cvd);
|
||||
vdev_remove_child(pvd, mvd);
|
||||
|
||||
@@ -1677,7 +1683,8 @@ vdev_open(vdev_t *vd)
|
||||
uint64_t osize = 0;
|
||||
uint64_t max_osize = 0;
|
||||
uint64_t asize, max_asize, psize;
|
||||
uint64_t ashift = 0;
|
||||
uint64_t logical_ashift = 0;
|
||||
uint64_t physical_ashift = 0;
|
||||
|
||||
ASSERT(vd->vdev_open_thread == curthread ||
|
||||
spa_config_held(spa, SCL_STATE_ALL, RW_WRITER) == SCL_STATE_ALL);
|
||||
@@ -1707,8 +1714,8 @@ vdev_open(vdev_t *vd)
|
||||
return (SET_ERROR(ENXIO));
|
||||
}
|
||||
|
||||
error = vd->vdev_ops->vdev_op_open(vd, &osize, &max_osize, &ashift);
|
||||
|
||||
error = vd->vdev_ops->vdev_op_open(vd, &osize, &max_osize,
|
||||
&logical_ashift, &physical_ashift);
|
||||
/*
|
||||
* Physical volume size should never be larger than its max size, unless
|
||||
* the disk has shrunk while we were reading it or the device is buggy
|
||||
@@ -1823,6 +1830,17 @@ vdev_open(vdev_t *vd)
|
||||
return (SET_ERROR(EINVAL));
|
||||
}
|
||||
|
||||
vd->vdev_physical_ashift =
|
||||
MAX(physical_ashift, vd->vdev_physical_ashift);
|
||||
vd->vdev_logical_ashift = MAX(logical_ashift, vd->vdev_logical_ashift);
|
||||
vd->vdev_ashift = MAX(vd->vdev_logical_ashift, vd->vdev_ashift);
|
||||
|
||||
if (vd->vdev_logical_ashift > ASHIFT_MAX) {
|
||||
vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
|
||||
VDEV_AUX_ASHIFT_TOO_BIG);
|
||||
return (SET_ERROR(EDOM));
|
||||
}
|
||||
|
||||
if (vd->vdev_asize == 0) {
|
||||
/*
|
||||
* This is the first-ever open, so use the computed values.
|
||||
@@ -1830,9 +1848,6 @@ vdev_open(vdev_t *vd)
|
||||
*/
|
||||
vd->vdev_asize = asize;
|
||||
vd->vdev_max_asize = max_asize;
|
||||
if (vd->vdev_ashift == 0) {
|
||||
vd->vdev_ashift = ashift; /* use detected value */
|
||||
}
|
||||
if (vd->vdev_ashift != 0 && (vd->vdev_ashift < ASHIFT_MIN ||
|
||||
vd->vdev_ashift > ASHIFT_MAX)) {
|
||||
vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
|
||||
@@ -1841,16 +1856,17 @@ vdev_open(vdev_t *vd)
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Detect if the alignment requirement has increased.
|
||||
* We don't want to make the pool unavailable, just
|
||||
* post an event instead.
|
||||
* Make sure the alignment required hasn't increased.
|
||||
*/
|
||||
if (ashift > vd->vdev_top->vdev_ashift &&
|
||||
if (vd->vdev_ashift > vd->vdev_top->vdev_ashift &&
|
||||
vd->vdev_ops->vdev_op_leaf) {
|
||||
zfs_ereport_post(FM_EREPORT_ZFS_DEVICE_BAD_ASHIFT,
|
||||
spa, vd, NULL, NULL, 0, 0);
|
||||
}
|
||||
vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
|
||||
VDEV_AUX_BAD_LABEL);
|
||||
return (SET_ERROR(EDOM));
|
||||
|
||||
}
|
||||
vd->vdev_max_asize = max_asize;
|
||||
}
|
||||
|
||||
@@ -2428,6 +2444,35 @@ vdev_metaslab_set_size(vdev_t *vd)
|
||||
ASSERT3U(vd->vdev_ms_shift, >=, SPA_MAXBLOCKSHIFT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Maximize performance by inflating the configured ashift for top level
|
||||
* vdevs to be as close to the physical ashift as possible while maintaining
|
||||
* administrator defined limits and ensuring it doesn't go below the
|
||||
* logical ashift.
|
||||
*/
|
||||
void
|
||||
vdev_ashift_optimize(vdev_t *vd)
|
||||
{
|
||||
if (vd == vd->vdev_top) {
|
||||
if (vd->vdev_ashift < vd->vdev_physical_ashift) {
|
||||
vd->vdev_ashift = MIN(
|
||||
MAX(zfs_vdev_max_auto_ashift, vd->vdev_ashift),
|
||||
MAX(zfs_vdev_min_auto_ashift,
|
||||
vd->vdev_physical_ashift));
|
||||
} else {
|
||||
/*
|
||||
* Unusual case where logical ashift > physical ashift
|
||||
* so we can't cap the calculated ashift based on max
|
||||
* ashift as that would cause failures.
|
||||
* We still check if we need to increase it to match
|
||||
* the min ashift.
|
||||
*/
|
||||
vd->vdev_ashift = MAX(zfs_vdev_min_auto_ashift,
|
||||
vd->vdev_ashift);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vdev_dirty(vdev_t *vd, int flags, void *arg, uint64_t txg)
|
||||
{
|
||||
@@ -4083,6 +4128,11 @@ vdev_get_stats_ex(vdev_t *vd, vdev_stat_t *vs, vdev_stat_ex_t *vsx)
|
||||
1ULL << tvd->vdev_ms_shift);
|
||||
}
|
||||
|
||||
vs->vs_configured_ashift = vd->vdev_top != NULL
|
||||
? vd->vdev_top->vdev_ashift : vd->vdev_ashift;
|
||||
vs->vs_logical_ashift = vd->vdev_logical_ashift;
|
||||
vs->vs_physical_ashift = vd->vdev_physical_ashift;
|
||||
|
||||
/*
|
||||
* Report fragmentation and rebuild progress for top-level,
|
||||
* non-auxiliary, concrete devices.
|
||||
@@ -5028,4 +5078,13 @@ ZFS_MODULE_PARAM(zfs_vdev, vdev_, validate_skip, INT, ZMOD_RW,
|
||||
|
||||
ZFS_MODULE_PARAM(zfs, zfs_, nocacheflush, INT, ZMOD_RW,
|
||||
"Disable cache flushes");
|
||||
|
||||
ZFS_MODULE_PARAM_CALL(zfs_vdev, zfs_vdev_, min_auto_ashift,
|
||||
param_set_min_auto_ashift, param_get_ulong, ZMOD_RW,
|
||||
"Minimum ashift used when creating new top-level vdevs");
|
||||
|
||||
ZFS_MODULE_PARAM_CALL(zfs_vdev, zfs_vdev_, max_auto_ashift,
|
||||
param_set_max_auto_ashift, param_get_ulong, ZMOD_RW,
|
||||
"Maximum ashift used when optimizing for logical -> physical sector "
|
||||
"size on new top-level vdevs");
|
||||
/* END CSTYLED */
|
||||
|
||||
@@ -950,11 +950,12 @@ vdev_indirect_close(vdev_t *vd)
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
vdev_indirect_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
|
||||
uint64_t *ashift)
|
||||
uint64_t *logical_ashift, uint64_t *physical_ashift)
|
||||
{
|
||||
*psize = *max_psize = vd->vdev_asize +
|
||||
VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE;
|
||||
*ashift = vd->vdev_ashift;
|
||||
*logical_ashift = vd->vdev_ashift;
|
||||
*physical_ashift = vd->vdev_physical_ashift;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@@ -366,7 +366,7 @@ vdev_mirror_map_init(zio_t *zio)
|
||||
|
||||
static int
|
||||
vdev_mirror_open(vdev_t *vd, uint64_t *asize, uint64_t *max_asize,
|
||||
uint64_t *ashift)
|
||||
uint64_t *logical_ashift, uint64_t *physical_ashift)
|
||||
{
|
||||
int numerrors = 0;
|
||||
int lasterror = 0;
|
||||
@@ -389,7 +389,9 @@ vdev_mirror_open(vdev_t *vd, uint64_t *asize, uint64_t *max_asize,
|
||||
|
||||
*asize = MIN(*asize - 1, cvd->vdev_asize - 1) + 1;
|
||||
*max_asize = MIN(*max_asize - 1, cvd->vdev_max_asize - 1) + 1;
|
||||
*ashift = MAX(*ashift, cvd->vdev_ashift);
|
||||
*logical_ashift = MAX(*logical_ashift, cvd->vdev_ashift);
|
||||
*physical_ashift = MAX(*physical_ashift,
|
||||
vd->vdev_physical_ashift);
|
||||
}
|
||||
|
||||
if (numerrors == vd->vdev_children) {
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
vdev_missing_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
|
||||
uint64_t *ashift)
|
||||
uint64_t *ashift, uint64_t *pshift)
|
||||
{
|
||||
/*
|
||||
* Really this should just fail. But then the root vdev will be in the
|
||||
@@ -56,6 +56,7 @@ vdev_missing_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
|
||||
*psize = 0;
|
||||
*max_psize = 0;
|
||||
*ashift = 0;
|
||||
*pshift = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1554,7 +1554,7 @@ vdev_raidz_reconstruct(raidz_map_t *rm, const int *t, int nt)
|
||||
|
||||
static int
|
||||
vdev_raidz_open(vdev_t *vd, uint64_t *asize, uint64_t *max_asize,
|
||||
uint64_t *ashift)
|
||||
uint64_t *logical_ashift, uint64_t *physical_ashift)
|
||||
{
|
||||
vdev_t *cvd;
|
||||
uint64_t nparity = vd->vdev_nparity;
|
||||
@@ -1583,7 +1583,9 @@ vdev_raidz_open(vdev_t *vd, uint64_t *asize, uint64_t *max_asize,
|
||||
|
||||
*asize = MIN(*asize - 1, cvd->vdev_asize - 1) + 1;
|
||||
*max_asize = MIN(*max_asize - 1, cvd->vdev_max_asize - 1) + 1;
|
||||
*ashift = MAX(*ashift, cvd->vdev_ashift);
|
||||
*logical_ashift = MAX(*logical_ashift, cvd->vdev_ashift);
|
||||
*physical_ashift = MAX(*physical_ashift,
|
||||
cvd->vdev_physical_ashift);
|
||||
}
|
||||
|
||||
*asize *= vd->vdev_children;
|
||||
|
||||
@@ -82,7 +82,7 @@ too_many_errors(vdev_t *vd, uint64_t numerrors)
|
||||
|
||||
static int
|
||||
vdev_root_open(vdev_t *vd, uint64_t *asize, uint64_t *max_asize,
|
||||
uint64_t *ashift)
|
||||
uint64_t *ashift, uint64_t *pshift)
|
||||
{
|
||||
spa_t *spa = vd->vdev_spa;
|
||||
int lasterror = 0;
|
||||
@@ -116,6 +116,7 @@ vdev_root_open(vdev_t *vd, uint64_t *asize, uint64_t *max_asize,
|
||||
*asize = 0;
|
||||
*max_asize = 0;
|
||||
*ashift = 0;
|
||||
*pshift = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user