libzfs.h: Set ZFS_MAXPROPLEN and ZPOOL_MAXPROPLEN to ZAP_MAXVALUELEN
So far, the values of ZFS_MAXPROPLEN and ZPOOL_MAXPROPLEN were equal to MAXPATHLEN, which is 1024 on FreeBSD and 4096 on Linux. This wasn't ideal. Some of the surprising outcomes of this implementation are: 1. When creating a pool user property with zpool-set(8), libzfs makes sure that the length of the property's value is less than ZFS_MAXPROPLEN. However, the ZFS kernel module does not do that. Instead, it checks the length against ZAP_MAXVALUELEN. As a result, it is possible to create a property the length of which is going to be larger than zpool(8) is ready to read. 2. A pool user property created on Linux is too big to be read on FreeBSD. This change sets both ZFS_MAXPROPLEN and ZPOOL_MAXPROPLEN to ZAP_MAXVALUELEN, which is 8192 at the moment. Reviewed-by: Tony Hutter <hutter2@llnl.gov> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Tino Reichardt <milky-zfs@mcmilk.de> Reviewed-by: Allan Jude <allan@klarasystems.com> Signed-off-by: Mateusz Piotrowski <0mp@FreeBSD.org> Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Closes #16248
This commit is contained in:
parent
2558518c5d
commit
24e6585e76
|
@ -51,8 +51,8 @@ extern "C" {
|
||||||
/*
|
/*
|
||||||
* Miscellaneous ZFS constants
|
* Miscellaneous ZFS constants
|
||||||
*/
|
*/
|
||||||
#define ZFS_MAXPROPLEN MAXPATHLEN
|
#define ZFS_MAXPROPLEN ZAP_MAXVALUELEN
|
||||||
#define ZPOOL_MAXPROPLEN MAXPATHLEN
|
#define ZPOOL_MAXPROPLEN ZAP_MAXVALUELEN
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* libzfs errors
|
* libzfs errors
|
||||||
|
|
|
@ -210,19 +210,15 @@ log_must local_cleanup
|
||||||
log_note "verify clone list truncated correctly"
|
log_note "verify clone list truncated correctly"
|
||||||
fs=$TESTPOOL/$TESTFS1
|
fs=$TESTPOOL/$TESTFS1
|
||||||
xs=""; for i in {1..200}; do xs+="x"; done
|
xs=""; for i in {1..200}; do xs+="x"; done
|
||||||
if is_linux; then
|
maxproplen=8192
|
||||||
ZFS_MAXPROPLEN=4096
|
|
||||||
else
|
|
||||||
ZFS_MAXPROPLEN=1024
|
|
||||||
fi
|
|
||||||
log_must zfs create $fs
|
log_must zfs create $fs
|
||||||
log_must zfs snapshot $fs@snap
|
log_must zfs snapshot $fs@snap
|
||||||
for (( i = 1; i <= (ZFS_MAXPROPLEN / 200 + 1); i++ )); do
|
for (( i = 1; i <= (maxproplen / 200 + 1); i++ )); do
|
||||||
log_must zfs clone ${fs}@snap ${fs}/${TESTCLONE}${xs}.${i}
|
log_must zfs clone ${fs}@snap ${fs}/${TESTCLONE}${xs}.${i}
|
||||||
done
|
done
|
||||||
clone_list=$(zfs list -o clones $fs@snap)
|
clone_list=$(zfs list -o clones $fs@snap)
|
||||||
char_count=$(echo "$clone_list" | tail -1 | wc -c)
|
char_count=$(echo "$clone_list" | tail -1 | wc -c)
|
||||||
[[ $char_count -eq $ZFS_MAXPROPLEN ]] || \
|
[[ $char_count -eq $maxproplen ]] || \
|
||||||
log_fail "Clone list not truncated correctly. Unexpected character count" \
|
log_fail "Clone list not truncated correctly. Unexpected character count" \
|
||||||
"$char_count"
|
"$char_count"
|
||||||
|
|
||||||
|
|
|
@ -56,16 +56,10 @@ typeset -a values=()
|
||||||
# for the null byte)
|
# for the null byte)
|
||||||
names+=("$(awk 'BEGIN { printf "x:"; while (c++ < (256 - 2 - 1)) printf "a" }')")
|
names+=("$(awk 'BEGIN { printf "x:"; while (c++ < (256 - 2 - 1)) printf "a" }')")
|
||||||
values+=("long-property-name")
|
values+=("long-property-name")
|
||||||
# Longest property value (the limits are 1024 on FreeBSD and 4096 on Linux, so
|
# Longest property value (8191 bytes, which is the 8192-byte limit minus 1 byte
|
||||||
# pick the right one; the longest value can use limit minus 1 bytes for the
|
# for the null byte).
|
||||||
# null byte)
|
|
||||||
if is_linux; then
|
|
||||||
typeset ZFS_MAXPROPLEN=4096
|
|
||||||
else
|
|
||||||
typeset ZFS_MAXPROPLEN=1024
|
|
||||||
fi
|
|
||||||
names+=("long:property:value")
|
names+=("long:property:value")
|
||||||
values+=("$(awk -v max="$ZFS_MAXPROPLEN" 'BEGIN { while (c++ < (max - 1)) printf "A" }')")
|
values+=("$(awk 'BEGIN { while (c++ < (8192 - 1)) printf "A" }')")
|
||||||
# Valid property names
|
# Valid property names
|
||||||
for i in {1..10}; do
|
for i in {1..10}; do
|
||||||
typeset -i len
|
typeset -i len
|
||||||
|
|
|
@ -64,17 +64,11 @@ names+=("$(awk '
|
||||||
}'
|
}'
|
||||||
)")
|
)")
|
||||||
values+=("too-long-property-name")
|
values+=("too-long-property-name")
|
||||||
# A property value that is too long consists of at least 1024 bytes on FreeBSD
|
# A property value that is too long consists of at least 8192 bytes.
|
||||||
# and 4096 bytes on Linux.
|
|
||||||
# The smallest too-long value is (1) the limit (2) minus 1 byte for the null
|
# The smallest too-long value is (1) the limit (2) minus 1 byte for the null
|
||||||
# byte (2) plus 1 byte to reach back over the limit).
|
# byte (2) plus 1 byte to reach back over the limit).
|
||||||
if is_linux; then
|
|
||||||
typeset ZFS_MAXPROPLEN=4096
|
|
||||||
else
|
|
||||||
typeset ZFS_MAXPROPLEN=1024
|
|
||||||
fi
|
|
||||||
names+=("too:long:property:value")
|
names+=("too:long:property:value")
|
||||||
values+=("$(awk -v max="$ZFS_MAXPROPLEN" 'BEGIN { while (c++ < (max - 1 + 1)) printf "A" }')")
|
values+=("$(awk 'BEGIN { while (c++ < (8192 - 1 + 1)) printf "A" }')")
|
||||||
# Invalid property names
|
# Invalid property names
|
||||||
for i in {1..10}; do
|
for i in {1..10}; do
|
||||||
typeset -i len
|
typeset -i len
|
||||||
|
|
Loading…
Reference in New Issue