aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/zfs/zfs_main.c25
-rw-r--r--man/man8/zfs-create.83
-rw-r--r--tests/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create.cfg8
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_002_pos.ksh12
4 files changed, 45 insertions, 3 deletions
diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c
index 15e350313..27f34b9fd 100644
--- a/cmd/zfs/zfs_main.c
+++ b/cmd/zfs/zfs_main.c
@@ -1038,6 +1038,31 @@ zfs_do_create(int argc, char **argv)
}
}
+ /*
+ * if volsize is not a multiple of volblocksize, round it up to the
+ * nearest multiple of the volblocksize
+ */
+ if (type == ZFS_TYPE_VOLUME) {
+ uint64_t volblocksize;
+
+ if (nvlist_lookup_uint64(props,
+ zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
+ &volblocksize) != 0)
+ volblocksize = ZVOL_DEFAULT_BLOCKSIZE;
+
+ if (volsize % volblocksize) {
+ volsize = P2ROUNDUP_TYPED(volsize, volblocksize,
+ uint64_t);
+
+ if (nvlist_add_uint64(props,
+ zfs_prop_to_name(ZFS_PROP_VOLSIZE), volsize) != 0) {
+ nvlist_free(props);
+ nomem();
+ }
+ }
+ }
+
+
if (type == ZFS_TYPE_VOLUME && !noreserve) {
uint64_t spa_version;
zfs_prop_t resv_prop;
diff --git a/man/man8/zfs-create.8 b/man/man8/zfs-create.8
index 6aef2bb57..24ad77d02 100644
--- a/man/man8/zfs-create.8
+++ b/man/man8/zfs-create.8
@@ -143,8 +143,7 @@ The size represents the logical size as exported by the device.
By default, a reservation of equal size is created.
.Pp
.Ar size
-is automatically rounded up to the nearest 128 Kbytes to ensure that the volume
-has an integral number of blocks regardless of
+is automatically rounded up to the nearest multiple of the
.Sy blocksize .
.Bl -tag -width "-b"
.It Fl b Ar blocksize
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create.cfg b/tests/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create.cfg
index b96908ce1..9bf25327e 100644
--- a/tests/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create.cfg
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create.cfg
@@ -54,6 +54,12 @@ export VOL_LIMIT_KEYWORD1="1TB on 32-bit"
export VOL_LIMIT_KEYWORD2="value is too large"
export VOL_LIMIT_KEYWORD3="volume size exceeds limit"
-set -A size "8k" "8K" "1m" "1M" "1mb" "1mB" "1Mb" "1MB" "1g" "1G" \
+set -A size "8k" "8K" "35K" "1m" "1M" "1mb" "1mB" "1Mb" "1MB" "1g" "1G" \
"1p" "1P" "1z" "1Z" "1gb" "1gB" "1Gb" "1GB" "1pb" "1pB" "1Pb" \
"1PB" "1zb" "1zB" "1Zb" "1ZB"
+
+# If a datasize has a volume size that is not a multiple of the blocksize,
+# explicitly check that its size has been rounded up to the nearest multiple
+# The volume with the exact size must exist in the "size" array above
+set -A explicit_size_check "35K"
+set -A expected_rounded_size "40960"
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_002_pos.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_002_pos.ksh
index 6f36b40bf..0218e2e16 100755
--- a/tests/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_002_pos.ksh
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_002_pos.ksh
@@ -31,6 +31,7 @@
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/cli_root/zfs_create/zfs_create.cfg
+. $STF_SUITE/tests/functional/cli_root/zfs_create/zfs_create_common.kshlib
#
# DESCRIPTION:
@@ -39,6 +40,8 @@
# STRATEGY:
# 1. Create a volume in the storage pool.
# 2. Verify the volume is created correctly.
+# 3. Verify that the volume created has its volsize rounded to the nearest
+# multiple of the blocksize (in this case, the default blocksize)
#
verify_runnable "global"
@@ -76,6 +79,15 @@ while (( $j < ${#size[*]} )); do
fi
((j = j + 1))
+done
+
+typeset -i j=0
+while (( $j < ${#explicit_size_check[*]} )); do
+ propertycheck ${TESTPOOL}/${TESTVOL}${explicit_size_check[j]} \
+ volsize=${expected_rounded_size[j]} || \
+ log_fail "volsize ${size[j]} was not rounded up"
+ ((j = j + 1))
done
+
log_pass "'zfs create -s -V <size> <volume>' works as expected."