Add stage-mulit-part test

Add a test which stages a file in multiple parts while a long-lived
process is blocking on offline extents trying to compare the file to the
known contents.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2020-12-15 15:13:42 -08:00
parent 807ae11ee9
commit 511cb04330
3 changed files with 70 additions and 0 deletions

View File

View File

@@ -16,6 +16,7 @@ createmany-parallel.sh
createmany-large-names.sh
createmany-rename-large-dir.sh
stage-release-race-alloc.sh
stage-multi-part.sh
basic-posix-consistency.sh
dirent-consistency.sh
lock-ex-race-processes.sh

View File

@@ -0,0 +1,69 @@
#
# Stage a large file in multiple parts and have a reader read it while
# it's being staged. This has found problems with extent access
# locking.
#
t_require_commands scoutfs perl cmp rm
FILE_BYTES=$((4 * 1024 * 1024 * 1024))
FILE_BLOCKS=$((FILE_BYTES / 4096))
FRAG_BYTES=$((128 * 1024 * 1024))
FRAG_BLOCKS=$((FRAG_BYTES / 4096))
NR_FRAGS=$((FILE_BLOCKS / FRAG_BLOCKS))
#
# high bandwidth way to generate file contents with predictable
# contents. We use ascii lines with the block identity, padded to 4KB
# with spaces.
#
# $1 is number of 4k blocks to write, and each block gets its block
# number in the line. $2, $3, and $4 are fields that are put in every
# block.
#
gen() {
perl -e 'for (my $i = 0; $i < '$1'; $i++) { printf("mount %020u process %020u file %020u blkno %020u%s\n", '$2', '$3', '$4', $i, " " x 3987); }'
}
release_file() {
local path="$1"
local vers=$(scoutfs stat -s data_version "$path")
scoutfs release "$path" "$vers" 0 $FILE_BLOCKS
}
stage_file() {
local path="$1"
local vers=$(scoutfs stat -s data_version "$path")
local off=0
for a in $(seq 1 $NR_FRAGS); do
scoutfs stage "$path" "$vers" $off $FRAG_BYTES \
<(gen $FRAG_BLOCKS $a $a $a)
((off+=$FRAG_BYTES))
done
}
FILE="$T_D0/file"
whole_file() {
for a in $(seq 1 $NR_FRAGS); do
gen $FRAG_BLOCKS $a $a $a
done
}
#
# just one pass through the file.
#
whole_file > "$FILE"
release_file "$FILE"
cmp "$FILE" <(whole_file) &
pid=$!
stage_file "$FILE"
wait $pid || t_fail "comparison failed"
t_pass