Skip to content

Commit

Permalink
Relax (ref)reservation constraints on ZVOLs
Browse files Browse the repository at this point in the history
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.

Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
  • Loading branch information
loli10K committed Sep 10, 2017
1 parent 835db58 commit 502fed8
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 52 deletions.
14 changes: 0 additions & 14 deletions lib/libzfs/libzfs_dataset.c
Original file line number Diff line number Diff line change
Expand Up @@ -1451,25 +1451,11 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
* checks to enforce.
*/
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,
ZFS_PROP_VOLBLOCKSIZE);
char buf[64];

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:
if (intval % blocksize != 0) {
zfs_nicebytes(blocksize, buf,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ verify_runnable "both"

function cleanup
{
log_must zpool export $TESTPOOL
log_must_busy zpool export $TESTPOOL
log_must zpool import $TESTPOOL
snapexists $TESTSNAP && log_must zfs destroy $TESTSNAP
[[ -d $MNTPSNAP ]] && log_must rmdir $MNTPSNAP
Expand Down
26 changes: 14 additions & 12 deletions tests/zfs-tests/tests/functional/refreserv/refreserv_005_pos.ksh
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,12 @@

#
# DESCRIPTION:
# Volume refreservation is limited by volsize
# Volume (ref)reservation is not limited by volsize
#
# STRATEGY:
# 1. Create volume on filesystem
# 2. Setting quota for parent filesystem
# 3. Verify volume refreservation is only limited by volsize
# 4. Verify volume refreservation can be changed when volsize changed
# 3. Verify volume (ref)reservation is not limited by volsize
#

verify_runnable "global"
Expand All @@ -51,21 +50,24 @@ function cleanup
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

fs=$TESTPOOL/$TESTFS; vol=$fs/vol
fs=$TESTPOOL/$TESTFS
vol=$fs/vol
log_must zfs create -V 10M $vol
refreserv=`get_prop refreservation $vol`
fudge=1

# Verify the parent filesystem does not affect volume
log_must zfs set quota=25M $fs
log_must zfs set reservation=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
log_must zfs set volsize=15M $vol
log_must zfs set refreservation=15M $vol
log_mustnot zfs set refreservation=16M $vol
# Verify it is not affected by volsize
log_must zfs set reservation=$(($refreserv + $fudge)) $vol
log_must zfs set reservation=$(($refreserv - $fudge)) $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"
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,9 @@ fi

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`

#
# 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_mustnot zfs set reservation=$resv_size_set $obj

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,30 +79,23 @@ fi

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))

#
# A regular (non-sparse) volume's size is effectively
# its quota so only need to explicitly set quotas for
# filesystems and datasets.
# Volumes do not support quota so only need to explicitly
# set quotas for filesystems.
#
# A volumes size is effectively its quota. The maximum
# reservation value that can be set on a volume is
# determined by the size of the volume or the amount of
# space in the pool, whichever is smaller.
# The maximum reservation value that can be set on a volume
# is determined by the quota set on its parent filesystems or
# the amount of space in the pool, whichever is smaller.
#
if [[ $obj == $TESTPOOL/$TESTFS ]]; then
log_must zfs set quota=$quota_set_size $obj
((resv_set_size = quota_set_size + RESV_SIZE))

elif [[ $obj == $TESTPOOL/$TESTVOL2 ]] ; then

((resv_set_size = sparse_vol_set_size + RESV_SIZE))

elif [[ $obj == $TESTPOOL/$TESTVOL ]] ; then

((resv_set_size = vol_set_size + RESV_SIZE))
elif [[ $obj == $TESTPOOL/$TESTVOL || $obj == $TESTPOOL/$TESTVOL2 ]]
then
resv_set_size=`expr $space_avail + $RESV_DELTA`
fi

orig_quota=`get_prop quota $obj`
Expand Down

0 comments on commit 502fed8

Please sign in to comment.