1#!/bin/bash
2
3# This is the script that was used to create the image.gz in this directory.
4
5set -e -u
6
7BLOCKSIZE=4096
8
9do_debugfs() {
10	umount mnt
11	debugfs -w "$@" image
12	mount image mnt
13}
14
15do_tune2fs() {
16	umount mnt
17	tune2fs $@ image
18	mount image mnt
19}
20
21symlink() {
22	local len=$1
23	local src=$2
24	local target=$(perl -e 'print "A" x '$len)
25	ln -s $target $src
26	stat -c %i $src
27}
28
29# Overwrite the length in the header of the encrypted symlink target
30set_encrypted_symlink_len() {
31	local ino=$1
32	local len=$2
33
34	echo "zap_block -f <$ino> -p $((len%256)) -o 0 -l 1 0"
35	echo "zap_block -f <$ino> -p $((len/256)) -o 1 -l 1 0"
36}
37
38create_symlinks() {
39	local dir=$1
40	local encrypted=${2:-false}
41	local overhead=0
42	local ino
43
44	if $encrypted; then
45		overhead=2
46	fi
47
48	mkdir -p $dir
49
50	{
51	ino=$(symlink 1 $dir/empty)
52	echo "set_inode_field <$ino> i_size 10"
53	echo "set_inode_field <$ino> block[0] 0"
54
55	symlink 1 $dir/fast_min > /dev/null
56
57	ino=$(symlink 10 $dir/fast_isize_too_small)
58	echo "set_inode_field <$ino> i_size 1"
59
60	ino=$(symlink 10 $dir/fast_isize_too_large)
61	echo "set_inode_field <$ino> i_size 20"
62
63	symlink $((59 - overhead)) $dir/fast_max > /dev/null
64
65	symlink $((60 - overhead)) $dir/slow_min > /dev/null
66
67	ino=$(symlink 100 $dir/slow_isize_too_small)
68	echo "set_inode_field <$ino> i_size 80"
69
70	ino=$(symlink 100 $dir/slow_isize_too_large)
71	echo "set_inode_field <$ino> i_size 120"
72
73	symlink $((BLOCKSIZE - 1 - overhead)) $dir/slow_max > /dev/null
74
75	ino=$(symlink $((BLOCKSIZE - 1 - overhead)) $dir/one_too_long)
76	echo "set_inode_field <$ino> i_size $BLOCKSIZE"
77	echo "zap_block -f <$ino> -p 65 0"
78	if $encrypted; then
79		set_encrypted_symlink_len $ino $((BLOCKSIZE - overhead))
80	fi
81
82	ino=$(symlink $((BLOCKSIZE - 1 - overhead)) $dir/too_long)
83	echo "set_inode_field <$ino> i_size $((BLOCKSIZE + 1000))"
84	echo "zap_block -f <$ino> -p 65 0"
85	if $encrypted; then
86		set_encrypted_symlink_len $ino $((BLOCKSIZE + 1000 - overhead))
87	fi
88
89	} >> debugfs_commands
90	do_debugfs < debugfs_commands
91}
92
93create_encrypted_symlinks() {
94	local dir=$1 link
95
96	mkdir $dir
97	echo | e4crypt add_key $dir
98	create_symlinks $dir true
99
100	# Move symlinks into an unencrypted directory (leaving their targets
101	# encrypted).  This makes the fsck output consistent.
102	mv $dir ${dir}~encrypted
103	mkdir $dir
104	mv ${dir}~encrypted/* $dir
105}
106
107mkdir -p mnt
108umount mnt &> /dev/null || true
109dd if=/dev/zero of=image bs=1024 count=600
110
111mke2fs -O 'encrypt,^extents,^64bit' -b $BLOCKSIZE -I 256 image
112mount image mnt
113
114create_symlinks mnt/default
115create_encrypted_symlinks mnt/encrypted
116
117do_tune2fs -O extents
118create_symlinks mnt/extents
119create_encrypted_symlinks mnt/extents_encrypted
120
121do_debugfs -R 'feature inline_data'
122create_symlinks mnt/inline_data
123
124rm -rf debugfs_commands mnt/*~encrypted
125umount mnt
126rmdir mnt
127gzip -9 -f image
128