| ##/bin/bash |
| # SPDX-License-Identifier: GPL-2.0 |
| # Copyright (c) 2007 Silicon Graphics, Inc. All Rights Reserved. |
| # |
| # Core of filestreams tests. |
| |
| _check_filestreams_support() |
| { |
| [ -f /proc/sys/fs/xfs/filestream_centisecs ] |
| } |
| |
| _set_stream_timeout_centisecs() |
| { |
| echo $1 > /proc/sys/fs/xfs/filestream_centisecs |
| } |
| |
| _do_stream() |
| { |
| local directory_name=$1 |
| local files=$2 |
| local file_size=$3 |
| local bsize=$4 |
| local iflag=$5 |
| local dio=$6 |
| local blocks_in_file=`expr $file_size / $bsize` |
| |
| mkdir $directory_name |
| if [ "$iflag" = "1" ]; then |
| $XFS_IO_PROG -x -c "chattr +S" $directory_name \ |
| || _fail "chattr of filestream flag" |
| fi |
| cd $directory_name |
| |
| local dd_cmd="dd" |
| [ "$dio" = "1" ] && dd_cmd="$dd_cmd oflag=direct" |
| dd_cmd="$dd_cmd if=/dev/zero bs=${bsize} count=${blocks_in_file}" |
| |
| local i=1 |
| while [ $i -le $files ]; do |
| $dd_cmd of=frame-${i} 2>&1 | grep -v records | grep -v secs |
| i=`expr $i + 1` |
| done |
| } |
| |
| _filter_agno() |
| { |
| # the ag number is in column 4 of xfs_bmap output |
| perl -ne ' |
| $ag = (split /\s+/)[4] ; |
| if ($ag =~ /\d+/) {print "$ag "} ; |
| ' |
| } |
| |
| _get_stream_ags() |
| { |
| local directory_name=$1 |
| local stream_ags=`xfs_bmap -vp ${directory_name}/* | _filter_agno` |
| echo $stream_ags |
| } |
| |
| _check_for_dupes() |
| { |
| # check for duplicate numbers between two space seperated vars |
| local num_str_one=$1 |
| local num_str_two=$2 |
| |
| local this_num_one |
| local this_num_two |
| for this_num_one in $num_str_one; do |
| for this_num_two in $num_str_two; do |
| if [ "$this_num_one" == "$this_num_two" ]; then |
| echo "duplicate AG $this_num_one found" \ |
| >> $seqres.full |
| return 1 |
| fi |
| done |
| done |
| return 0 |
| } |
| |
| _test_streams() { |
| |
| echo "# testing $* ...." |
| local agcount="$1" |
| local agsize="$2" # in MB |
| local stream_count="$3" |
| local stream_files="$4" |
| local stream_file_size=`expr $5 \* 1024 \* 1024` |
| local use_iflag="$6" |
| local use_directio="$7" |
| local expected_result="$8" # "fail" if failure is expected |
| |
| local size=`expr $agsize \* 1024 \* 1024 \* $agcount` |
| _scratch_mkfs_xfs -dsize=$size,agcount=$agcount >/dev/null 2>&1 \ |
| || _fail "mkfs failed" |
| |
| if [ "$use_iflag" = "0" ]; then |
| # mount using filestreams mount option |
| _try_scratch_mount "-o filestreams" \ |
| || _fail "filestreams mount failed" |
| else |
| # test will set inode flag |
| _scratch_mount |
| fi |
| |
| cd $SCRATCH_MNT |
| |
| # start $stream_count streams |
| # each stream writes ($stream_files x $stream_file_size)M |
| echo "# streaming" |
| local stream_pids="" |
| local stream_index=1 |
| while [ $stream_index -le $stream_count ]; do |
| _do_stream stream${stream_index}-dir $stream_files \ |
| $stream_file_size 1048576 $use_iflag $use_directio & |
| stream_pids="$stream_pids $!" |
| stream_index=`expr $stream_index + 1` |
| done |
| |
| # wait for streams to finish |
| # XXX wait here not needed? -dgc |
| wait $stream_pids |
| |
| # sync the buffered streams out in parallel |
| # _get_stream_ags does a xfs_bmap which syncs delayed allocations |
| echo "# sync AGs..." |
| local ag_sync_pids="" |
| stream_index=1 |
| while [ $stream_index -le $stream_count ]; do |
| _get_stream_ags stream${stream_index}-dir > /dev/null 2>&1 & |
| ag_sync_pids="$ag_sync_pids $!" |
| stream_index=`expr $stream_index + 1` |
| done |
| |
| # wait for syncs to finish |
| wait $ag_sync_pids |
| |
| # confirm streams are in seperate AGs |
| echo "# checking stream AGs..." |
| local this_stream_ags="" |
| local ags_seen="" |
| local num_streams_with_matching_ags=0 |
| stream_index=1 |
| while [ $stream_index -le $stream_count ]; do |
| this_stream_ags=`_get_stream_ags stream${stream_index}-dir` |
| echo "stream $stream_index AGs: $this_stream_ags" >> $seqres.full |
| _check_for_dupes "$ags_seen" "$this_stream_ags" |
| if [ $? -ne 0 ]; then |
| # this stream is not in seperate AGs to previous streams |
| num_streams_with_matching_ags=`expr $num_streams_with_matching_ags + 1` |
| fi |
| ags_seen="$ags_seen $this_stream_ags" |
| stream_index=`expr $stream_index + 1` |
| done |
| |
| _cleanup_streams_umount |
| if [ "$expected_result" != "fail" ]; then |
| if [ $num_streams_with_matching_ags -eq 0 ]; then |
| # all streams in seperate AGs, as expected |
| echo "+ passed, streams are in seperate AGs" |
| else |
| # streams with matching AGs, should be seperate |
| _fail "- failed, $num_streams_with_matching_ags streams with matching AGs" |
| fi |
| else |
| # expecting streams to have overlapped |
| if [ $num_streams_with_matching_ags -eq 0 ]; then |
| # all streams in seperate AGs, should have overlapped |
| _fail "- streams are in seperate AGs, expected _matching_" |
| else |
| # streams with matching AGs, as expected |
| echo "+ expected failure, matching AGs" |
| fi |
| fi |
| return 0 |
| } |
| |
| _cleanup_streams_umount() |
| { |
| cd / |
| rm -rf ${SCRATCH_MNT}/stream* |
| _scratch_unmount 2>/dev/null |
| } |