Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "ashift" pool property to zpool create (follow-up of pull-request #195 and #277) #280

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cmd/zpool/zpool_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ zpool_do_add(int argc, char **argv)
}

/* pass off to get_vdev_spec for processing */
nvroot = make_root_vdev(zhp, force, !force, B_FALSE, dryrun,
nvroot = make_root_vdev(zhp, NULL, force, !force, B_FALSE, dryrun,
argc, argv);
if (nvroot == NULL) {
zpool_close(zhp);
Expand Down Expand Up @@ -688,7 +688,7 @@ zpool_do_create(int argc, char **argv)
}

/* pass off to get_vdev_spec for bulk processing */
nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun,
nvroot = make_root_vdev(NULL, props, force, !force, B_FALSE, dryrun,
argc - 1, argv + 1);
if (nvroot == NULL)
goto errout;
Expand Down Expand Up @@ -2683,7 +2683,7 @@ zpool_do_attach_or_replace(int argc, char **argv, int replacing)
return (1);
}

nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE,
nvroot = make_root_vdev(zhp, NULL, force, B_FALSE, replacing, B_FALSE,
argc, argv);
if (nvroot == NULL) {
zpool_close(zhp);
Expand Down
4 changes: 2 additions & 2 deletions cmd/zpool/zpool_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ uint_t num_logs(nvlist_t *nv);
* Virtual device functions
*/

nvlist_t *make_root_vdev(zpool_handle_t *zhp, int force, int check_rep,
boolean_t replacing, boolean_t dryrun, int argc, char **argv);
nvlist_t *make_root_vdev(zpool_handle_t *zhp, nvlist_t *props, int force,
int check_rep, boolean_t replacing, boolean_t dryrun, int argc, char **argv);
nvlist_t *split_mirror_vdev(zpool_handle_t *zhp, char *newname,
nvlist_t *props, splitflags_t flags, int argc, char **argv);

Expand Down
27 changes: 20 additions & 7 deletions cmd/zpool/zpool_vdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ is_shorthand_path(const char *arg, char *path,
* xxx Shorthand for /dev/disk/yyy/xxx
*/
static nvlist_t *
make_leaf_vdev(const char *arg, uint64_t is_log)
make_leaf_vdev(nvlist_t *props, const char *arg, uint64_t is_log)
{
char path[MAXPATHLEN];
struct stat64 statbuf;
Expand Down Expand Up @@ -499,6 +499,19 @@ make_leaf_vdev(const char *arg, uint64_t is_log)
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK,
(uint64_t)wholedisk) == 0);

if (props != NULL) {
uint64_t ashift = 0;

char *value = NULL;
if (nvlist_lookup_string(props,
zpool_prop_to_name(ZPOOL_PROP_ASHIFT), &value) == 0)
zfs_nicestrtonum(NULL, value, &ashift);

if (ashift > 0)
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_ASHIFT,
ashift) == 0);
}

return (vdev);
}

Expand Down Expand Up @@ -1195,7 +1208,7 @@ is_grouping(const char *type, int *mindev, int *maxdev)
* because the program is just going to exit anyway.
*/
nvlist_t *
construct_spec(int argc, char **argv)
construct_spec(nvlist_t *props, int argc, char **argv)
{
nvlist_t *nvroot, *nv, **top, **spares, **l2cache;
int t, toplevels, mindev, maxdev, nspares, nlogs, nl2cache;
Expand Down Expand Up @@ -1284,7 +1297,7 @@ construct_spec(int argc, char **argv)
children * sizeof (nvlist_t *));
if (child == NULL)
zpool_no_memory();
if ((nv = make_leaf_vdev(argv[c], B_FALSE))
if ((nv = make_leaf_vdev(props, argv[c], B_FALSE))
== NULL)
return (NULL);
child[children - 1] = nv;
Expand Down Expand Up @@ -1340,7 +1353,7 @@ construct_spec(int argc, char **argv)
* We have a device. Pass off to make_leaf_vdev() to
* construct the appropriate nvlist describing the vdev.
*/
if ((nv = make_leaf_vdev(argv[0], is_log)) == NULL)
if ((nv = make_leaf_vdev(props, argv[0], is_log)) == NULL)
return (NULL);
if (is_log)
nlogs++;
Expand Down Expand Up @@ -1406,7 +1419,7 @@ split_mirror_vdev(zpool_handle_t *zhp, char *newname, nvlist_t *props,
uint_t c, children;

if (argc > 0) {
if ((newroot = construct_spec(argc, argv)) == NULL) {
if ((newroot = construct_spec(props, argc, argv)) == NULL) {
(void) fprintf(stderr, gettext("Unable to build a "
"pool from the specified devices\n"));
return (NULL);
Expand Down Expand Up @@ -1456,7 +1469,7 @@ split_mirror_vdev(zpool_handle_t *zhp, char *newname, nvlist_t *props,
* added, even if they appear in use.
*/
nvlist_t *
make_root_vdev(zpool_handle_t *zhp, int force, int check_rep,
make_root_vdev(zpool_handle_t *zhp, nvlist_t *props, int force, int check_rep,
boolean_t replacing, boolean_t dryrun, int argc, char **argv)
{
nvlist_t *newroot;
Expand All @@ -1468,7 +1481,7 @@ make_root_vdev(zpool_handle_t *zhp, int force, int check_rep,
* that we have a valid specification, and that all devices can be
* opened.
*/
if ((newroot = construct_spec(argc, argv)) == NULL)
if ((newroot = construct_spec(props, argc, argv)) == NULL)
return (NULL);

if (zhp && ((poolconfig = zpool_get_config(zhp, NULL)) == NULL))
Expand Down
1 change: 1 addition & 0 deletions include/sys/fs/zfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ typedef enum {
ZPOOL_PROP_FREE,
ZPOOL_PROP_ALLOCATED,
ZPOOL_PROP_READONLY,
ZPOOL_PROP_ASHIFT,
ZPOOL_NUM_PROPS
} zpool_prop_t;

Expand Down
23 changes: 23 additions & 0 deletions lib/libzfs/libzfs_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len,
case ZPOOL_PROP_SIZE:
case ZPOOL_PROP_ALLOCATED:
case ZPOOL_PROP_FREE:
case ZPOOL_PROP_ASHIFT:
(void) zfs_nicenum(intval, buf, len);
break;

Expand Down Expand Up @@ -433,6 +434,28 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
}
break;

case ZPOOL_PROP_ASHIFT:
if (!flags.create) {
zfs_error_aux(
hdl,
dgettext(TEXT_DOMAIN,
"property '%s' can only be set at creation "
"time"), propname);
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
goto error;
}

if (intval != 0 && (intval < 9 || intval > 17)) {
zfs_error_aux(
hdl,
dgettext(TEXT_DOMAIN,
"property '%s' number %d is invalid."),
propname, intval);
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
goto error;
}
break;

case ZPOOL_PROP_BOOTFS:
if (flags.create || flags.import) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
Expand Down
17 changes: 17 additions & 0 deletions man/man8/zpool.8
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,23 @@ Amount of storage space used within the pool.
.sp
.LP
These space usage properties report actual physical space available to the storage pool. The physical space can be different from the total amount of space that any contained datasets can actually use. The amount of space used in a \fBraidz\fR configuration depends on the characteristics of the data being written. In addition, \fBZFS\fR reserves some space for internal accounting that the \fBzfs\fR(8) command takes into account, but the \fBzpool\fR command does not. For non-full pools of a reasonable size, these effects should be invisible. For small pools, or pools that are close to being completely full, these discrepancies may become more noticeable.

.sp
.LP
The following property can be set at creation time:
.sp
.ne 2
.mk
.na
\fB\fBashift\fR\fR
.ad
.sp .6
.RS 4n
Pool sector size exponent, to the power of 2 (internally referred to as "ashift"). I/O operations will be aligned to the specified size boundaries. Additionally, the minimum (disk) write size will be set to the specified size, so this represents a space vs. performance trade-off. The typical case for setting this property is when performance is important and the underlying disks use 4KiB sectors but report 512B sectors to the OS (for compatibility reasons); in that case, set \fBashift=12\fR (which is 1<<12 = 4096).
.LP
For optimal performance, the pool sector size should be greater than or equal to the sector size of the underlying disks. Since the property cannot be changed after pool creation, if in a given pool, you \fIever\fR want to use drives that \fIreport\fR 4KiB sectors, you must set \fBashift=12\fR at pool creation time.
.RE

.sp
.LP
The following property can be set at creation time and import time:
Expand Down
4 changes: 4 additions & 0 deletions module/zcommon/zpool_prop.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ zpool_prop_init(void)
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");
Expand Down