blob: 13921bb8165a4dadcff0803db529f5c87ea114af [file] [log] [blame]
#
# ext4 specific common functions
#
__generate_ext4_report_vars() {
__generate_blockdev_report_vars TEST_LOGDEV
__generate_blockdev_report_vars SCRATCH_LOGDEV
}
_setup_large_ext4_fs()
{
local fs_size=$1
local tmp_dir=/tmp/
[ "$LARGE_SCRATCH_DEV" != yes ] && return 0
[ -z "$SCRATCH_DEV_EMPTY_SPACE" ] && SCRATCH_DEV_EMPTY_SPACE=0
[ $SCRATCH_DEV_EMPTY_SPACE -ge $fs_size ] && return 0
# Default free space in the FS is 50GB, but you can specify more via
# SCRATCH_DEV_EMPTY_SPACE
local space_to_consume=$(($fs_size - 50*1024*1024*1024 - $SCRATCH_DEV_EMPTY_SPACE))
# mount the filesystem and create 16TB - 4KB files until we consume
# all the necessary space.
_try_scratch_mount 2>&1 >$tmp_dir/mnt.err
local status=$?
if [ $status -ne 0 ]; then
echo "mount failed"
cat $tmp_dir/mnt.err >&2
rm -f $tmp_dir/mnt.err
return $status
fi
rm -f $tmp_dir/mnt.err
local file_size=$((16*1024*1024*1024*1024 - 4096))
local nfiles=0
while [ $space_to_consume -gt $file_size ]; do
xfs_io -F -f \
-c "truncate $file_size" \
-c "falloc -k 0 $file_size" \
$SCRATCH_MNT/.use_space.$nfiles 2>&1
status=$?
if [ $status -ne 0 ]; then
break;
fi
space_to_consume=$(( $space_to_consume - $file_size ))
nfiles=$(($nfiles + 1))
done
# consume the remaining space.
if [ $space_to_consume -gt 0 ]; then
xfs_io -F -f \
-c "truncate $space_to_consume" \
-c "falloc -k 0 $space_to_consume" \
$SCRATCH_MNT/.use_space.$nfiles 2>&1
status=$?
fi
export NUM_SPACE_FILES=$nfiles
_scratch_unmount
if [ $status -ne 0 ]; then
echo "large file prealloc failed"
cat $tmp_dir/mnt.err >&2
return $status
fi
return 0
}
_scratch_mkfs_ext4_opts()
{
mkfs_opts=$*
_scratch_options mkfs
echo "$MKFS_EXT4_PROG $SCRATCH_OPTIONS $mkfs_opts"
}
_scratch_mkfs_ext4()
{
local mkfs_cmd="`_scratch_mkfs_ext4_opts`"
local mkfs_filter="grep -v -e ^Warning: -e \"^mke2fs \" | grep -v \"^$\""
local tmp=`mktemp -u`
local mkfs_status
if [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ]; then
$MKFS_EXT4_PROG -F -O journal_dev $MKFS_OPTIONS $* $SCRATCH_LOGDEV 2>$tmp.mkfserr 1>$tmp.mkfsstd
mkjournal_status=$?
if [ $mkjournal_status -ne 0 ]; then
cat $tmp.mkfsstd
cat $tmp.mkfserr >&2
return $mkjournal_status
fi
fi
_scratch_do_mkfs "$mkfs_cmd" "$mkfs_filter" $* 2>$tmp.mkfserr 1>$tmp.mkfsstd
mkfs_status=$?
if [ $mkfs_status -eq 0 -a "$LARGE_SCRATCH_DEV" = yes ]; then
# manually parse the mkfs output to get the fs size in bytes
local fs_size=`cat $tmp.mkfsstd | awk ' \
/^Block size/ { split($2, a, "="); bs = a[2] ; } \
/ inodes, / { blks = $3 } \
/reserved for the super user/ { resv = $1 } \
END { fssize = bs * blks - resv; print fssize }'`
_setup_large_ext4_fs $fs_size
mkfs_status=$?
fi
# output mkfs stdout and stderr
cat $tmp.mkfsstd
cat $tmp.mkfserr >&2
rm -f $tmp.mkfserr $tmp.mkfsstd
return $mkfs_status
}
_ext4_metadump()
{
local device="$1"
local dumpfile="$2"
local compressopt="$3"
test -n "$E2IMAGE_PROG" || _fail "e2image not installed"
$E2IMAGE_PROG -Q "$device" "$dumpfile"
[ "$compressopt" = "compress" ] && [ -n "$DUMP_COMPRESSOR" ] &&
$DUMP_COMPRESSOR -f "$dumpfile" &>> "$seqres.full"
}
_ext4_mdrestore()
{
local metadump="$1"
local device="$2"
shift; shift
local options="$@"
# If we're configured for compressed dumps and there isn't already an
# uncompressed dump, see if we can use DUMP_COMPRESSOR to decompress
# something.
if [ ! -e "$metadump" ] && [ -n "$DUMP_COMPRESSOR" ]; then
for compr in "$metadump".*; do
[ -e "$compr" ] && $DUMP_COMPRESSOR -d -f -k "$compr" && break
done
fi
test -r "$metadump" || return 1
$E2IMAGE_PROG $options -r "${metadump}" "${SCRATCH_DEV}"
}
# this test requires the ext4 kernel support crc feature on scratch device
#
_require_scratch_ext4_crc()
{
_scratch_mkfs_ext4 >/dev/null 2>&1
dumpe2fs -h $SCRATCH_DEV 2> /dev/null | grep -q metadata_csum || _notrun "metadata_csum not supported by this filesystem"
_try_scratch_mount >/dev/null 2>&1 \
|| _notrun "Kernel doesn't support metadata_csum feature"
_scratch_unmount
}
# Check whether the specified feature whether it is supported by
# mkfs.ext4 and the kernel.
_require_scratch_ext4_feature()
{
if [ -z "$1" ]; then
echo "Usage: _require_scratch_ext4_feature feature"
exit 1
fi
$MKFS_EXT4_PROG -F $MKFS_OPTIONS -O "$1" \
$SCRATCH_DEV 512m >/dev/null 2>&1 \
|| _notrun "mkfs.ext4 doesn't support $1 feature"
_try_scratch_mount >/dev/null 2>&1 \
|| _notrun "Kernel doesn't support the ext4 feature(s): $1"
_scratch_unmount
}
# Disable extent zeroing for ext4 on the given device
_ext4_disable_extent_zeroout()
{
local dev=${1:-$TEST_DEV}
local sdev=`_short_dev $dev`
[ -f /sys/fs/ext4/$sdev/extent_max_zeroout_kb ] && \
echo 0 >/sys/fs/ext4/$sdev/extent_max_zeroout_kb
}
_scratch_ext4_options()
{
local type=$1
local log_opt=""
case $type in
mkfs)
SCRATCH_OPTIONS="$SCRATCH_OPTIONS -F"
log_opt="-J device=$SCRATCH_LOGDEV"
;;
mount)
# As of kernel 5.19, the kernel mount option path parser only
# accepts direct paths to block devices--the final path
# component cannot be a symlink.
log_opt="-o journal_path=$(realpath -q "$SCRATCH_LOGDEV")"
;;
esac
[ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
SCRATCH_OPTIONS="$SCRATCH_OPTIONS ${log_opt}"
}
# Get the inode flags for a particular inode number
_ext4_get_inum_iflags() {
local dev="$1"
local inumber="$2"
debugfs -R "stat <${inumber}>" "${dev}" 2> /dev/null | \
sed -n 's/^.*Flags: \([0-9a-fx]*\).*$/\1/p'
}