ext4: test journal checkpoint ioctl
[xfstests-dev.git] / tests / ext4 / 050
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2021 Google, Inc. All Rights Reserved.
4 #
5 # FS QA Test No. 050
6 #
7 # Test checkpoint and zeroout of journal via ioctl EXT4_IOC_CHECKPOINT
8 #
9
10 seq=`basename $0`
11 seqres=$RESULT_DIR/$seq
12 echo "QA output created by $seq"
13
14 status=1       # failure is the default!
15
16 # get standard environment, filters and checks
17 . ./common/rc
18 . ./common/filter
19
20 # remove previous $seqres.full before test
21 rm -f $seqres.full
22
23 # real QA test starts here
24 _supported_fs ext4
25
26 _require_scratch
27 _require_command "$DEBUGFS_PROG" debugfs
28
29 checkpoint_journal=$here/src/checkpoint_journal
30 _require_test_program "checkpoint_journal"
31
32 # convert output from stat<journal_inode> to list of block numbers
33 get_journal_extents() {
34         inode_info=$($DEBUGFS_PROG $SCRATCH_DEV -R "stat <8>" 2>> $seqres.full)
35         echo -e "\nJournal info:" >> $seqres.full
36         echo "$inode_info" >> $seqres.full
37
38         extents_line=$(echo "$inode_info" | awk '/EXTENTS:/{ print NR; exit }')
39         get_extents=$(echo "$inode_info" | sed -n "$(($extents_line + 1))"p)
40
41         # get just the physical block numbers
42         get_extents=$(echo "$get_extents" |  perl -pe 's|\(.*?\):||g' | sed -e 's/, /\n/g' | perl -pe 's|(\d+)-(\d+)|\1 \2|g')
43
44         echo "$get_extents"
45 }
46
47
48 # checks all extents are zero'd out except for the superblock
49 # arg 1: extents (output of get_journal_extents())
50 check_extents() {
51         echo -e "\nChecking extents:" >> $seqres.full
52         echo "$1" >> $seqres.full
53
54         super_block="true"
55         echo "$1" | while IFS= read line; do
56                 start_block=$(echo $line | cut -f1 -d' ')
57                 end_block=$(echo $line | cut -f2 -d' ' -s)
58
59                 # if first block of journal, shouldn't be wiped
60                 if [ "$super_block" == "true" ]; then
61                         super_block="false"
62
63                         #if super block only block in this extent, skip extent
64                         if [ -z "$end_block" ]; then
65                                 continue;
66                         fi
67                         start_block=$(($start_block + 1))
68                 fi
69
70                 if [ ! -z "$end_block" ]; then
71                         blocks=$(($end_block - $start_block + 1))
72                 else
73                         blocks=1
74                 fi
75
76                 check=$(od $SCRATCH_DEV --skip-bytes=$(($start_block * $blocksize)) --read-bytes=$(($blocks * $blocksize)) -An -v | sed -e 's/[0 \t\n\r]//g')
77
78                 [ ! -z "$check" ] && echo "error" && break
79         done
80 }
81
82 testdir="${SCRATCH_MNT}/testdir"
83
84 _scratch_mkfs_sized $((64 * 1024 * 1024)) >> $seqres.full 2>&1
85 _require_metadata_journaling $SCRATCH_DEV
86 _scratch_mount >> $seqres.full 2>&1
87 blocksize=$(_get_block_size $SCRATCH_MNT)
88 mkdir $testdir
89
90 # check if ioctl present, skip test if not present
91 $checkpoint_journal $SCRATCH_MNT --dry-run || _notrun "journal checkpoint ioctl not present on device"
92
93 # create some files to add some entries to journal
94 for i in {1..100}; do
95         echo > $testdir/$i
96 done
97
98 # make sure these files get to the journal
99 sync --file-system $testdir/1
100
101 # call ioctl to checkpoint and zero-fill journal blocks
102 $checkpoint_journal $SCRATCH_MNT --erase=zeroout || _fail "ioctl returned error"
103
104 extents=$(get_journal_extents)
105
106 # check journal blocks zeroed out
107 ret=$(check_extents "$extents")
108 [ "$ret" = "error" ] && _fail "Journal was not zero-filled"
109
110 _scratch_unmount >> $seqres.full 2>&1
111
112 echo "Silence is golden"
113
114 status=0
115 exit