#!/bin/bash # SPDX-License-Identifier: GPL-2.0 # Copyright (c) 2021 Google, Inc. All Rights Reserved. # # FS QA Test No. 050 # # Test checkpoint and zeroout of journal via ioctl EXT4_IOC_CHECKPOINT # . ./common/preamble _begin_fstest auto ioctl quick # Import common functions. . ./common/filter # real QA test starts here _supported_fs ext4 _require_scratch _require_command "$DEBUGFS_PROG" debugfs checkpoint_journal=$here/src/checkpoint_journal _require_test_program "checkpoint_journal" # convert output from stat to list of block numbers get_journal_extents() { inode_info=$($DEBUGFS_PROG $SCRATCH_DEV -R "stat <8>" 2>> $seqres.full) echo -e "\nJournal info:" >> $seqres.full echo "$inode_info" >> $seqres.full extents_line=$(echo "$inode_info" | awk '/EXTENTS:/{ print NR; exit }') get_extents=$(echo "$inode_info" | sed -n "$(($extents_line + 1))"p) # get just the physical block numbers get_extents=$(echo "$get_extents" | perl -pe 's|\(.*?\):||g' | sed -e 's/, /\n/g' | perl -pe 's|(\d+)-(\d+)|\1 \2|g') echo "$get_extents" } # checks all extents are zero'd out except for the superblock # arg 1: extents (output of get_journal_extents()) check_extents() { echo -e "\nChecking extents:" >> $seqres.full echo "$1" >> $seqres.full super_block="true" echo "$1" | while IFS= read line; do start_block=$(echo $line | cut -f1 -d' ') end_block=$(echo $line | cut -f2 -d' ' -s) # if first block of journal, shouldn't be wiped if [ "$super_block" == "true" ]; then super_block="false" #if super block only block in this extent, skip extent if [ -z "$end_block" ]; then continue; fi start_block=$(($start_block + 1)) fi if [ ! -z "$end_block" ]; then blocks=$(($end_block - $start_block + 1)) else blocks=1 fi check=$(od $SCRATCH_DEV --skip-bytes=$(($start_block * $blocksize)) --read-bytes=$(($blocks * $blocksize)) -An -v | sed -e 's/[0 \t\n\r]//g') [ ! -z "$check" ] && echo "error" && break done } testdir="${SCRATCH_MNT}/testdir" _scratch_mkfs_sized $((64 * 1024 * 1024)) >> $seqres.full 2>&1 _require_metadata_journaling $SCRATCH_DEV _scratch_mount >> $seqres.full 2>&1 blocksize=$(_get_block_size $SCRATCH_MNT) mkdir $testdir # check if ioctl present, skip test if not present $checkpoint_journal $SCRATCH_MNT --dry-run || _notrun "journal checkpoint ioctl not present on device" # create some files to add some entries to journal for i in {1..100}; do echo > $testdir/$i done # make sure these files get to the journal sync --file-system $testdir/1 # call ioctl to checkpoint and zero-fill journal blocks $checkpoint_journal $SCRATCH_MNT --erase=zeroout || _fail "ioctl returned error" extents=$(get_journal_extents) # check journal blocks zeroed out ret=$(check_extents "$extents") [ "$ret" = "error" ] && _fail "Journal was not zero-filled" _scratch_unmount >> $seqres.full 2>&1 echo "Silence is golden" status=0 exit