]> granicus.if.org Git - zfs/commitdiff
Relax (ref)reservation constraints on ZVOLs
authorLOLi <loli10K@users.noreply.github.com>
Tue, 12 Sep 2017 18:33:22 +0000 (20:33 +0200)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 12 Sep 2017 18:33:22 +0000 (11:33 -0700)
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

lib/libzfs/libzfs_dataset.c
tests/zfs-tests/tests/functional/refreserv/refreserv_005_pos.ksh
tests/zfs-tests/tests/functional/reservation/reservation_002_pos.sh
tests/zfs-tests/tests/functional/reservation/reservation_014_pos.sh

index 76a16603853d56195df101fe08387c5a7da7acb4..3cf4707598dbfa79df9c8ca0f11464b95348bf53 100644 (file)
@@ -1451,25 +1451,11 @@ badlabel:
                 * 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,
index a43dd84327d1e16f43c4039fd2b83d91188016b7..8c044eca59d5e972fbc119306eb8ed2ebdb6b7c2 100755 (executable)
 
 #
 # 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"
@@ -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"
index f96010802686a5571bc0d7e9435e2866a6e93b48..202393d4d58c22558111404d156dba18abae3dad 100755 (executable)
@@ -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
 
index d307917b5b17891e24666a78ba1ef7e4c7e2f78e..e8bd91d00e6896e3e2b3780ee01139c08201c506 100755 (executable)
@@ -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`