mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-27 03:19:35 +03:00
df30f56639
Some disks with internal sectors larger than 512 bytes (e.g., 4k) can suffer from bad write performance when ashift is not configured correctly. This is caused by the disk not reporting its actual sector size, but a sector size of 512 bytes. The drive may behave this way for compatibility reasons. For example, the WDC WD20EARS disks are known to exhibit this behavior. When creating a zpool, ZFS takes that wrong sector size and sets the "ashift" property accordingly (to 9: 1<<9=512), whereas it should be set to 12 for 4k sectors (1<<12=4096). This patch allows an adminstrator to manual specify the known correct ashift size at 'zpool create' time. This can significantly improve performance in certain cases. However, it will have an impact on your total pool capacity. See the updated ashift property description in the zpool.8 man page for additional details. Valid values for the ashift property range from 9 to 17 (512B-128KB). Additionally, you may set the ashift to 0 if you wish to auto-detect the sector size based on what the disk reports, this is the default behavior. The most common ashift values are 9 and 12. Example: zpool create -o ashift=12 tank raidz2 sda sdb sdc sdd Closes #280 Original-patch-by: Richard Laager <rlaager@wiktel.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
223 lines
6.4 KiB
C
223 lines
6.4 KiB
C
/*
|
|
* CDDL HEADER START
|
|
*
|
|
* The contents of this file are subject to the terms of the
|
|
* Common Development and Distribution License (the "License").
|
|
* You may not use this file except in compliance with the License.
|
|
*
|
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
|
* or http://www.opensolaris.org/os/licensing.
|
|
* See the License for the specific language governing permissions
|
|
* and limitations under the License.
|
|
*
|
|
* When distributing Covered Code, include this CDDL HEADER in each
|
|
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
|
* If applicable, add the following below this CDDL HEADER, with the
|
|
* fields enclosed by brackets "[]" replaced with your own identifying
|
|
* information: Portions Copyright [yyyy] [name of copyright owner]
|
|
*
|
|
* CDDL HEADER END
|
|
*/
|
|
/*
|
|
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
|
|
*/
|
|
|
|
#include <sys/zio.h>
|
|
#include <sys/spa.h>
|
|
#include <sys/zfs_acl.h>
|
|
#include <sys/zfs_ioctl.h>
|
|
#include <sys/fs/zfs.h>
|
|
|
|
#include "zfs_prop.h"
|
|
|
|
#if defined(_KERNEL)
|
|
#include <sys/systm.h>
|
|
#else
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#endif
|
|
|
|
static zprop_desc_t zpool_prop_table[ZPOOL_NUM_PROPS];
|
|
|
|
zprop_desc_t *
|
|
zpool_prop_get_table(void)
|
|
{
|
|
return (zpool_prop_table);
|
|
}
|
|
|
|
void
|
|
zpool_prop_init(void)
|
|
{
|
|
static zprop_index_t boolean_table[] = {
|
|
{ "off", 0},
|
|
{ "on", 1},
|
|
{ NULL }
|
|
};
|
|
|
|
static zprop_index_t failuremode_table[] = {
|
|
{ "wait", ZIO_FAILURE_MODE_WAIT },
|
|
{ "continue", ZIO_FAILURE_MODE_CONTINUE },
|
|
{ "panic", ZIO_FAILURE_MODE_PANIC },
|
|
{ NULL }
|
|
};
|
|
|
|
/* string properties */
|
|
zprop_register_string(ZPOOL_PROP_ALTROOT, "altroot", NULL, PROP_DEFAULT,
|
|
ZFS_TYPE_POOL, "<path>", "ALTROOT");
|
|
zprop_register_string(ZPOOL_PROP_BOOTFS, "bootfs", NULL, PROP_DEFAULT,
|
|
ZFS_TYPE_POOL, "<filesystem>", "BOOTFS");
|
|
zprop_register_string(ZPOOL_PROP_CACHEFILE, "cachefile", NULL,
|
|
PROP_DEFAULT, ZFS_TYPE_POOL, "<file> | none", "CACHEFILE");
|
|
|
|
/* readonly number properties */
|
|
zprop_register_number(ZPOOL_PROP_SIZE, "size", 0, PROP_READONLY,
|
|
ZFS_TYPE_POOL, "<size>", "SIZE");
|
|
zprop_register_number(ZPOOL_PROP_FREE, "free", 0, PROP_READONLY,
|
|
ZFS_TYPE_POOL, "<size>", "FREE");
|
|
zprop_register_number(ZPOOL_PROP_ALLOCATED, "allocated", 0,
|
|
PROP_READONLY, ZFS_TYPE_POOL, "<size>", "ALLOC");
|
|
zprop_register_number(ZPOOL_PROP_CAPACITY, "capacity", 0, PROP_READONLY,
|
|
ZFS_TYPE_POOL, "<size>", "CAP");
|
|
zprop_register_number(ZPOOL_PROP_GUID, "guid", 0, PROP_READONLY,
|
|
ZFS_TYPE_POOL, "<guid>", "GUID");
|
|
zprop_register_number(ZPOOL_PROP_HEALTH, "health", 0, PROP_READONLY,
|
|
ZFS_TYPE_POOL, "<state>", "HEALTH");
|
|
zprop_register_number(ZPOOL_PROP_DEDUPRATIO, "dedupratio", 0,
|
|
PROP_READONLY, ZFS_TYPE_POOL, "<1.00x or higher if deduped>",
|
|
"DEDUP");
|
|
|
|
/* readonly onetime number properties */
|
|
zprop_register_number(ZPOOL_PROP_ASHIFT, "ashift", 0, PROP_ONETIME,
|
|
ZFS_TYPE_POOL, "<ashift, 9-17, or 0=default>", "ASHIFT");
|
|
|
|
/* default number properties */
|
|
zprop_register_number(ZPOOL_PROP_VERSION, "version", SPA_VERSION,
|
|
PROP_DEFAULT, ZFS_TYPE_POOL, "<version>", "VERSION");
|
|
zprop_register_number(ZPOOL_PROP_DEDUPDITTO, "dedupditto", 0,
|
|
PROP_DEFAULT, ZFS_TYPE_POOL, "<threshold (min 100)>", "DEDUPDITTO");
|
|
|
|
/* default index (boolean) properties */
|
|
zprop_register_index(ZPOOL_PROP_DELEGATION, "delegation", 1,
|
|
PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "DELEGATION",
|
|
boolean_table);
|
|
zprop_register_index(ZPOOL_PROP_AUTOREPLACE, "autoreplace", 0,
|
|
PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "REPLACE", boolean_table);
|
|
zprop_register_index(ZPOOL_PROP_LISTSNAPS, "listsnapshots", 0,
|
|
PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "LISTSNAPS",
|
|
boolean_table);
|
|
zprop_register_index(ZPOOL_PROP_AUTOEXPAND, "autoexpand", 0,
|
|
PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "EXPAND", boolean_table);
|
|
zprop_register_index(ZPOOL_PROP_READONLY, "readonly", 0,
|
|
PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "RDONLY", boolean_table);
|
|
|
|
/* default index properties */
|
|
zprop_register_index(ZPOOL_PROP_FAILUREMODE, "failmode",
|
|
ZIO_FAILURE_MODE_WAIT, PROP_DEFAULT, ZFS_TYPE_POOL,
|
|
"wait | continue | panic", "FAILMODE", failuremode_table);
|
|
|
|
/* hidden properties */
|
|
zprop_register_hidden(ZPOOL_PROP_NAME, "name", PROP_TYPE_STRING,
|
|
PROP_READONLY, ZFS_TYPE_POOL, "NAME");
|
|
}
|
|
|
|
/*
|
|
* Given a property name and its type, returns the corresponding property ID.
|
|
*/
|
|
zpool_prop_t
|
|
zpool_name_to_prop(const char *propname)
|
|
{
|
|
return (zprop_name_to_prop(propname, ZFS_TYPE_POOL));
|
|
}
|
|
|
|
/*
|
|
* Given a pool property ID, returns the corresponding name.
|
|
* Assuming the pool propety ID is valid.
|
|
*/
|
|
const char *
|
|
zpool_prop_to_name(zpool_prop_t prop)
|
|
{
|
|
return (zpool_prop_table[prop].pd_name);
|
|
}
|
|
|
|
zprop_type_t
|
|
zpool_prop_get_type(zpool_prop_t prop)
|
|
{
|
|
return (zpool_prop_table[prop].pd_proptype);
|
|
}
|
|
|
|
boolean_t
|
|
zpool_prop_readonly(zpool_prop_t prop)
|
|
{
|
|
return (zpool_prop_table[prop].pd_attr == PROP_READONLY);
|
|
}
|
|
|
|
const char *
|
|
zpool_prop_default_string(zpool_prop_t prop)
|
|
{
|
|
return (zpool_prop_table[prop].pd_strdefault);
|
|
}
|
|
|
|
uint64_t
|
|
zpool_prop_default_numeric(zpool_prop_t prop)
|
|
{
|
|
return (zpool_prop_table[prop].pd_numdefault);
|
|
}
|
|
|
|
int
|
|
zpool_prop_string_to_index(zpool_prop_t prop, const char *string,
|
|
uint64_t *index)
|
|
{
|
|
return (zprop_string_to_index(prop, string, index, ZFS_TYPE_POOL));
|
|
}
|
|
|
|
int
|
|
zpool_prop_index_to_string(zpool_prop_t prop, uint64_t index,
|
|
const char **string)
|
|
{
|
|
return (zprop_index_to_string(prop, index, string, ZFS_TYPE_POOL));
|
|
}
|
|
|
|
uint64_t
|
|
zpool_prop_random_value(zpool_prop_t prop, uint64_t seed)
|
|
{
|
|
return (zprop_random_value(prop, seed, ZFS_TYPE_POOL));
|
|
}
|
|
|
|
#ifndef _KERNEL
|
|
|
|
const char *
|
|
zpool_prop_values(zpool_prop_t prop)
|
|
{
|
|
return (zpool_prop_table[prop].pd_values);
|
|
}
|
|
|
|
const char *
|
|
zpool_prop_column_name(zpool_prop_t prop)
|
|
{
|
|
return (zpool_prop_table[prop].pd_colname);
|
|
}
|
|
|
|
boolean_t
|
|
zpool_prop_align_right(zpool_prop_t prop)
|
|
{
|
|
return (zpool_prop_table[prop].pd_rightalign);
|
|
}
|
|
#endif
|
|
|
|
#if defined(_KERNEL) && defined(HAVE_SPL)
|
|
/* zpool property functions */
|
|
EXPORT_SYMBOL(zpool_prop_init);
|
|
EXPORT_SYMBOL(zpool_prop_get_type);
|
|
EXPORT_SYMBOL(zpool_prop_get_table);
|
|
|
|
/* Pool property functions shared between libzfs and kernel. */
|
|
EXPORT_SYMBOL(zpool_name_to_prop);
|
|
EXPORT_SYMBOL(zpool_prop_to_name);
|
|
EXPORT_SYMBOL(zpool_prop_default_string);
|
|
EXPORT_SYMBOL(zpool_prop_default_numeric);
|
|
EXPORT_SYMBOL(zpool_prop_readonly);
|
|
EXPORT_SYMBOL(zpool_prop_index_to_string);
|
|
EXPORT_SYMBOL(zpool_prop_string_to_index);
|
|
#endif
|