Relax (ref)reservation constraints on ZVOLs
This change allow (ref)reservation to be set larger than the current ZVOL size: this is safe as we normally set refreservation > volsize at ZVOL creation time when we account for metadata. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: George Melikov <mail@gmelikov.ru> Reviewed by: Richard Elling <Richard.Elling@RichardElling.com> Reviewed by: Matthew Ahrens <mahrens@delphix.com> Signed-off-by: loli10K <ezomori.nozomu@gmail.com> Closes #2468 Closes #6610
This commit is contained in:
parent
d9549cba96
commit
ded8f06a3c
@ -1451,25 +1451,11 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
|
|||||||
* checks to enforce.
|
* checks to enforce.
|
||||||
*/
|
*/
|
||||||
if (type == ZFS_TYPE_VOLUME && zhp != NULL) {
|
if (type == ZFS_TYPE_VOLUME && zhp != NULL) {
|
||||||
uint64_t volsize = zfs_prop_get_int(zhp,
|
|
||||||
ZFS_PROP_VOLSIZE);
|
|
||||||
uint64_t blocksize = zfs_prop_get_int(zhp,
|
uint64_t blocksize = zfs_prop_get_int(zhp,
|
||||||
ZFS_PROP_VOLBLOCKSIZE);
|
ZFS_PROP_VOLBLOCKSIZE);
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
switch (prop) {
|
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 "
|
|
||||||
"volume size"), propname);
|
|
||||||
(void) zfs_error(hdl, EZFS_BADPROP,
|
|
||||||
errbuf);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZFS_PROP_VOLSIZE:
|
case ZFS_PROP_VOLSIZE:
|
||||||
if (intval % blocksize != 0) {
|
if (intval % blocksize != 0) {
|
||||||
zfs_nicebytes(blocksize, buf,
|
zfs_nicebytes(blocksize, buf,
|
||||||
|
@ -33,13 +33,12 @@
|
|||||||
|
|
||||||
#
|
#
|
||||||
# DESCRIPTION:
|
# DESCRIPTION:
|
||||||
# Volume refreservation is limited by volsize
|
# Volume (ref)reservation is not limited by volsize
|
||||||
#
|
#
|
||||||
# STRATEGY:
|
# STRATEGY:
|
||||||
# 1. Create volume on filesystem
|
# 1. Create volume on filesystem
|
||||||
# 2. Setting quota for parent filesystem
|
# 2. Setting quota for parent filesystem
|
||||||
# 3. Verify volume refreservation is only limited by volsize
|
# 3. Verify volume (ref)reservation is not limited by volsize
|
||||||
# 4. Verify volume refreservation can be changed when volsize changed
|
|
||||||
#
|
#
|
||||||
|
|
||||||
verify_runnable "global"
|
verify_runnable "global"
|
||||||
@ -51,21 +50,24 @@ function cleanup
|
|||||||
log_must zfs set mountpoint=$TESTDIR $TESTPOOL/$TESTFS
|
log_must zfs set mountpoint=$TESTDIR $TESTPOOL/$TESTFS
|
||||||
}
|
}
|
||||||
|
|
||||||
log_assert "Volume refreservation is limited by volsize"
|
log_assert "Volume (ref)reservation is not limited by volsize"
|
||||||
log_onexit cleanup
|
log_onexit cleanup
|
||||||
|
|
||||||
fs=$TESTPOOL/$TESTFS; vol=$fs/vol
|
fs=$TESTPOOL/$TESTFS
|
||||||
|
vol=$fs/vol
|
||||||
log_must zfs create -V 10M $vol
|
log_must zfs create -V 10M $vol
|
||||||
|
refreserv=`get_prop refreservation $vol`
|
||||||
|
fudge=1
|
||||||
|
|
||||||
# Verify the parent filesystem does not affect volume
|
# Verify the parent filesystem does not affect volume
|
||||||
log_must zfs set quota=25M $fs
|
log_must zfs set quota=25M $fs
|
||||||
|
log_must zfs set reservation=10M $vol
|
||||||
log_must zfs set refreservation=10M $vol
|
log_must zfs set refreservation=10M $vol
|
||||||
avail=$(get_prop mountpoint $vol)
|
|
||||||
log_mustnot zfs set refreservation=$avail $vol
|
|
||||||
|
|
||||||
# Verify it is affected by volsize
|
# Verify it is not affected by volsize
|
||||||
log_must zfs set volsize=15M $vol
|
log_must zfs set reservation=$(($refreserv + $fudge)) $vol
|
||||||
log_must zfs set refreservation=15M $vol
|
log_must zfs set reservation=$(($refreserv - $fudge)) $vol
|
||||||
log_mustnot zfs set refreservation=16M $vol
|
log_must zfs set refreservation=$(($refreserv + $fudge)) $vol
|
||||||
|
log_must zfs set refreservation=$(($refreserv - $fudge)) $vol
|
||||||
|
|
||||||
log_pass "Volume refreservation is limited by volsize"
|
log_pass "Volume (ref)reservation is not limited by volsize"
|
||||||
|
@ -84,17 +84,9 @@ fi
|
|||||||
|
|
||||||
for obj in $TESTPOOL/$TESTFS $OBJ_LIST ; do
|
for obj in $TESTPOOL/$TESTFS $OBJ_LIST ; do
|
||||||
|
|
||||||
space_avail=`get_prop available $TESTPOOL`
|
space_avail=`get_prop available $obj`
|
||||||
resv_size_set=`expr $space_avail + $RESV_DELTA`
|
resv_size_set=`expr $space_avail + $RESV_DELTA`
|
||||||
|
|
||||||
#
|
|
||||||
# For regular (non-sparse) volumes the upper limit is determined
|
|
||||||
# not by the space available in the pool but rather by the size
|
|
||||||
# of the volume itself.
|
|
||||||
#
|
|
||||||
[[ $obj == $TESTPOOL/$TESTVOL ]] && \
|
|
||||||
((resv_size_set = vol_set_size + RESV_DELTA))
|
|
||||||
|
|
||||||
log_must zero_reservation $obj
|
log_must zero_reservation $obj
|
||||||
log_mustnot zfs set reservation=$resv_size_set $obj
|
log_mustnot zfs set reservation=$resv_size_set $obj
|
||||||
|
|
||||||
|
@ -79,30 +79,23 @@ fi
|
|||||||
|
|
||||||
for obj in $TESTPOOL/$TESTFS $OBJ_LIST ; do
|
for obj in $TESTPOOL/$TESTFS $OBJ_LIST ; do
|
||||||
|
|
||||||
space_avail=`get_prop available $TESTPOOL`
|
space_avail=`get_prop available $obj`
|
||||||
((quota_set_size = space_avail / 3))
|
((quota_set_size = space_avail / 3))
|
||||||
|
|
||||||
#
|
#
|
||||||
# A regular (non-sparse) volume's size is effectively
|
# Volumes do not support quota so only need to explicitly
|
||||||
# its quota so only need to explicitly set quotas for
|
# set quotas for filesystems.
|
||||||
# filesystems and datasets.
|
|
||||||
#
|
#
|
||||||
# A volumes size is effectively its quota. The maximum
|
# The maximum reservation value that can be set on a volume
|
||||||
# reservation value that can be set on a volume is
|
# is determined by the quota set on its parent filesystems or
|
||||||
# determined by the size of the volume or the amount of
|
# the amount of space in the pool, whichever is smaller.
|
||||||
# space in the pool, whichever is smaller.
|
|
||||||
#
|
#
|
||||||
if [[ $obj == $TESTPOOL/$TESTFS ]]; then
|
if [[ $obj == $TESTPOOL/$TESTFS ]]; then
|
||||||
log_must zfs set quota=$quota_set_size $obj
|
log_must zfs set quota=$quota_set_size $obj
|
||||||
((resv_set_size = quota_set_size + RESV_SIZE))
|
((resv_set_size = quota_set_size + RESV_SIZE))
|
||||||
|
elif [[ $obj == $TESTPOOL/$TESTVOL || $obj == $TESTPOOL/$TESTVOL2 ]]
|
||||||
elif [[ $obj == $TESTPOOL/$TESTVOL2 ]] ; then
|
then
|
||||||
|
resv_set_size=`expr $space_avail + $RESV_DELTA`
|
||||||
((resv_set_size = sparse_vol_set_size + RESV_SIZE))
|
|
||||||
|
|
||||||
elif [[ $obj == $TESTPOOL/$TESTVOL ]] ; then
|
|
||||||
|
|
||||||
((resv_set_size = vol_set_size + RESV_SIZE))
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
orig_quota=`get_prop quota $obj`
|
orig_quota=`get_prop quota $obj`
|
||||||
|
Loading…
Reference in New Issue
Block a user