generic/003: ensure time changes between stat calls
authorDave Chinner <dchinner@redhat.com>
Thu, 13 Mar 2014 03:58:24 +0000 (14:58 +1100)
committerDave Chinner <david@fromorbit.com>
Thu, 13 Mar 2014 03:58:24 +0000 (14:58 +1100)
On a fast device like a ramdisk, kernel time may not have changed
between a stat of a file and some operation on it immediately
afterwards. Hence there is no guarantee that an operation actually
changes the timestamps of a file immediately after it is stat'd.

Hence, ensure that the times will change by sleeping for a second
between the initial stat that reads the timestamps and the
operations that is supposed to modify them. This way we ensure that
the timestamp will change if the filesystem is correctly
implemented.

While there, fix the indenting to be 8 space tabs and correct the
header which is missing the bash shell declaration and the test
number identifier.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
tests/generic/003

index 3a11ab36b740d8cb74f96776ea3f69c10bd02745..5c2d383703c487fac7e1facf437f12dc47223916 100755 (executable)
@@ -1,3 +1,6 @@
+#! /bin/bash
+# FS QA Test No. generic/003
+#
 # Tests the noatime, relatime, strictatime and nodiratime mount options.
 # There is an extra check for Btrfs to ensure that the access time is
 # never updated on read-only subvolumes. (Regression test for bug fixed
 # Tests the noatime, relatime, strictatime and nodiratime mount options.
 # There is an extra check for Btrfs to ensure that the access time is
 # never updated on read-only subvolumes. (Regression test for bug fixed
@@ -49,41 +52,40 @@ _require_relatime
 rm -f $seqres.full
 
 _stat() {
 rm -f $seqres.full
 
 _stat() {
-    stat --printf="%x;%y;%z" $1
+       stat --printf="%x;%y;%z" $1
 }
 
 _compare_stat_times() {
 }
 
 _compare_stat_times() {
-    updated=$1      # 3 chars indicating if access, modify and
-                    # change times should be updated (Y) or not (N)
-    IFS=';' read -a first_stat <<< "$2"   # Convert first stat to array
-    IFS=';' read -a second_stat <<< "$3"  # Convert second stat to array
-    test_step=$4    # Will be printed to output stream in case of an
-                    # error, to make debugging easier
-    types=( access modify change )
-
-    for i in 0 1 2; do
-        if [ "${first_stat[$i]}" == "${second_stat[$i]}" ]; then
-            if [ "${updated:$i:1}" == "Y" ]; then
-                echo -n "ERROR: ${types[$i]} time has not been updated "
-                echo $test_step
-            fi
-        else
-            if [ "${updated:$i:1}" == "N" ]; then
-                echo -n "ERROR: ${types[$i]} time has changed "
-                echo $test_step
-            fi
-        fi
-    done
+       updated=$1      # 3 chars indicating if access, modify and
+                       # change times should be updated (Y) or not (N)
+       IFS=';' read -a first_stat <<< "$2"   # Convert first stat to array
+       IFS=';' read -a second_stat <<< "$3"  # Convert second stat to array
+       test_step=$4    # Will be printed to output stream in case of an
+                       # error, to make debugging easier
+       types=( access modify change )
+
+       for i in 0 1 2; do
+               if [ "${first_stat[$i]}" == "${second_stat[$i]}" ]; then
+                       if [ "${updated:$i:1}" == "N" ]; then
+                               continue;
+                       fi
+                       echo -n "ERROR: ${types[$i]} time has not been updated "
+                       echo $test_step
+               elif [ "${updated:$i:1}" == "N" ]; then
+                       echo -n "ERROR: ${types[$i]} time has changed "
+                       echo $test_step
+               fi
+       done
 }
 
 _scratch_mkfs >> $seqres.full 2>&1 || _fail "mkfs failed"
 _scratch_mount "-o relatime"
 
 if [ "$FSTYP" = "btrfs" ]; then
 }
 
 _scratch_mkfs >> $seqres.full 2>&1 || _fail "mkfs failed"
 _scratch_mount "-o relatime"
 
 if [ "$FSTYP" = "btrfs" ]; then
-    TPATH=$SCRATCH_MNT/sub1
-    $BTRFS_UTIL_PROG subvolume create $TPATH > $seqres.full
+       TPATH=$SCRATCH_MNT/sub1
+       $BTRFS_UTIL_PROG subvolume create $TPATH > $seqres.full
 else
 else
-    TPATH=$SCRATCH_MNT
+       TPATH=$SCRATCH_MNT
 fi
 
 mkdir $TPATH/dir1
 fi
 
 mkdir $TPATH/dir1
@@ -91,62 +93,69 @@ echo "aaa" > $TPATH/dir1/file1
 file1_stat_before_first_access=`_stat $TPATH/dir1/file1`
 
 # Accessing file1 the first time
 file1_stat_before_first_access=`_stat $TPATH/dir1/file1`
 
 # Accessing file1 the first time
+sleep 1
 cat $TPATH/dir1/file1 > /dev/null
 file1_stat_after_first_access=`_stat $TPATH/dir1/file1`
 _compare_stat_times YNN "$file1_stat_before_first_access" \
 cat $TPATH/dir1/file1 > /dev/null
 file1_stat_after_first_access=`_stat $TPATH/dir1/file1`
 _compare_stat_times YNN "$file1_stat_before_first_access" \
-    "$file1_stat_after_first_access" "after accessing file1 first time"
+       "$file1_stat_after_first_access" "after accessing file1 first time"
 
 # Accessing file1 a second time
 
 # Accessing file1 a second time
+sleep 1
 cat $TPATH/dir1/file1 > /dev/null
 file1_stat_after_second_access=`_stat $TPATH/dir1/file1`
 _compare_stat_times NNN "$file1_stat_after_first_access" \
 cat $TPATH/dir1/file1 > /dev/null
 file1_stat_after_second_access=`_stat $TPATH/dir1/file1`
 _compare_stat_times NNN "$file1_stat_after_first_access" \
-    "$file1_stat_after_second_access" "after accessing file1 second time"
+       "$file1_stat_after_second_access" "after accessing file1 second time"
 
 # Remounting with nodiratime option
 _scratch_unmount
 _scratch_mount "-o nodiratime"
 file1_stat_after_remount=`_stat $TPATH/dir1/file1`
 _compare_stat_times NNN "$file1_stat_after_second_access" \
 
 # Remounting with nodiratime option
 _scratch_unmount
 _scratch_mount "-o nodiratime"
 file1_stat_after_remount=`_stat $TPATH/dir1/file1`
 _compare_stat_times NNN "$file1_stat_after_second_access" \
-    "$file1_stat_after_remount" "for file1 after remount"
+       "$file1_stat_after_remount" "for file1 after remount"
 
 # Creating dir2 and file2, checking directory stats
 mkdir $TPATH/dir2
 dir2_stat_before_file_creation=`_stat $TPATH/dir2`
 
 # Creating dir2 and file2, checking directory stats
 mkdir $TPATH/dir2
 dir2_stat_before_file_creation=`_stat $TPATH/dir2`
+sleep 1
 echo "bbb" > $TPATH/dir2/file2
 dir2_stat_after_file_creation=`_stat $TPATH/dir2`
 _compare_stat_times NYY "$dir2_stat_before_file_creation" \
 echo "bbb" > $TPATH/dir2/file2
 dir2_stat_after_file_creation=`_stat $TPATH/dir2`
 _compare_stat_times NYY "$dir2_stat_before_file_creation" \
-    "$dir2_stat_after_file_creation" "for dir2 after file creation"
+       "$dir2_stat_after_file_creation" "for dir2 after file creation"
 
 # Accessing file2
 file2_stat_before_first_access=`_stat $TPATH/dir2/file2`
 
 # Accessing file2
 file2_stat_before_first_access=`_stat $TPATH/dir2/file2`
+sleep 1
 cat $TPATH/dir2/file2 > /dev/null
 file2_stat_after_first_access=`_stat $TPATH/dir2/file2`
 _compare_stat_times YNN "$file2_stat_before_first_access" \
 cat $TPATH/dir2/file2 > /dev/null
 file2_stat_after_first_access=`_stat $TPATH/dir2/file2`
 _compare_stat_times YNN "$file2_stat_before_first_access" \
-    "$file2_stat_after_first_access" "after accessing file2"
+       "$file2_stat_after_first_access" "after accessing file2"
 dir2_stat_after_file_access=`_stat $TPATH/dir2`
 _compare_stat_times NNN "$dir2_stat_after_file_creation" \
 dir2_stat_after_file_access=`_stat $TPATH/dir2`
 _compare_stat_times NNN "$dir2_stat_after_file_creation" \
-    "$dir2_stat_after_file_access" "for dir2 after file access"
+       "$dir2_stat_after_file_access" "for dir2 after file access"
 
 # Remounting with noatime option, creating a file and accessing it
 _scratch_unmount
 _scratch_mount "-o noatime"
 echo "ccc" > $TPATH/dir2/file3
 file3_stat_before_first_access=`_stat $TPATH/dir2/file3`
 
 # Remounting with noatime option, creating a file and accessing it
 _scratch_unmount
 _scratch_mount "-o noatime"
 echo "ccc" > $TPATH/dir2/file3
 file3_stat_before_first_access=`_stat $TPATH/dir2/file3`
+sleep 1
 cat $TPATH/dir2/file3 > /dev/null
 file3_stat_after_first_access=`_stat $TPATH/dir2/file3`
 _compare_stat_times NNN "$file3_stat_before_first_access" \
 cat $TPATH/dir2/file3 > /dev/null
 file3_stat_after_first_access=`_stat $TPATH/dir2/file3`
 _compare_stat_times NNN "$file3_stat_before_first_access" \
-    "$file3_stat_after_first_access" "after accessing file3 first time"
+       "$file3_stat_after_first_access" "after accessing file3 first time"
 
 # Checking that the modify and change times are still updated
 file1_stat_before_modify=`_stat $TPATH/dir1/file1`
 
 # Checking that the modify and change times are still updated
 file1_stat_before_modify=`_stat $TPATH/dir1/file1`
+sleep 1
 echo "xyz" > $TPATH/dir1/file1
 file1_stat_after_modify=`_stat $TPATH/dir1/file1`
 _compare_stat_times NYY "$file1_stat_before_modify" \
 echo "xyz" > $TPATH/dir1/file1
 file1_stat_after_modify=`_stat $TPATH/dir1/file1`
 _compare_stat_times NYY "$file1_stat_before_modify" \
-    "$file1_stat_after_modify" "after modifying file1"
+       "$file1_stat_after_modify" "after modifying file1"
+sleep 1
 mv $TPATH/dir1/file1 $TPATH/dir1/file1_renamed
 file1_stat_after_change=`_stat $TPATH/dir1/file1_renamed`
 _compare_stat_times NNY "$file1_stat_after_modify" \
 mv $TPATH/dir1/file1 $TPATH/dir1/file1_renamed
 file1_stat_after_change=`_stat $TPATH/dir1/file1_renamed`
 _compare_stat_times NNY "$file1_stat_after_modify" \
-    "$file1_stat_after_change" "after changing file1"
+       "$file1_stat_after_change" "after changing file1"
 
 # Remounting with strictatime option and
 # accessing a previously created file twice
 
 # Remounting with strictatime option and
 # accessing a previously created file twice
@@ -155,30 +164,33 @@ _scratch_mount "-o strictatime"
 cat $TPATH/dir2/file3 > /dev/null
 file3_stat_after_second_access=`_stat $TPATH/dir2/file3`
 _compare_stat_times YNN "$file3_stat_after_first_access" \
 cat $TPATH/dir2/file3 > /dev/null
 file3_stat_after_second_access=`_stat $TPATH/dir2/file3`
 _compare_stat_times YNN "$file3_stat_after_first_access" \
-    "$file3_stat_after_second_access" "after accessing file3 second time"
+       "$file3_stat_after_second_access" "after accessing file3 second time"
+sleep 1
 cat $TPATH/dir2/file3 > /dev/null
 file3_stat_after_third_access=`_stat $TPATH/dir2/file3`
 _compare_stat_times YNN "$file3_stat_after_second_access" \
 cat $TPATH/dir2/file3 > /dev/null
 file3_stat_after_third_access=`_stat $TPATH/dir2/file3`
 _compare_stat_times YNN "$file3_stat_after_second_access" \
-    "$file3_stat_after_third_access" "after accessing file3 third time"
+       "$file3_stat_after_third_access" "after accessing file3 third time"
 
 # Btrfs only: Creating readonly snapshot. Access time should never
 # be updated, even when the strictatime mount option is active
 if [ "$FSTYP" = "btrfs" ]; then
 
 # Btrfs only: Creating readonly snapshot. Access time should never
 # be updated, even when the strictatime mount option is active
 if [ "$FSTYP" = "btrfs" ]; then
-    SPATH=$SCRATCH_MNT/snap1
-    btrfs subvol snapshot -r $TPATH $SPATH >> $seqres.full
-    dir2_stat_readonly_before_access=`_stat $SPATH/dir2`
-    ls $SPATH/dir2 >> $seqres.full
-    cat $SPATH/dir2/file3 >> $seqres.full
-    dir2_stat_readonly_after_access=`_stat $SPATH/dir2`
-    _compare_stat_times NNN "$dir2_stat_readonly_before_access" \
-        "$dir2_stat_readonly_after_access" "for dir in readonly subvol"
-    file3_stat_readonly_after_access=`_stat $SPATH/dir2/file3`
-    _compare_stat_times NNN "$file3_stat_after_third_access" \
-        "$file3_stat_readonly_after_access" "for file in readonly subvol"
+       SPATH=$SCRATCH_MNT/snap1
+       btrfs subvol snapshot -r $TPATH $SPATH >> $seqres.full
+       dir2_stat_readonly_before_access=`_stat $SPATH/dir2`
+       sleep 1
+       ls $SPATH/dir2 >> $seqres.full
+       cat $SPATH/dir2/file3 >> $seqres.full
+       dir2_stat_readonly_after_access=`_stat $SPATH/dir2`
+       _compare_stat_times NNN "$dir2_stat_readonly_before_access" \
+               "$dir2_stat_readonly_after_access" "for dir in readonly subvol"
+       file3_stat_readonly_after_access=`_stat $SPATH/dir2/file3`
+       _compare_stat_times NNN "$file3_stat_after_third_access" \
+               "$file3_stat_readonly_after_access" "for file in readonly subvol"
 fi
 
 # Remounting read-only. Access time should never be updated, despite the
 # strictatime mount option.
 fi
 
 # Remounting read-only. Access time should never be updated, despite the
 # strictatime mount option.
+sleep 1
 dir2_stat_before_ro_mount=`_stat $TPATH/dir2`
 file3_stat_before_ro_mount=`_stat $TPATH/dir2/file3`
 _scratch_unmount
 dir2_stat_before_ro_mount=`_stat $TPATH/dir2`
 file3_stat_before_ro_mount=`_stat $TPATH/dir2/file3`
 _scratch_unmount
@@ -187,10 +199,10 @@ ls $TPATH/dir2 > /dev/null
 cat $TPATH/dir2/file3 > /dev/null
 dir2_stat_after_ro_mount=`_stat $TPATH/dir2`
 _compare_stat_times NNN "$dir2_stat_before_ro_mount" \
 cat $TPATH/dir2/file3 > /dev/null
 dir2_stat_after_ro_mount=`_stat $TPATH/dir2`
 _compare_stat_times NNN "$dir2_stat_before_ro_mount" \
-    "$dir2_stat_after_ro_mount" "for dir in read-only filesystem"
+       "$dir2_stat_after_ro_mount" "for dir in read-only filesystem"
 file3_stat_after_ro_mount=`_stat $TPATH/dir2/file3`
 _compare_stat_times NNN "$file3_stat_before_ro_mount" \
 file3_stat_after_ro_mount=`_stat $TPATH/dir2/file3`
 _compare_stat_times NNN "$file3_stat_before_ro_mount" \
-    "$file3_stat_after_ro_mount" "for file in read-only filesystem"
+       "$file3_stat_after_ro_mount" "for file in read-only filesystem"
 
 # success, all done
 _scratch_unmount
 
 # success, all done
 _scratch_unmount