Skip to content
This repository has been archived by the owner on Nov 7, 2019. It is now read-only.

Commit

Permalink
9286 want refreservation=auto
Browse files Browse the repository at this point in the history
Reviewed by: Allan Jude <allanjude@freebsd.org>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: John Kennedy <john.kennedy@delphix.com>
Reviewed by: Andy Stormont <astormont@racktopsystems.com>
Approved by: Richard Lowe <richlowe@richlowe.net>

Closes #592
  • Loading branch information
Mike Gerdts authored and Prakash Surya committed Apr 2, 2018
1 parent f6af1b7 commit 723d0c8
Show file tree
Hide file tree
Showing 11 changed files with 457 additions and 13 deletions.
80 changes: 78 additions & 2 deletions usr/src/lib/libzfs/common/libzfs_dataset.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2018, Joyent, Inc. All rights reserved.
* Copyright (c) 2011, 2016 by Delphix. All rights reserved.
* Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved.
* Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved.
Expand Down Expand Up @@ -1387,7 +1387,6 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,

switch (prop) {
case ZFS_PROP_RESERVATION:
case ZFS_PROP_REFRESERVATION:
if (intval > volsize) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"'%s' is greater than current "
Expand All @@ -1398,6 +1397,17 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
}
break;

case ZFS_PROP_REFRESERVATION:
if (intval > volsize && intval != UINT64_MAX) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"'%s' is greater than current "
"volume size"), propname);
(void) zfs_error(hdl, EZFS_BADPROP,
errbuf);
goto error;
}
break;

case ZFS_PROP_VOLSIZE:
if (intval % blocksize != 0) {
zfs_nicenum(blocksize, buf,
Expand Down Expand Up @@ -1499,6 +1509,61 @@ zfs_add_synthetic_resv(zfs_handle_t *zhp, nvlist_t *nvl)
return (1);
}

/*
* Helper for 'zfs {set|clone} refreservation=auto'. Must be called after
* zfs_valid_proplist(), as it is what sets the UINT64_MAX sentinal value.
* Return codes must match zfs_add_synthetic_resv().
*/
static int
zfs_fix_auto_resv(zfs_handle_t *zhp, nvlist_t *nvl)
{
uint64_t volsize;
uint64_t resvsize;
zfs_prop_t prop;
nvlist_t *props;

if (!ZFS_IS_VOLUME(zhp)) {
return (0);
}

if (zfs_which_resv_prop(zhp, &prop) != 0) {
return (-1);
}

if (prop != ZFS_PROP_REFRESERVATION) {
return (0);
}

if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(prop), &resvsize) != 0) {
/* No value being set, so it can't be "auto" */
return (0);
}
if (resvsize != UINT64_MAX) {
/* Being set to a value other than "auto" */
return (0);
}

props = fnvlist_alloc();

fnvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
zfs_prop_get_int(zhp, ZFS_PROP_VOLBLOCKSIZE));

if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(ZFS_PROP_VOLSIZE),
&volsize) != 0) {
volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
}

resvsize = zvol_volsize_to_reservation(volsize, props);
fnvlist_free(props);

(void) nvlist_remove_all(nvl, zfs_prop_to_name(prop));
if (nvlist_add_uint64(nvl, zfs_prop_to_name(prop), resvsize) != 0) {
(void) no_memory(zhp->zfs_hdl);
return (-1);
}
return (1);
}

void
zfs_setprop_error(libzfs_handle_t *hdl, zfs_prop_t prop, int err,
char *errbuf)
Expand Down Expand Up @@ -1664,6 +1729,12 @@ zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props)
goto error;
}
}

if (added_resv != 1 &&
(added_resv = zfs_fix_auto_resv(zhp, nvl)) == -1) {
goto error;
}

/*
* Check how many properties we're setting and allocate an array to
* store changelist pointers for postfix().
Expand Down Expand Up @@ -3666,6 +3737,7 @@ zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)

if (props) {
zfs_type_t type;

if (ZFS_IS_VOLUME(zhp)) {
type = ZFS_TYPE_VOLUME;
} else {
Expand All @@ -3674,6 +3746,10 @@ zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
if ((props = zfs_valid_proplist(hdl, type, props, zoned,
zhp, zhp->zpool_hdl, errbuf)) == NULL)
return (-1);
if (zfs_fix_auto_resv(zhp, props) == -1) {
nvlist_free(props);
return (-1);
}
}

ret = lzc_clone(target, zhp->zfs_name, props);
Expand Down
33 changes: 30 additions & 3 deletions usr/src/lib/libzfs/common/libzfs_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2018 Joyent, Inc.
* Copyright (c) 2011, 2017 by Delphix. All rights reserved.
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
* Copyright (c) 2017 Datto Inc.
Expand Down Expand Up @@ -1184,6 +1184,7 @@ zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
const char *propname;
char *value;
boolean_t isnone = B_FALSE;
boolean_t isauto = B_FALSE;

if (type == ZFS_TYPE_POOL) {
proptype = zpool_prop_get_type(prop);
Expand Down Expand Up @@ -1219,8 +1220,9 @@ zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
(void) nvpair_value_string(elem, &value);
if (strcmp(value, "none") == 0) {
isnone = B_TRUE;
} else if (zfs_nicestrtonum(hdl, value, ivalp)
!= 0) {
} else if (strcmp(value, "auto") == 0) {
isauto = B_TRUE;
} else if (zfs_nicestrtonum(hdl, value, ivalp) != 0) {
goto error;
}
} else if (datatype == DATA_TYPE_UINT64) {
Expand Down Expand Up @@ -1250,6 +1252,31 @@ zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
prop == ZFS_PROP_SNAPSHOT_LIMIT)) {
*ivalp = UINT64_MAX;
}

/*
* Special handling for setting 'refreservation' to 'auto'. Use
* UINT64_MAX to tell the caller to use zfs_fix_auto_resv().
* 'auto' is only allowed on volumes.
*/
if (isauto) {
switch (prop) {
case ZFS_PROP_REFRESERVATION:
if ((type & ZFS_TYPE_VOLUME) == 0) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"'%s=auto' only allowed on "
"volumes"), nvpair_name(elem));
goto error;
}
*ivalp = UINT64_MAX;
break;
default:
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"'auto' is invalid value for '%s'"),
nvpair_name(elem));
goto error;
}
}

break;

case PROP_TYPE_INDEX:
Expand Down
44 changes: 39 additions & 5 deletions usr/src/man/man1m/zfs.1m
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
.\" Copyright (c) 2014 by Adam Stevko. All rights reserved.
.\" Copyright (c) 2014 Integros [integros.com]
.\" Copyright 2017 Nexenta Systems, Inc.
.\" Copyright 2018 Joyent, Inc.
.\"
.Dd December 6, 2017
.Dt ZFS 1M
Expand Down Expand Up @@ -1345,7 +1346,7 @@ Limits the amount of space a dataset can consume.
This property enforces a hard limit on the amount of space used.
This hard limit does not include space used by descendents, including file
systems and snapshots.
.It Sy refreservation Ns = Ns Em size Ns | Ns Sy none
.It Sy refreservation Ns = Ns Em size Ns | Ns Sy none Ns | Ns Sy auto
The minimum amount of space guaranteed to a dataset, not including its
descendents.
When the amount of space used is below this value, the dataset is treated as if
Expand All @@ -1363,6 +1364,22 @@ this reservation to accommodate the current number of
.Qq referenced
bytes in the dataset.
.Pp
If
.Sy refreservation
is set to
.Sy auto ,
a volume is thick provisioned
.Po or
.Qq not sparse
.Pc .
.Sy refreservation Ns = Ns Sy auto
is only supported on volumes.
See
.Sy volsize
in the
.Sx Native Properties
section for more information about sparse volumes.
.Pp
This property can also be referred to by its shortened column name,
.Sy refreserv .
.It Sy reservation Ns = Ns Em size Ns | Ns Sy none
Expand Down Expand Up @@ -1577,22 +1594,39 @@ Extreme care should be used when adjusting the volume size.
Though not recommended, a
.Qq sparse volume
.Po also known as
.Qq thin provisioning
.Qq thin provisioned
.Pc
can be created by specifying the
.Fl s
option to the
.Nm zfs Cm create Fl V
command, or by changing the reservation after the volume has been created.
command, or by changing the value of the
.Sy refreservation
property
.Po or
.Sy reservation
property on pool version 8 or earlier
.Pc
after the volume has been created.
A
.Qq sparse volume
is a volume where the reservation is less then the volume size.
is a volume where the value of
.Sy refreservation
is less than the size of the volume plus the space required to store its
metadata.
Consequently, writes to a sparse volume can fail with
.Er ENOSPC
when the pool is low on space.
For a sparse volume, changes to
.Sy volsize
are not reflected in the reservation.
are not reflected in the
.Sy refreservation.
A volume that is not sparse is said to be
.Qq thick provisioned .
A sparse volume can become thick provisioned by setting
.Sy refreservation
to
.Sy auto .
.It Sy vscan Ns = Ns Sy on Ns | Ns Sy off
Controls whether regular files should be scanned for viruses when a file is
opened and closed.
Expand Down
9 changes: 9 additions & 0 deletions usr/src/pkg/manifests/system-test-zfstest.mf
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# Copyright (c) 2012, 2017 by Delphix. All rights reserved.
# Copyright 2015, 2016 Nexenta Systems, Inc. All rights reserved.
# Copyright 2016, OmniTI Computer Consulting, Inc. All rights reserved.
# Copyright 2018 Joyent, Inc.
#

set name=pkg.fmri value=pkg:/system/test/zfstest@$(PKGVERS)
Expand Down Expand Up @@ -2397,6 +2398,14 @@ file path=opt/zfs-tests/tests/functional/reservation/reservation_017_pos \
mode=0555
file path=opt/zfs-tests/tests/functional/reservation/reservation_018_pos \
mode=0555
file path=opt/zfs-tests/tests/functional/reservation/reservation_019_pos \
mode=0555
file path=opt/zfs-tests/tests/functional/reservation/reservation_020_pos \
mode=0555
file path=opt/zfs-tests/tests/functional/reservation/reservation_021_neg \
mode=0555
file path=opt/zfs-tests/tests/functional/reservation/reservation_022_pos \
mode=0555
file path=opt/zfs-tests/tests/functional/reservation/setup mode=0555
file path=opt/zfs-tests/tests/functional/rootpool/cleanup mode=0555
file path=opt/zfs-tests/tests/functional/rootpool/rootpool_002_neg mode=0555
Expand Down
5 changes: 4 additions & 1 deletion usr/src/test/zfs-tests/runfiles/delphix.run
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#
# Copyright (c) 2012, 2018 by Delphix. All rights reserved.
# Copyright 2016, OmniTI Computer Consulting, Inc. All rights reserved.
# Copyright 2018 Joyent, Inc.
#

[DEFAULT]
Expand Down Expand Up @@ -515,7 +516,9 @@ tests = ['reservation_001_pos', 'reservation_002_pos', 'reservation_003_pos',
'reservation_007_pos', 'reservation_008_pos', 'reservation_009_pos',
'reservation_010_pos', 'reservation_011_pos', 'reservation_012_pos',
'reservation_013_pos', 'reservation_014_pos', 'reservation_015_pos',
'reservation_016_pos', 'reservation_017_pos', 'reservation_018_pos']
'reservation_016_pos', 'reservation_017_pos', 'reservation_018_pos',
'reservation_019_pos', 'reservation_020_pos', 'reservation_021_neg',
'reservation_022_pos']

[/opt/zfs-tests/tests/functional/rootpool]
tests = ['rootpool_002_neg', 'rootpool_003_neg', 'rootpool_007_pos']
Expand Down
5 changes: 4 additions & 1 deletion usr/src/test/zfs-tests/runfiles/omnios.run
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#
# Copyright (c) 2013, 2017 by Delphix. All rights reserved.
# Copyright 2016, OmniTI Computer Consulting, Inc. All rights reserved.
# Copyright 2018 Joyent, Inc.
#

[DEFAULT]
Expand Down Expand Up @@ -484,7 +485,9 @@ tests = ['reservation_001_pos', 'reservation_002_pos', 'reservation_003_pos',
'reservation_007_pos', 'reservation_008_pos', 'reservation_009_pos',
'reservation_010_pos', 'reservation_011_pos', 'reservation_012_pos',
'reservation_013_pos', 'reservation_014_pos', 'reservation_015_pos',
'reservation_016_pos', 'reservation_017_pos', 'reservation_018_pos']
'reservation_016_pos', 'reservation_017_pos', 'reservation_018_pos',
'reservation_019_pos', 'reservation_020_pos', 'reservation_021_neg',
'reservation_022_pos']

[/opt/zfs-tests/tests/functional/rootpool]
tests = ['rootpool_002_neg', 'rootpool_003_neg', 'rootpool_007_pos']
Expand Down
5 changes: 4 additions & 1 deletion usr/src/test/zfs-tests/runfiles/openindiana.run
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#
# Copyright (c) 2012, 2017 by Delphix. All rights reserved.
# Copyright 2016, OmniTI Computer Consulting, Inc. All rights reserved.
# Copyright 2018 Joyent, Inc.
#

[DEFAULT]
Expand Down Expand Up @@ -484,7 +485,9 @@ tests = ['reservation_001_pos', 'reservation_002_pos', 'reservation_003_pos',
'reservation_007_pos', 'reservation_008_pos', 'reservation_009_pos',
'reservation_010_pos', 'reservation_011_pos', 'reservation_012_pos',
'reservation_013_pos', 'reservation_014_pos', 'reservation_015_pos',
'reservation_016_pos', 'reservation_017_pos', 'reservation_018_pos']
'reservation_016_pos', 'reservation_017_pos', 'reservation_018_pos',
'reservation_019_pos', 'reservation_020_pos', 'reservation_021_neg',
'reservation_022_pos']

[/opt/zfs-tests/tests/functional/rootpool]
tests = ['rootpool_002_neg', 'rootpool_003_neg', 'rootpool_007_pos']
Expand Down
Loading

0 comments on commit 723d0c8

Please sign in to comment.