defrag: add options to _defrag helper
authorDmitry Monakhov <dmonakhov@openvz.org>
Wed, 13 Aug 2014 01:16:49 +0000 (11:16 +1000)
committerDave Chinner <david@fromorbit.com>
Wed, 13 Aug 2014 01:16:49 +0000 (11:16 +1000)
Sometimes it is not easy to know number of expected extents in advance.
In that case it is reasonable to provide sane MIN and MAX values.
Also helper will check that number of extents before defragmentaion
is not greather than after.

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
common/defrag
tests/generic/018

index 732cd64006e364ac2701552d57f0e7aa70c243d4..f5e36fb25c088fe94e32ec6cdccf8ad8f147f1fd 100644 (file)
@@ -43,29 +43,114 @@ _require_defrag()
 
 _extent_count()
 {
-       $XFS_IO_PROG -c "fiemap" $1 | tail -n +2 | grep -v hole | wc -l
        $XFS_IO_PROG -c "fiemap" $1  >> $seqres.full 2>&1
+       $XFS_IO_PROG -c "fiemap" $1 | tail -n +2 | grep -v hole | wc -l| $AWK_PROG '{print $1}'
+}
+
+_check_extent_count()
+{
+       min=$1
+       max=$2
+       ext_cnt=$3
+
+       [ "$min" -gt "$ext_cnt" ] && _fail "Found $ext_cnt extents  min:$max"
+       [ "$max" -ne -1 ] && [ "$ext_cnt" -gt "$max" ] && _fail "Found $ext_cnt max: $max"
+
+       if [ $max -ne $min ]; then
+           echo "in_range($min, $max)"
+       else
+           echo "$ext_cnt"
+       fi
+       return $ext_cnt
 }
 
 # Defrag file, check it, and remove it.
 _defrag()
 {
+       min_before=0
+       max_before=-1
+       min_after=0
+       max_after=-1
+       csum=1
+       mtime=1
+
+       while [ $# -gt 1 ]
+       do
+            case $1
+               in
+               --min_before)
+                   [ -z "$2" ] && _fail "missing argument for --min_before"
+                   min_before=$2
+                   shift
+                   ;;
+               --max_before)
+                   [ -z "$2" ] && _fail "missing argument for --max_before"
+                   max_before=$2
+                   shift
+                   ;;
+               --min_after)
+                   [ -z "$2" ] && _fail "missing argument for --min_after"
+                   min_after=$2
+                   shift
+                   ;;
+               --max_after)
+                   [ -z "$2" ] && _fail "missing argument for --max_after"
+                   max_after=$2
+                   shift
+                   ;;
+               --before)
+                   [ -z "$2" ] && _fail "missing argument for --before"
+                   min_before=$2
+                   max_before=$2
+                   shift
+                   ;;
+               --after)
+                   [ -z "$2" ] && _fail "missing argument for --after"
+                   min_after=$2
+                   max_after=$2
+                   shift
+                   ;;
+               --no_csum)
+                   csum=
+                   ;;
+               --no_mtime)
+                   mtime=
+                   ;;
+               --no_unlink)
+                   no_unlink=1
+                   ;;
+               *)
+                   _fail "invalid argument to common/dump function: $1"
+                   ;;
+            esac
+           shift
+       done
+
        echo -n "Before: "
-       _extent_count $1
-       CSUM_BEFORE=`md5sum $1`
+       ext_before=$(_extent_count $1)
+       _check_extent_count $min_before $max_before $ext_before
+
+       [ ! -z $csum ] && CSUM_BEFORE=`md5sum $1`
        STAT_BEFORE=`stat -c "a: %x m: %y c: %z" $1`
        $DEFRAG_PROG -v $1 >> $seqres.full 2>&1
+
        _scratch_remount
        STAT_AFTER=`stat -c "a: %x m: %y c: %z" $1`
-       CSUM_AFTER=`md5sum $1`
+       [ ! -z $csum ] && CSUM_AFTER=`md5sum $1`
+
        echo -n "After: "
-       _extent_count $1
-       if [ "$CSUM_BEFORE" != "$CSUM_AFTER" ]; then
+       ext_after=$(_extent_count $1)
+       _check_extent_count $min_after $max_after $ext_after
+
+       [ "$ext_before" -lt "$ext_after" ] && \
+               _fail "Number of extents increased after defragmentation," \
+                     " before:$ext_before, after:$ext_after"
+       if [ ! -z $csum ] && [ "$CSUM_BEFORE" != "$CSUM_AFTER" ]; then
                _fail "file checksum changed post-defrag ($CSUM_BEFORE/$CSUM_AFTER)"
        fi
-       if [ "$STAT_BEFORE" != "$STAT_AFTER" ]; then
+       if [ ! -z $mtime ] && [ "$STAT_BEFORE" != "$STAT_AFTER" ]; then
                _fail "file timestamps changed post-defrag:\n$STAT_BEFORE\n$STAT_AFTER"
        fi
-       rm -f $1
+       [ -z $no_unlink ] && rm -f $1
 }
 
index 25443917de06b75bda508b6868179179a89fae71..2b804b55347c412983af2a58aea8f0e40235e259 100755 (executable)
@@ -60,33 +60,33 @@ rm -f $fragfile
 
 echo "zero-length file:" | tee -a $seqres.full
 touch $fragfile
-_defrag $fragfile
+_defrag --before 0 --after 0 $fragfile
 
 echo "Sparse file (no blocks):" | tee -a $seqres.full
 $XFS_IO_PROG -f -c "truncate 1m" $fragfile
-_defrag $fragfile
+_defrag --before 0 --after 0 $fragfile
 
 echo "Contiguous file:" | tee -a $seqres.full
 dd if=/dev/zero of=$fragfile bs=4k count=4 &>/dev/null
-_defrag $fragfile
+_defrag --before 1 --after 1 $fragfile
 
 echo "Write backwards sync, but contiguous - should defrag to 1 extent" | tee -a $seqres.full
 for I in `seq 9 -1 0`; do
        dd if=/dev/zero of=$fragfile bs=4k count=1 conv=notrunc seek=$I oflag=sync &>/dev/null
 done
-_defrag $fragfile
+_defrag --before 10 --after 1 $fragfile
 
 echo "Write backwards sync leaving holes - defrag should do nothing" | tee -a $seqres.full
 for I in `seq 31 -2 0`; do
        dd if=/dev/zero of=$fragfile bs=4k count=1 conv=notrunc seek=$I oflag=sync &>/dev/null
 done
-_defrag $fragfile
+_defrag --before 16 --after 16 $fragfile
 
 echo "Write forwards sync leaving holes - defrag should do nothing" | tee -a $seqres.full
 for I in `seq 0 2 31`; do
        dd if=/dev/zero of=$fragfile bs=4k count=1 conv=notrunc seek=$I oflag=sync &>/dev/null
 done
-_defrag $fragfile
+_defrag --before 16 --after 16 $fragfile
 
 rm -f $seqres.full
 status=0