mirror of
https://github.com/versity/scoutfs.git
synced 2025-12-23 13:35:18 +00:00
Add move-blocks test
Add a basic test of the move_blocks ioctl. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
33
tests/golden/move-blocks
Normal file
33
tests/golden/move-blocks
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
== build test files
|
||||||
|
== wrapped offsets should fail
|
||||||
|
ioctl failed on '/mnt/test/test/move-blocks/to': Value too large for defined data type (75)
|
||||||
|
scoutfs: move-blocks failed: Value too large for defined data type (75)
|
||||||
|
ioctl failed on '/mnt/test/test/move-blocks/to': Value too large for defined data type (75)
|
||||||
|
scoutfs: move-blocks failed: Value too large for defined data type (75)
|
||||||
|
== specifying same file fails
|
||||||
|
ioctl failed on '/mnt/test/test/move-blocks/hardlink': Invalid argument (22)
|
||||||
|
scoutfs: move-blocks failed: Invalid argument (22)
|
||||||
|
== specifying files in other file systems fails
|
||||||
|
ioctl failed on '/mnt/test/test/move-blocks/to': Invalid cross-device link (18)
|
||||||
|
scoutfs: move-blocks failed: Invalid cross-device link (18)
|
||||||
|
== offsets must be multiples of 4KB
|
||||||
|
ioctl failed on '/mnt/test/test/move-blocks/to': Invalid argument (22)
|
||||||
|
scoutfs: move-blocks failed: Invalid argument (22)
|
||||||
|
ioctl failed on '/mnt/test/test/move-blocks/to': Invalid argument (22)
|
||||||
|
scoutfs: move-blocks failed: Invalid argument (22)
|
||||||
|
ioctl failed on '/mnt/test/test/move-blocks/to': Invalid argument (22)
|
||||||
|
scoutfs: move-blocks failed: Invalid argument (22)
|
||||||
|
== can't move onto existing extent
|
||||||
|
ioctl failed on '/mnt/test/test/move-blocks/to': Invalid argument (22)
|
||||||
|
scoutfs: move-blocks failed: Invalid argument (22)
|
||||||
|
== can't move between files with offline extents
|
||||||
|
ioctl failed on '/mnt/test/test/move-blocks/to': No data available (61)
|
||||||
|
scoutfs: move-blocks failed: No data available (61)
|
||||||
|
ioctl failed on '/mnt/test/test/move-blocks/to': No data available (61)
|
||||||
|
scoutfs: move-blocks failed: No data available (61)
|
||||||
|
== basic moves work
|
||||||
|
== moving final partial block sets partial i_size
|
||||||
|
123
|
||||||
|
== moving updates inode fields
|
||||||
|
== moving blocks backwards works
|
||||||
|
== combine many files into one
|
||||||
@@ -6,6 +6,7 @@ simple-staging.sh
|
|||||||
simple-release-extents.sh
|
simple-release-extents.sh
|
||||||
setattr_more.sh
|
setattr_more.sh
|
||||||
offline-extent-waiting.sh
|
offline-extent-waiting.sh
|
||||||
|
move-blocks.sh
|
||||||
srch-basic-functionality.sh
|
srch-basic-functionality.sh
|
||||||
simple-xattr-unit.sh
|
simple-xattr-unit.sh
|
||||||
lock-refleak.sh
|
lock-refleak.sh
|
||||||
|
|||||||
169
tests/tests/move-blocks.sh
Normal file
169
tests/tests/move-blocks.sh
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
#
|
||||||
|
# test MOVE_BLOCKS ioctl, mostly basic error testing and functionality,
|
||||||
|
# but a bit of expected use.
|
||||||
|
#
|
||||||
|
|
||||||
|
t_require_commands scoutfs dd
|
||||||
|
|
||||||
|
FROM="$T_D0/from"
|
||||||
|
TO="$T_D0/to"
|
||||||
|
HARD="$T_D0/hardlink"
|
||||||
|
OTHER="$T_TMP.other"
|
||||||
|
|
||||||
|
BLOCKS=8
|
||||||
|
BS=4096
|
||||||
|
PART=123
|
||||||
|
LEN=$(((BS * BLOCKS) + PART))
|
||||||
|
PIECES=8
|
||||||
|
|
||||||
|
regenerate_files() {
|
||||||
|
rm -f "$FROM"
|
||||||
|
rm -f "$TO"
|
||||||
|
dd if=/dev/urandom of="$FROM" bs=$LEN count=1 status=none
|
||||||
|
touch "$TO"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_updated_fields() {
|
||||||
|
local arr="$1"
|
||||||
|
local path="$2"
|
||||||
|
|
||||||
|
eval $arr["ctime"]="$(stat -c '%Z' "$path")"
|
||||||
|
eval $arr["mtime"]="$(stat -c '%Y' "$path")"
|
||||||
|
eval $arr["data_version"]="$(scoutfs stat -s data_version "$path")"
|
||||||
|
eval $arr["meta_seq"]="$(scoutfs stat -s meta_seq "$path")"
|
||||||
|
eval $arr["data_seq"]="$(scoutfs stat -s data_seq "$path")"
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# before moving extents manually copy the byte regions so that we have
|
||||||
|
# expected good file contents to compare to. We know that the byte
|
||||||
|
# regions are 4KB block aligned (with an allowance for a len that ends
|
||||||
|
# on from i_size).
|
||||||
|
#
|
||||||
|
move_and_compare() {
|
||||||
|
local from="$1"
|
||||||
|
local from_off="$2"
|
||||||
|
local from_blk="$((from_off / BS))"
|
||||||
|
local len="$3"
|
||||||
|
local blocks="$(((len + BS - 1) / BS))"
|
||||||
|
local to="$4"
|
||||||
|
local to_off="$5"
|
||||||
|
local to_blk="$((to_off / BS))"
|
||||||
|
|
||||||
|
local right_start=$((from_blk + blocks))
|
||||||
|
local from_size=$(stat -c "%s" "$from")
|
||||||
|
local from_blocks=$(( (from_size + BS - 1) / BS ))
|
||||||
|
local right_len=$((from_blocks - right_start))
|
||||||
|
|
||||||
|
# copying around instead of punching hole
|
||||||
|
dd if="$from" of="$from.expected" bs="$BS" \
|
||||||
|
skip=0 seek=0 count="$from_blk" \
|
||||||
|
status=none
|
||||||
|
dd if="$from" of="$from.expected" bs="$BS" \
|
||||||
|
skip="$right_start" seek="$right_start" count="$right_len" \
|
||||||
|
status=none conv=notrunc
|
||||||
|
# moving doesn't truncate, expect full size when no data
|
||||||
|
truncate -s "$from_size" "$from.expected"
|
||||||
|
|
||||||
|
cp "$to" "$to.expected"
|
||||||
|
dd if="$from" of="$to.expected" bs="$BS" \
|
||||||
|
skip="$from_blk" seek="$to_blk" count="$blocks" \
|
||||||
|
status=none conv=notrunc
|
||||||
|
|
||||||
|
scoutfs move-blocks "$from" -f "$from_off" -l "$len" "$to" -t "$to_off" \
|
||||||
|
2>&1 | t_filter_fs
|
||||||
|
|
||||||
|
cmp "$from" "$from.expected"
|
||||||
|
cmp "$to" "$to.expected"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "== build test files"
|
||||||
|
regenerate_files
|
||||||
|
touch "$OTHER"
|
||||||
|
ln "$FROM" "$HARD"
|
||||||
|
|
||||||
|
echo "== wrapped offsets should fail"
|
||||||
|
HUGE=0x8000000000000000
|
||||||
|
scoutfs move-blocks "$FROM" -f "$HUGE" -l "$HUGE" "$TO" -t 0 2>&1 | t_filter_fs
|
||||||
|
scoutfs move-blocks "$FROM" -f 0 -l "$HUGE" "$TO" -t "$HUGE" 2>&1 | t_filter_fs
|
||||||
|
|
||||||
|
echo "== specifying same file fails"
|
||||||
|
scoutfs move-blocks "$FROM" -f 0 -l "$BS" "$HARD" -t 0 2>&1 | t_filter_fs
|
||||||
|
|
||||||
|
echo "== specifying files in other file systems fails"
|
||||||
|
scoutfs move-blocks "$OTHER" -f 0 -l "$BS" "$TO" -t 0 2>&1 | t_filter_fs
|
||||||
|
|
||||||
|
echo "== offsets must be multiples of 4KB"
|
||||||
|
scoutfs move-blocks "$FROM" -f 1 -l "$BS" "$TO" -t 0 2>&1 | t_filter_fs
|
||||||
|
scoutfs move-blocks "$FROM" -f 0 -l 1 "$TO" -t 0 2>&1 | t_filter_fs
|
||||||
|
scoutfs move-blocks "$FROM" -f 0 -l "$BS" "$TO" -t 1 2>&1 | t_filter_fs
|
||||||
|
|
||||||
|
echo "== can't move onto existing extent"
|
||||||
|
dd if=/dev/urandom of="$TO" bs=$BS count=1 status=none
|
||||||
|
scoutfs move-blocks "$FROM" -f 0 -l "$BS" "$TO" -t 0 2>&1 | t_filter_fs
|
||||||
|
|
||||||
|
echo "== can't move between files with offline extents"
|
||||||
|
dd if=/dev/zero of="$TO" bs=$BS count=1 status=none
|
||||||
|
vers=$(scoutfs stat -s data_version "$TO")
|
||||||
|
scoutfs release "$TO" -V "$vers" -o 0 -l $BS
|
||||||
|
scoutfs move-blocks "$FROM" -f 0 -l "$BS" "$TO" -t 0 2>&1 | t_filter_fs
|
||||||
|
regenerate_files
|
||||||
|
vers=$(scoutfs stat -s data_version "$FROM")
|
||||||
|
scoutfs release "$FROM" -V "$vers" -o 0 -l $BS
|
||||||
|
scoutfs move-blocks "$FROM" -f 0 -l "$BS" "$TO" -t 0 2>&1 | t_filter_fs
|
||||||
|
regenerate_files
|
||||||
|
|
||||||
|
echo "== basic moves work"
|
||||||
|
move_and_compare "$FROM" 0 "$BS" "$TO" 0
|
||||||
|
regenerate_files
|
||||||
|
move_and_compare "$FROM" 0 "$BS" "$TO" "$BS"
|
||||||
|
regenerate_files
|
||||||
|
move_and_compare "$FROM" 0 "$LEN" "$TO" 0
|
||||||
|
regenerate_files
|
||||||
|
|
||||||
|
echo "== moving final partial block sets partial i_size"
|
||||||
|
move_and_compare "$FROM" $((LEN - PART)) "$PART" "$TO" 0
|
||||||
|
stat -c '%s' "$TO"
|
||||||
|
regenerate_files
|
||||||
|
|
||||||
|
echo "== moving updates inode fields"
|
||||||
|
declare -A from_before from_after to_before to_after
|
||||||
|
set_updated_fields from_before "$FROM"
|
||||||
|
set_updated_fields to_before "$TO"
|
||||||
|
t_quiet sync
|
||||||
|
sleep 1
|
||||||
|
move_and_compare "$FROM" 0 "$BS" "$TO" 0
|
||||||
|
set_updated_fields from_after "$FROM"
|
||||||
|
set_updated_fields to_after "$TO"
|
||||||
|
for k in ${!from_after[@]}; do
|
||||||
|
if [ "${from_before[$k]}" == "${from_after[$k]}" ]; then
|
||||||
|
echo "move didn't change from $k ${from_before[$k]}"
|
||||||
|
fi
|
||||||
|
if [ "${to_before[$k]}" == "${to_after[$k]}" ]; then
|
||||||
|
echo "move didn't change to $k ${to_before[$k]}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
regenerate_files
|
||||||
|
|
||||||
|
echo "== moving blocks backwards works"
|
||||||
|
cp "$FROM" "$FROM.orig"
|
||||||
|
move_and_compare "$FROM" $((LEN - PART)) "$PART" "$TO" $((LEN - PART))
|
||||||
|
for i in $(seq $((BLOCKS - 1)) -1 0); do
|
||||||
|
move_and_compare "$FROM" $((i * BS)) "$BS" "$TO" $((i * BS))
|
||||||
|
done
|
||||||
|
cmp "$TO" "$FROM.orig"
|
||||||
|
regenerate_files
|
||||||
|
|
||||||
|
echo "== combine many files into one"
|
||||||
|
for i in $(seq 0 $((PIECES - 1))); do
|
||||||
|
dd if=/dev/urandom of="$FROM.$i" bs=$BS count=$BLOCKS status=none
|
||||||
|
cat "$FROM.$i" >> "$TO.large"
|
||||||
|
move_and_compare "$FROM.$i" 0 "$((BS * BLOCKS))" \
|
||||||
|
"$TO" $((i * BS * BLOCKS))
|
||||||
|
done
|
||||||
|
((i++))
|
||||||
|
cat "$FROM" >> "$TO.large"
|
||||||
|
move_and_compare "$FROM" 0 "$LEN" "$TO" $((i * BS * BLOCKS))
|
||||||
|
cmp "$TO.large" "$TO"
|
||||||
|
|
||||||
|
t_pass
|
||||||
Reference in New Issue
Block a user