+#LU-4825
+test_311() {
+ [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.8.54) ] &&
+ skip "lustre < 2.8.54 does not contain LU-4825 fix" && return
+ [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
+
+ local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
+
+ mkdir -p $DIR/$tdir
+ $SETSTRIPE -i 0 -c 1 $DIR/$tdir
+ createmany -o $DIR/$tdir/$tfile. 1000
+
+ # statfs data is not real time, let's just calculate it
+ old_iused=$((old_iused + 1000))
+
+ local count=$(do_facet $SINGLEMDS "lctl get_param -n \
+ osp.*OST0000*MDT0000.create_count")
+ local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
+ osp.*OST0000*MDT0000.max_create_count")
+ for idx in $(seq $MDSCOUNT); do
+ do_facet mds$idx "lctl set_param -n \
+ osp.*OST0000*MDT000?.max_create_count=0"
+ done
+
+ $SETSTRIPE -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
+ local index=$($GETSTRIPE -i $DIR/$tdir/$tfile)
+ [ $index -ne 0 ] || error "$tfile stripe index is 0"
+
+ unlinkmany $DIR/$tdir/$tfile. 1000
+
+ for idx in $(seq $MDSCOUNT); do
+ do_facet mds$idx "lctl set_param -n \
+ osp.*OST0000*MDT000?.max_create_count=$max_count"
+ do_facet mds$idx "lctl set_param -n \
+ osp.*OST0000*MDT000?.create_count=$count"
+ done
+
+ local new_iused
+ for i in $(seq 120); do
+ new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
+ # system may be too busy to destroy all objs in time, use
+ # a somewhat small value to not fail autotest
+ [ $((old_iused - new_iused)) -gt 400 ] && break
+ sleep 1
+ done
+
+ echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
+ [ $((old_iused - new_iused)) -gt 400 ] ||
+ error "objs not destroyed after unlink"
+}
+run_test 311 "disable OSP precreate, and unlink should destroy objs"
+
+zfs_oid_to_objid()
+{
+ local ost=$1
+ local objid=$2
+
+ local vdevdir=$(dirname $(facet_vdevice $ost))
+ local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
+ local zfs_zapid=$(do_facet $ost $cmd |
+ grep -w "/O/0/d$((objid%32))" -C 5 |
+ awk '/Object/{getline; print $1}')
+ local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
+ awk "/$objid = /"'{printf $3}')
+
+ echo $zfs_objid
+}
+
+zfs_object_blksz() {
+ local ost=$1
+ local objid=$2
+
+ local vdevdir=$(dirname $(facet_vdevice $ost))
+ local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
+ local blksz=$(do_facet $ost $cmd $objid |
+ awk '/dblk/{getline; printf $4}')
+
+ case "${blksz: -1}" in
+ k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
+ m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
+ *) ;;
+ esac
+
+ echo $blksz
+}
+
+test_312() { # LU-4856
+ [ $(facet_fstype ost1) = "zfs" ] ||
+ { skip "the test only applies to zfs" && return; }
+
+ local max_blksz=$(do_facet ost1 \
+ $ZFS get -p recordsize $(facet_device ost1) |
+ awk '!/VALUE/{print $3}')
+
+ # to make life a little bit easier
+ $LFS mkdir -c 1 -i 0 $DIR/$tdir
+ $LFS setstripe -c 1 -i 0 $DIR/$tdir
+
+ local tf=$DIR/$tdir/$tfile
+ touch $tf
+ local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
+
+ # Get ZFS object id
+ local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
+
+ # block size change by sequential over write
+ local blksz
+ for ((bs=4096; bs <= max_blksz; bs <<= 2)); do
+ dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
+
+ blksz=$(zfs_object_blksz ost1 $zfs_objid)
+ [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
+ done
+ rm -f $tf
+
+ # block size change by sequential append write
+ dd if=/dev/zero of=$tf bs=4K count=1 oflag=sync conv=notrunc
+ oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
+ zfs_objid=$(zfs_oid_to_objid ost1 $oid)
+
+ for ((count = 1; count < $((max_blksz / 4096)); count *= 2)); do
+ dd if=/dev/zero of=$tf bs=4K count=$count seek=$count \
+ oflag=sync conv=notrunc
+
+ blksz=$(zfs_object_blksz ost1 $zfs_objid)
+ blksz=$((blksz / 8192)) # in 2*4K unit
+ [ $blksz -eq $count ] ||
+ error "blksz error(in 8k): $blksz, expected: $count"
+ done
+ rm -f $tf
+
+ # random write
+ touch $tf
+ oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
+ zfs_objid=$(zfs_oid_to_objid ost1 $oid)
+
+ dd if=/dev/zero of=$tf bs=8K count=1 oflag=sync conv=notrunc
+ blksz=$(zfs_object_blksz ost1 $zfs_objid)
+ [ $blksz -eq 8192 ] || error "blksz error: $blksz, expected: 8k"
+
+ dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
+ blksz=$(zfs_object_blksz ost1 $zfs_objid)
+ [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
+
+ dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
+ blksz=$(zfs_object_blksz ost1 $zfs_objid)
+ [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
+}
+run_test 312 "make sure ZFS adjusts its block size by write pattern"
+
+test_313() {
+ local file=$DIR/$tfile
+ rm -f $file
+ $SETSTRIPE -c 1 -i 0 $file || error "setstripe failed"
+
+ # define OBD_FAIL_TGT_RCVD_EIO 0x720
+ do_facet ost1 "$LCTL set_param fail_loc=0x720"
+ dd if=/dev/zero of=$file bs=4096 oflag=direct count=1 &&
+ error "write should failed"
+ do_facet ost1 "$LCTL set_param fail_loc=0"
+ rm -f $file
+}
+run_test 313 "io should fail after last_rcvd update fail"
+
+test_fake_rw() {
+ local read_write=$1
+ if [ "$read_write" = "write" ]; then
+ local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
+ elif [ "$read_write" = "read" ]; then
+ local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
+ else
+ error "argument error"
+ fi
+
+ # turn off debug for performance testing
+ local saved_debug=$($LCTL get_param -n debug)
+ $LCTL set_param debug=0
+
+ $SETSTRIPE -c 1 -i 0 $DIR/$tfile
+
+ # get ost1 size - lustre-OST0000
+ local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
+ local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
+ [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
+
+ if [ "$read_write" = "read" ]; then
+ truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
+ fi
+
+ local start_time=$(date +%s.%N)
+ $dd_cmd bs=1M count=$blocks oflag=sync ||
+ error "real dd $read_write error"
+ local duration=$(bc <<< "$(date +%s.%N) - $start_time")
+
+ if [ "$read_write" = "write" ]; then
+ rm -f $DIR/$tfile
+ fi
+
+ # define OBD_FAIL_OST_FAKE_RW 0x238
+ do_facet ost1 $LCTL set_param fail_loc=0x238
+
+ local start_time=$(date +%s.%N)
+ $dd_cmd bs=1M count=$blocks oflag=sync ||
+ error "fake dd $read_write error"
+ local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
+
+ if [ "$read_write" = "write" ]; then
+ # verify file size
+ cancel_lru_locks osc
+ $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
+ error "$tfile size not $blocks MB"
+ fi
+ do_facet ost1 $LCTL set_param fail_loc=0
+
+ echo "fake $read_write $duration_fake vs. normal $read_write" \
+ "$duration in seconds"
+ [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
+ error_not_in_vm "fake write is slower"
+
+ $LCTL set_param -n debug="$saved_debug"
+ rm -f $DIR/$tfile
+}
+test_399a() { # LU-7655 for OST fake write
+ test_fake_rw write
+}
+run_test 399a "fake write should not be slower than normal write"
+
+
+test_399b() { # LU-8726 for OST fake read
+ if [ "$(facet_fstype ost1)" != "ldiskfs" ]; then
+ skip "only for ldiskfs" && return 0
+ fi
+ test_fake_rw read
+}
+run_test 399b "fake read should not be slower than normal read"
+