016: Do not discard blocks at mkfs time
[xfstests-dev.git] / 016
diff --git a/016 b/016
index 76ee2c01d4902fde3efb5a89cfbca044c9c5b160..08a73f49ace8e727e12ac8bc3f8aeaf5907c17bb 100755 (executable)
--- a/016
+++ b/016
@@ -1,39 +1,24 @@
-#! /bin/sh
-# XFS QA Test No. 016
-# $Id: 1.1 $
+#! /bin/bash
+# FS QA Test No. 016
 #
 # test end of log overwrite bug #796141
 #
 #-----------------------------------------------------------------------
-# Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
-# 
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of version 2 of the GNU General Public License as
+# Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
 # published by the Free Software Foundation.
-# 
-# This program is distributed in the hope that it would be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# 
-# Further, this software is distributed without any warranty that it is
-# free of the rightful claim of any third person regarding infringement
-# or the like.  Any license provided herein, whether implied or
-# otherwise, applies only to this software file.  Patent licenses, if
-# any, provided herein do not apply to combinations of this program with
-# other software, or any other product whatsoever.
-# 
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write the Free Software Foundation, Inc., 59
-# Temple Place - Suite 330, Boston MA 02111-1307, USA.
-# 
-# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
-# Mountain View, CA  94043, or:
-# 
-# http://www.sgi.com 
-# 
-# For further information regarding this notice, see: 
-# 
-# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#
+# This program is distributed in the hope that it would be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
 #-----------------------------------------------------------------------
 #
 # creator
@@ -46,7 +31,7 @@ owner=dxm@sgi.com
 # start bit by bit to force wiping of stale blocks near the end of the
 # log. Check the block after the log ends to check for corruption
 #
-# assumptions : 
+# assumptions :
 #    - given we're only touching a single inode, the block after the
 #      log which is in the middle ag should never be touched.
 #      if it changes, we assume the log is writing over it
@@ -63,6 +48,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 
 _cleanup()
 {
+    cd /
     rm -f $tmp.*
     echo "*** unmount"
     umount $SCRATCH_MNT 2>/dev/null
@@ -78,26 +64,35 @@ _init()
     echo "*** reset partition"
     $here/src/devzero -b 2048 -n 50 -v 198 $SCRATCH_DEV
     echo "*** mkfs"
-    lsize=2097152
-    dsize=50m
-    echo mkfs_xfs -dsize=$dsize -lsize=$lsize $SCRATCH_DEV >>$seq.full
-    if ! mkfs_xfs -dsize=$dsize -lsize=$lsize $SCRATCH_DEV >>$seq.full 2>&1
-    then
-        echo "failed to mkfs $SCRATCH_DEV" >>$seq.full
-        _notrun "mkfs cannot create scratch fs, probably too small log"
-        exit 1
+    force_opts="-dsize=50m -lsize=$log_size"
+    #
+    # Do not discard blocks as we check for patterns in free space.
+    # 
+    # First, make sure that mkfs supports '-K' option by using its
+    # dry run (-N option) and then add it to the force_opts.
+    #
+    if _scratch_mkfs_xfs -N -K $force_opts >/dev/null 2>&1; then
+        force_opts="-K $force_opts"
     fi
+    echo mkfs_xfs $force_opts $SCRATCH_DEV >>$seq.full
+    _scratch_mkfs_xfs $force_opts >$tmp.mkfs0 2>&1
+    [ $? -ne 0 ] && \
+        _notrun "Cannot mkfs for this test using MKFS_OPTIONS specified"
+    _filter_mkfs <$tmp.mkfs0 >/dev/null 2>$tmp.mkfs
+    . $tmp.mkfs
+    [ $logsunit -ne 0 ] && \
+        _notrun "Cannot run this test using log MKFS_OPTIONS specified"
 }
 
 _log_traffic()
 {
     count=$1
     echo "*** generate log traffic"
-    
+
     out=$SCRATCH_MNT/$$.tmp
-    
+
     echo "   *** mount"
-    if ! mount -t xfs $SCRATCH_DEV $SCRATCH_MNT
+    if ! _scratch_mount
     then
         echo "failed to mount $SCRATCH_DEV"
         exit 1
@@ -105,18 +100,22 @@ _log_traffic()
 
     # having any quota enabled (acct/enfd) means extra log traffic - evil!
     $here/src/feature -U $SCRATCH_DEV && \
-               _notrun "Quota are enabled, test needs controlled log traffic"
+               _notrun "UQuota are enabled, test needs controlled log traffic"
     $here/src/feature -G $SCRATCH_DEV && \
-               _notrun "Quota are enabled, test needs controlled log traffic"
+               _notrun "GQuota are enabled, test needs controlled log traffic"
+    $here/src/feature -P $SCRATCH_DEV && \
+               _notrun "PQuota are enabled, test needs controlled log traffic"
+
     echo "   *** fiddle"
     while [ $count -ge 0 ]
     do
-        touch $out 
-        rm $out
-        let "count = count - 1"
+       touch $out
+       sync
+       rm $out
+       sync
+       let "count = count - 1"
     done
-    
+
     echo "   *** unmount"
     if ! umount $SCRATCH_DEV
     then
@@ -127,18 +126,30 @@ _log_traffic()
 
 _log_size()
 {
-    xfs_logprint -tb $SCRATCH_DEV | $AWK_PROG '
-        /log device/ {  print $7}
+    _scratch_xfs_logprint -tb | $AWK_PROG '
+        /log file: / || /log device: / { print $7}
     '
 }
 
 _log_head()
 {
-    xfs_logprint -tb $SCRATCH_DEV | $AWK_PROG '
+    _scratch_xfs_logprint -tb | $AWK_PROG '
         /head:/ { print $5 }
     '
 }
 
+# Get log stripe unit for v2 logs; if none specified,
+# (or v1 log) just return "1" block
+
+_log_sunit()
+{
+    if [ ${lsunit:-0} -eq 0 ]; then
+        echo $dbsize
+    else
+        expr $lsunit \* $dbsize
+    fi
+}
+
 _after_log()
 {
     xfs_db -r $1 -c "sb" -c "print" | $AWK_PROG '
@@ -155,7 +166,7 @@ _check_corrupt()
     f="c6c6c6c6"
     echo "*** check for corruption"
     echo "expect $f..." >>$seq.full
-    xfs_db -r $1 -c "fsblock $2" -c "print" | head | tee -a $seq.full | \
+    xfs_db -r -c "fsblock $2" -c "print" $1 | head | tee -a $seq.full | \
         grep -q -v "$f $f $f $f $f $f $f $f" && \
             _fail "!!! block $2 corrupted!"
 }
@@ -165,9 +176,15 @@ _check_corrupt()
 . ./common.filter
 
 # real QA test starts here
+_supported_fs xfs
+_supported_os Linux
 
 rm -f $seq.full
 
+# mkfs sizes
+log_size=2097152
+log_size_bb=`expr $log_size / 512`
+
 _require_scratch
 _init
 
@@ -175,25 +192,47 @@ block=`_after_log $SCRATCH_DEV`
 echo "fsblock after log = $block"               >>$seq.full
 _check_corrupt $SCRATCH_DEV $block
 
-size=`_log_size`
-echo "log size = $size BB"                      >>$seq.full
+actual_log_size=`_log_size`
+echo "log size = $actual_log_size BB"                      >>$seq.full
 head=`_log_head`
 echo "log position = $head"                     >>$seq.full
+lsunit=`_log_sunit`
+echo "log sunit = $lsunit"                     >>$seq.full
 
-[ $size -eq 4096 ] || \
+# sanity checks
+[ $actual_log_size -eq $log_size_bb ] || \
     _fail "!!! unexpected log size $size"
-[ $head -eq 2 ] || \
-    _fail "!!! unexpected initial log position $head"
-
-echo "    lots of traffic"                      >>$seq.full
-_log_traffic 850
+[ $head -eq 2 -o $head -eq $((lsunit/512)) ] || \
+    _fail "!!! unexpected initial log position $head vs. $((lsunit/512))"
+
+# find how how many blocks per op for 100 ops
+# ignore the fact that it will also include an unmount record etc...
+# this should be small overall
+echo "    lots of traffic for sampling" >>$seq.full
+sample_size_ops=100
+_log_traffic $sample_size_ops
+head1=`_log_head`
+num_blocks=`expr $head1 - $head`
+blocks_per_op=`echo "scale=3; $num_blocks / $sample_size_ops" | bc`
+echo "blocks_per_op = $blocks_per_op" >>$seq.full
+num_expected_ops=`echo "$log_size_bb / $blocks_per_op" | bc`
+echo "num_expected_ops = $num_expected_ops" >>$seq.full
+num_expected_to_go=`echo "$num_expected_ops - $sample_size_ops" | bc`
+echo "num_expected_to_go = $num_expected_to_go" >>$seq.full
+
+echo "    lots more traffic" >>$seq.full
+_log_traffic $num_expected_to_go
 head=`_log_head`
 echo "log position = $head"                     >>$seq.full
 
-[ $head -gt 3850 -a $head -lt 4050 ] || \
-    _fail "!!! unexpected log position $head"
+# e.g. 3891
+near_end_min=`echo "0.95 * $log_size_bb" | bc | sed 's/\..*//'`
+echo "near_end_min = $near_end_min" >>$seq.full
+
+[ $head -gt $near_end_min -a $head -lt $log_size_bb ] || \
+    _fail "!!! unexpected near end log position $head"
 
-for c in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
+for c in `seq 0 20`
 do
     echo "   little traffic"            >>$seq.full
     _log_traffic 2
@@ -203,7 +242,7 @@ do
 done
 
 [ $head -lt 1000 ] || \
-    _fail "!!! unexpected log position $head"
+    _fail "!!! unexpected wrapped log position $head"
 
 # success, all done
 status=0