On 09/15/15 17:39, Jun'ichi Nomura wrote: >> However if admins run a command such as sync or fsfreeze along side, >> fsync/fdatasync may return success even if writeback has failed. >> That could lead to data corruption. > > For reproducing the problem, compile the attached C program (iogen.c) > and run with 'runtest.sh' script in the next mail: > # gcc -o iogen iogen.c > # bash ./runtest.sh -- cut here -- #!/bin/bash # preparation for hwpoison injection export KERNEL_SRC=/lib/modules/$(uname -r)/build [ -d "$KERNEL_SRC" ] || exit 1 # no kernel source given make vm -C $KERNEL_SRC/tools || exit 1 # tools/vm failed to build pagetypes=$KERNEL_SRC/tools/vm/page-types [ -x $pagetypes ] || exit 1 modprobe hwpoison-inject # ------------------------------------------------------------------- fstype=ext4 # file name of loopback image loopfile=test.img imgsize=16M lodev=/dev/loop0 # filesystem to use mkfs=mkfs.$fstype # device-mapper map name testmap=testmap # file name to store device-mapper table data mapok=testmap.ok maperr=testmap.err # mount point and file name used for testing testdir=/mnt/test testfile=$testdir/x # test file size filesize=16384 # ------------------------------------------------------------------- # Set up # endtest() { sleep 3 umount $testdir dmsetup remove $testmap losetup -d $lodev exit } # Create loopback device for testing dd if=/dev/zero of=$loopfile bs=$imgsize count=1 losetup $lodev $loopfile || endtest if [ ! -b $lodev ]; then endtest fi # Layer DM device for error injection echo "0 $(blockdev --getsz $lodev) linear $lodev 0" | dmsetup create $testmap dmsetup table $testmap > $mapok || endtest if [ ! -b /dev/mapper/$testmap ]; then endtest fi # Mount and create target file mkdir -p $testdir $mkfs /dev/mapper/$testmap mount /dev/mapper/$testmap $testdir || endtest dd if=/dev/zero of=$testfile bs=$filesize count=1 oflag=direct || endtest # Find physical location of the target file find_location() { # pick up physical block number of file offset 0 filefrag -v $1 | \ awk '$1 == "0" {print $3} $1 == "0:" {print $4}' | \ sed 's/\.//g' } filefrag -v $testfile block=$(find_location $testfile) if [ -z "$block" ]; then endtest fi blocksize=$(stat -c %s -f $testfile) secsize=512 sector=$((block * blocksize / secsize + 1)) # Create error mapping: inject error at $sector next=$((sector + 1)) total=$(blockdev --getsz $lodev) remainder=$((total - next)) cat <<EOF > $maperr 0 $sector linear $lodev 0 $sector 1 error $next $remainder linear $lodev $next EOF map_replace() { cat $1 | dmsetup load $testmap dmsetup suspend --nolockfs $testmap dmsetup resume $testmap } inject_memory_error() { local pfn=0x$($pagetypes -f $testfile -Nl | grep ^1$'\t' | cut -f2) [ "$pfn" = 0x ] && return 1 # target pfn not found $pagetypes -a $pfn -X -N } # ------------------------------------------------------------------- # Test # msg() { echo $* > /dev/kmsg echo $* } injector_ioerr_nop() { # start read x msg "TEST: $fstype / ioerr / (no admin action)" # inject read x msg "(admin): Injecting I/O error" map_replace $maperr msg "(admin): Do nothing" # remove read x map_replace $mapok # end read x umount /dev/mapper/$testmap || endtest mount /dev/mapper/$testmap $testdir || endtest } injector_ioerr_synccmd() { # start read x msg "TEST: $fstype / ioerr / sync-command" # inject read x msg "(admin): Injecting I/O error" map_replace $maperr msg "(admin): Calling sync(2)" sync # remove read x map_replace $mapok # end read x umount /dev/mapper/$testmap || endtest mount /dev/mapper/$testmap $testdir || endtest } injector_hwpoison_synccmd() { # start read x msg "TEST: $fstype / memory-error / sync-command" # inject read x msg "(admin): Injecting memory error" inject_memory_error msg "(admin): Calling sync(2)" sync # remove read x # end read x umount /dev/mapper/$testmap || endtest mount /dev/mapper/$testmap $testdir || endtest } msg '============' ./iogen $testfile $filesize | injector_ioerr_nop msg '============' ./iogen $testfile $filesize | injector_ioerr_synccmd msg '============' ./iogen $testfile $filesize | injector_hwpoison_synccmd # ------------------------------------------------------------------- # Clean up # endtest -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href