2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (C) 2019 CTERA Networks. All Rights Reserved.
7 # This is a variant of overlay/017 to test constant st_ino numbers for
8 # nested overlay setup, where lower overlay layers are not on the same fs.
10 # This simple test demonstrates a known issue with overlayfs:
11 # - stat file A shows inode number X
12 # - modify A to trigger copy up
13 # - stat file A shows inode number Y != X
15 # Also test that d_ino of readdir entries and i_ino from /proc/locks are
16 # consistent with st_ino and that inode numbers persist after rename to
17 # new parent, drop caches and mount cycle.
19 # With nested xino configuration, directory st_ino is not persistent and
20 # its st_ino/d_ino/i_ino values are not consistent, so test only non-dir
24 seqres=$RESULT_DIR/$seq
25 echo "QA output created by $seq"
29 status=1 # failure is the default!
30 trap "_cleanup; exit \$status" 0 1 2 3 15
36 # Unmount the nested overlay mount
37 $UMOUNT_PROG $mnt2 2>/dev/null
40 # get standard environment, filters and checks
44 # real QA test starts here
48 _require_scratch_nocheck
49 _require_test_program "af_unix"
50 _require_test_program "t_dir_type"
51 _require_command "$FLOCK_PROG" "flock"
52 # We need to require all features together, because nfs_export cannot
53 # be enabled when index is disabled
54 _require_scratch_overlay_features index nfs_export redirect_dir
56 # Lower overlay lower layer is on test fs, upper is on scratch fs
57 lower=$OVL_BASE_TEST_MNT/$OVL_LOWER-$seq
58 upper=$OVL_BASE_SCRATCH_MNT/$OVL_UPPER
59 work=$OVL_BASE_SCRATCH_MNT/$OVL_WORK
60 # Lower dir of nested overlay is the scratch overlay mount at SCRATCH_MNT
61 upper2=$OVL_BASE_SCRATCH_DIR/$OVL_UPPER.2
62 work2=$OVL_BASE_SCRATCH_DIR/$OVL_WORK.2
63 mnt2=$OVL_BASE_SCRATCH_DIR/$OVL_MNT.2
65 lowerdir=$lower/lowertestdir
66 upperdir=$upper/uppertestdir
67 lowertestdir=$mnt2/lowertestdir
68 uppertestdir=$mnt2/uppertestdir
72 # Create the underlying overlay dirs
75 # Re-create the nested overlay upper dirs
76 rm -rf $lower $upper2 $work2 $mnt2
77 mkdir $lower $upper2 $work2 $mnt2
80 # Mount a nested overlay with $SCRATCH_MNT as lower layer
83 # Mount the underlying overlay with file handle support
84 _overlay_mount_dirs $lower $upper $work overlay1 $SCRATCH_MNT \
85 -o "index=on,nfs_export=on,xino=on" || \
86 _notrun "cannot mount overlay with xino=on option"
87 _fs_options overlay1 | grep -q "xino=on" || \
88 _notrun "cannot enable xino feature on overlay"
90 # Mount the nested overlay
91 # Enable redirect_dir for renaming a merge directory.
92 # Enabling xino in this test requires that base filesystem inode numbers will
93 # not use bit 63 in inode number of the test files, because bit 63 is used by
94 # overlayfs to indicate the layer. Let's just assume that this is true for all
95 # tested filesystems and if we are wrong, the test may fail.
96 _overlay_mount_dirs $SCRATCH_MNT $upper2 $work2 overlay2 $mnt2 \
97 -o "redirect_dir=on,index=on,xino=on" || \
98 _notrun "cannot mount nested overlay with xino=on option"
99 _fs_options overlay2 | grep -q "xino=on" || \
100 _notrun "cannot enable xino feature on nested overlay"
103 # Unmount the nested overlay mount and check underlying overlay layers
106 # unmount & check nested overlay
108 _overlay_check_dirs $SCRATCH_MNT $upper2 $work2 \
109 -o "redirect_dir=on,index=on,xino=on"
111 # unmount & check underlying overlay
112 $UMOUNT_PROG $SCRATCH_MNT
113 _overlay_check_dirs $lower $upper $work \
114 -o "index=on,nfs_export=on"
117 FILES="file symlink link chrdev blkdev fifo socket"
123 # Create our test files.
126 ln -s $dir/file $dir/symlink
128 ln $dir/link $dir/link2
129 mknod $dir/chrdev c 1 1
130 mknod $dir/blkdev b 1 1
132 $here/src/af_unix $dir/socket
135 # Record inode numbers in format <ino> <basename>
136 record_inode_numbers()
141 echo "record_inode_numbers $outfile" >> $seqres.full
146 while read ino file; do
148 echo $ino $f | tee -a $seqres.full >> $outfile
149 # /proc/locks exposes i_ino - compare it to st_ino. flock -n
150 # doesn't follow symlink, blocks on fifo and fails on socket
151 [[ $f =~ fifo|socket|symlink ]] || \
152 $FLOCK_PROG -n $file cat /proc/locks | tee -a $seqres.full | grep -q ":$ino " || \
153 echo "lock for $f not found by ino $ino ($outfile) - see $seqres.full"
157 # Check inode numbers match recorder inode numbers
158 check_inode_numbers()
164 record_inode_numbers $dir $after
166 # Test constant stat(2) st_ino -
167 # Compare before..after - expect silence
168 # We use diff -u so out.bad will tell us which stage failed
169 diff -u $before $after
171 # Test constant readdir(3)/getdents(2) d_ino -
172 # Expect to find file by inode number
173 cat $before | while read ino f; do
174 $here/src/t_dir_type $dir $ino | tee -a $seqres.full | grep -q $f || \
175 echo "$f not found by ino $ino (from $before) - see $seqres.full"
183 create_test_files $lowerdir
184 create_test_files $upperdir
188 # Record inode numbers in the lower overlay
189 record_inode_numbers $SCRATCH_MNT/lowertestdir $tmp.lower.lo
190 record_inode_numbers $SCRATCH_MNT/uppertestdir $tmp.lower.up
192 # Compare inode numbers in lower overlay vs. nested overlay
193 # With nested xino lower/lower, all inode numbers overflow xino bits and
194 # d_ino/i_ino in nested overlay are the same as in lower overlay.
195 check_inode_numbers $lowertestdir $tmp.lower.lo $tmp.before.lo
197 # Record inode numbers before copy up from nested upper
198 record_inode_numbers $uppertestdir $tmp.before.up
202 # chown -h modifies all those file types
203 chown -h 100 $lowertestdir/$f
204 chown -h 100 $uppertestdir/$f
207 # Compare inode numbers before/after copy up
208 check_inode_numbers $lowertestdir $tmp.before.lo $tmp.after_copyup.lo
209 check_inode_numbers $uppertestdir $tmp.before.up $tmp.after_copyup.up
211 # Move all files to another dir
212 mkdir $lowertestdir.2 $uppertestdir.2
215 mv $lowertestdir/$f $lowertestdir.2/
216 mv $uppertestdir/$f $uppertestdir.2/
219 echo 3 > /proc/sys/vm/drop_caches
221 # Compare inode numbers before/after rename and drop caches
222 check_inode_numbers $lowertestdir.2 $tmp.after_copyup.lo $tmp.after_move.lo
223 check_inode_numbers $uppertestdir.2 $tmp.after_copyup.up $tmp.after_move.up
225 # Verify that the inode numbers survive a mount cycle
229 # Compare inode numbers before/after mount cycle
230 check_inode_numbers $lowertestdir.2 $tmp.after_move.lo $tmp.after_cycle.lo
231 check_inode_numbers $uppertestdir.2 $tmp.after_move.up $tmp.after_cycle.up
235 echo "Silence is golden"