summaryrefslogtreecommitdiff
path: root/tests/generic/635
blob: 198278c4328560ee701d221362cc4bffd6e1b5fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (c) 2021 Oracle.  All Rights Reserved.
#
# FS QA Test No. 635
#
# Make sure we can store and retrieve timestamps on the extremes of the
# date ranges supported by userspace, and the common places where overflows
# can happen.  This test also ensures that the timestamps are persisted
# correctly after a shutdown.
#
# This differs from generic/402 in that we don't constrain ourselves to the
# range that the filesystem claims to support; we attempt various things that
# /userspace/ can parse, and then check that the vfs clamps and persists the
# values correctly.
#
# NOTE: Old kernels (pre 5.4) allow filesystems to truncate timestamps silently
# when writing timestamps to disk!  This test detects this silent truncation
# and fails.  If you see a failure on such a kernel, contact your distributor
# for an update.

. ./common/preamble
_begin_fstest auto quick atime bigtime shutdown

# Import common functions.

# real QA test starts here
_supported_fs generic
_require_scratch
_require_scratch_shutdown

_scratch_mkfs > $seqres.full
_scratch_mount

# Does our userspace even support large dates?
test_bigdates=1
touch -d 'May 30 01:53:03 UTC 2514' $SCRATCH_MNT 2>/dev/null || test_bigdates=0

# And can we do statx?
test_statx=1
($XFS_IO_PROG -c 'help statx' | grep -q 'Print raw statx' && \
 $XFS_IO_PROG -c 'statx -r' $SCRATCH_MNT 2>/dev/null | grep -q 'stat.mtime') || \
	test_statx=0

echo "Userspace support of large timestamps: $test_bigdates" >> $seqres.full
echo "xfs_io support of statx: $test_statx" >> $seqres.full

touchme() {
	local arg="$1"
	local name="$2"

	echo "$arg" > $SCRATCH_MNT/t_$name
	touch -d "$arg" $SCRATCH_MNT/t_$name
}

report() {
	local files=($SCRATCH_MNT/t_*)
	for file in "${files[@]}"; do
		echo "${file}: $(cat "${file}")"
		TZ=UTC stat -c '%y %Y %n' "${file}"
		test $test_statx -gt 0 && \
			$XFS_IO_PROG -c 'statx -r' "${file}" | grep 'stat.mtime'
	done
}

# -2147483648 (S32_MIN, or classic unix min)
touchme 'Dec 13 20:45:52 UTC 1901' s32_min

# 2147483647 (S32_MAX, or classic unix max)
touchme 'Jan 19 03:14:07 UTC 2038' s32_max

# 7956915742, all twos
touchme 'Feb 22 22:22:22 UTC 2222' all_twos

if [ $test_bigdates -gt 0 ]; then
	# 16299260424 (u64 nsec counter from s32_min, like xfs does)
	touchme 'Tue Jul  2 20:20:24 UTC 2486' u64ns_from_s32_min

	# 15032385535 (u34 time if you start from s32_min, like ext4 does)
	touchme 'May 10 22:38:55 UTC 2446' u34_from_s32_min

	# 17179869183 (u34 time if you start from the unix epoch)
	touchme 'May 30 01:53:03 UTC 2514' u34_max

	# Latest date we can synthesize(?)
	touchme 'Dec 31 23:59:59 UTC 2147483647' abs_max_time

	# Earliest date we can synthesize(?)
	touchme 'Jan 1 00:00:00 UTC 0' abs_min_time
fi

# Query timestamps from incore
echo before >> $seqres.full
report > $tmp.before_crash
cat $tmp.before_crash >> $seqres.full

_scratch_shutdown -f
_scratch_cycle_mount

# Query timestamps from disk
echo after >> $seqres.full
report > $tmp.after_crash
cat $tmp.after_crash >> $seqres.full

# Did they match?
cmp -s $tmp.before_crash $tmp.after_crash

# success, all done
status=0
exit