zfs_create: round up volume size to multiple of bs
Round up the volume size requested in `zfs create -V size` to the next higher multiple of the volblocksize. Updates the man page and adds a test to verify the new behavior. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reported-by: puffi <puffi@users.noreply.github.com> Signed-off-by: Alex John <alex@stty.io> Closes #8541 Closes #10196
This commit is contained in:
parent
aa646323db
commit
47c9299fcc
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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."
|
||||
|
|
Loading…
Reference in New Issue