Whamcloud - gitweb
LU-9516 tests: fix sanity test_24v
[fs/lustre-release.git] / lustre / tests / sanity.sh
index 266600a..feff64f 100755 (executable)
@@ -59,8 +59,8 @@ fi
 if [[ $(uname -m) = aarch64 ]]; then
        # bug number:    LU-11596
        ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
-       # bug number:    LU-11671 LU-11667
-       ALWAYS_EXCEPT+=" 45       317"
+       # bug number:    LU-11671
+       ALWAYS_EXCEPT+=" 45"
        # bug number:    LU-14067 LU-14067
        ALWAYS_EXCEPT+=" 400a     400b"
 fi
@@ -77,8 +77,8 @@ if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
        ALWAYS_EXCEPT+=" 411"
 fi
 
-#                                  5              12     8   12  (min)"
-[ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 300o"
+#                                  5              12     8   12  15   (min)"
+[ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
 
 if [ "$mds1_FSTYPE" = "zfs" ]; then
        # bug number for skipped test:
@@ -1184,12 +1184,15 @@ test_24u() { # bug12192
 run_test 24u "create stripe file"
 
 simple_cleanup_common() {
+       local createmany=$1
        local rc=0
-       trap 0
-       [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
+
+       [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
 
        local start=$SECONDS
-       rm -rf $DIR/$tdir
+
+       [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
+       rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
        rc=$?
        wait_delete_completed
        echo "cleanup time $((SECONDS - start))"
@@ -1213,10 +1216,10 @@ test_24v() {
        test_mkdir "$(dirname $fname)"
        # assume MDT0000 has the fewest inodes
        local stripes=$($LFS getdirstripe -c $(dirname $fname))
-       local free_inodes=$(($(mdt_free_inodes 0) * stripes))
+       local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
        [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
 
-       trap simple_cleanup_common EXIT
+       stack_trap "simple_cleanup_common $nrfiles"
 
        createmany -m "$fname" $nrfiles
 
@@ -1245,12 +1248,10 @@ test_24v() {
        local rpc_pages=$(max_pages_per_rpc $mdt_idx)
        local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
        local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
-       echo "readpages: $mds_readpage rpc_max: $rpc_max"
-       (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
+       echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
+       (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
                error "large readdir doesn't take effect: " \
                      "$mds_readpage should be about $rpc_max"
-
-       simple_cleanup_common
 }
 run_test 24v "list large directory (test hash collision, b=17560)"
 
@@ -1359,19 +1360,15 @@ run_test 24z "cross-MDT rename is done as cp"
 test_24A() { # LU-3182
        local NFILES=5000
 
-       rm -rf $DIR/$tdir
        test_mkdir $DIR/$tdir
-       trap simple_cleanup_common EXIT
+       stack_trap "simple_cleanup_common $NFILES"
        createmany -m $DIR/$tdir/$tfile $NFILES
        local t=$(ls $DIR/$tdir | wc -l)
        local u=$(ls $DIR/$tdir | sort -u | wc -l)
        local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
-       if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
-          [ $v -ne $((NFILES + 2)) ] ; then
-               error "Expected $NFILES files, got $t ($u unique $v .&..)"
-       fi
 
-       simple_cleanup_common || error "Can not delete directories"
+       (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
+               error "Expected $NFILES files, got $t ($u unique $v .&..)"
 }
 run_test 24A "readdir() returns correct number of entries."
 
@@ -1816,7 +1813,7 @@ test_27m() {
        if [[ $ORIGFREE -gt $MAXFREE ]]; then
                skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
        fi
-       trap simple_cleanup_common EXIT
+       stack_trap simple_cleanup_common
        test_mkdir $DIR/$tdir
        $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
        dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
@@ -1835,8 +1832,7 @@ test_27m() {
        touch $DIR/$tdir/$tfile.$i
        [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
            awk '{print $1}'| grep -w "0") ] &&
-               error "OST0 was full but new created file still use it"
-       simple_cleanup_common
+               error "OST0 was full but new created file still use it" || true
 }
 run_test 27m "create file while OST0 was full"
 
@@ -1860,52 +1856,6 @@ reset_enospc() {
        wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
 }
 
-__exhaust_precreations() {
-       local OSTIDX=$1
-       local FAILLOC=$2
-       local FAILIDX=${3:-$OSTIDX}
-       local ofacet=ost$((OSTIDX + 1))
-
-       mkdir_on_mdt0 $DIR/$tdir
-       local mdtidx=$($LFS getstripe -m $DIR/$tdir)
-       local mfacet=mds$((mdtidx + 1))
-       echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
-
-       local OST=$(ostname_from_index $OSTIDX)
-
-       # on the mdt's osc
-       local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
-       local last_id=$(do_facet $mfacet lctl get_param -n \
-                       osp.$mdtosc_proc1.prealloc_last_id)
-       local next_id=$(do_facet $mfacet lctl get_param -n \
-                       osp.$mdtosc_proc1.prealloc_next_id)
-
-       local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
-       do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
-
-       test_mkdir -p $DIR/$tdir/${OST}
-       $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
-#define OBD_FAIL_OST_ENOSPC              0x215
-       do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
-       echo "Creating to objid $last_id on ost $OST..."
-       createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
-       do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
-       do_facet $ofacet lctl set_param fail_loc=$FAILLOC
-}
-
-exhaust_precreations() {
-       __exhaust_precreations $1 $2 $3
-       sleep_maxage
-}
-
-exhaust_all_precreations() {
-       local i
-       for (( i=0; i < OSTCOUNT; i++ )) ; do
-               __exhaust_precreations $i $1 -1
-       done
-       sleep_maxage
-}
-
 test_27n() {
        [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
        [ $PARALLEL == "yes" ] && skip "skip parallel run"
@@ -2084,15 +2034,13 @@ test_27u() { # bug 4900
 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
        do_nodes $list $LCTL set_param fail_loc=0x139
        test_mkdir -p $DIR/$tdir
-       trap simple_cleanup_common EXIT
-       createmany -o $DIR/$tdir/t- 1000
+       stack_trap "simple_cleanup_common 1000"
+       createmany -o $DIR/$tdir/$tfile 1000
        do_nodes $list $LCTL set_param fail_loc=0
 
        TLOG=$TMP/$tfile.getstripe
        $LFS getstripe $DIR/$tdir > $TLOG
        OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
-       unlinkmany $DIR/$tdir/t- 1000
-       trap 0
        [[ $OBJS -gt 0 ]] &&
                error "$OBJS objects created on OST-0. See $TLOG" ||
                rm -f $TLOG
@@ -3395,6 +3343,36 @@ test_27Q() {
 }
 run_test 27Q "llapi_file_get_stripe() works on symlinks"
 
+test_27R() {
+       (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
+               skip "need MDS 2.14.55 or later"
+       (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
+
+       local testdir="$DIR/$tdir"
+       test_mkdir -p $testdir
+       stack_trap "rm -rf $testdir"
+       $LFS setstripe -c -1 $testdir || error "setstripe failed"
+
+       local f1="$testdir/f1"
+       touch $f1 || error "failed to touch $f1"
+       local count=$($LFS getstripe -c $f1)
+       (( $count == $OSTCOUNT )) || error "wrong stripe count"
+
+       do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
+       (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
+
+       local maxcount=$(($OSTCOUNT - 1))
+       local mdts=$(comma_list $(mdts_nodes))
+       do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
+       stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
+
+       local f2="$testdir/f2"
+       touch $f2 || error "failed to touch $f2"
+       local count=$($LFS getstripe -c $f2)
+       (( $count == $maxcount )) || error "wrong stripe count"
+}
+run_test 27R "test max_stripecount limitation when stripe count is set to -1"
+
 # createtest also checks that device nodes are created and
 # then visible correctly (#2091)
 test_28() { # bug 2091
@@ -3406,6 +3384,11 @@ run_test 28 "create/mknod/mkdir with bad file types ============"
 test_29() {
        [ $PARALLEL == "yes" ] && skip "skip parallel run"
 
+       [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
+               disable_opencache
+               stack_trap "restore_opencache"
+       }
+
        sync; sleep 1; sync # flush out any dirty pages from previous tests
        cancel_lru_locks
        test_mkdir $DIR/d29
@@ -5682,38 +5665,51 @@ run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
 test_51d() {
        [ $PARALLEL == "yes" ] && skip "skip parallel run"
        [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
+       local qos_old
 
        test_mkdir $DIR/$tdir
+       $LFS setstripe -c $OSTCOUNT $DIR/$tdir
+
+       qos_old=$(do_facet mds1 \
+               "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
+       do_nodes $(comma_list $(mdts_nodes)) \
+               "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
+       stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
+               '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
+
        createmany -o $DIR/$tdir/t- 1000
        $LFS getstripe $DIR/$tdir > $TMP/$tfile
-       for N in $(seq 0 $((OSTCOUNT - 1))); do
-               OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
-                       END { printf("%0.0f", objs) }' $TMP/$tfile)
-               OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
-                       '($1 == '$N') { objs += 1 } \
-                       END { printf("%0.0f", objs) }')
-               log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
+       for ((n = 0; n < $OSTCOUNT; n++)); do
+               objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
+                          END { printf("%0.0f", objs) }' $TMP/$tfile)
+               objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
+                           '($1 == '$n') { objs += 1 } \
+                           END { printf("%0.0f", objs) }')
+               log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
        done
        unlinkmany $DIR/$tdir/t- 1000
 
-       NLAST=0
-       for N in $(seq 1 $((OSTCOUNT - 1))); do
-               [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
-                       error "OST $N has less objects vs OST $NLAST" \
-                             " (${OBJS[$N]} < ${OBJS[$NLAST]}"
-               [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
-                       error "OST $N has less objects vs OST $NLAST" \
-                             " (${OBJS[$N]} < ${OBJS[$NLAST]}"
-
-               [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
-                       error "OST $N has less #0 objects vs OST $NLAST" \
-                             " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
-               [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
-                       error "OST $N has less #0 objects vs OST $NLAST" \
-                             " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
-               NLAST=$N
+       nlast=0
+       for ((n = 0; n < $OSTCOUNT; n++)); do
+               (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
+                       { $LFS df && $LFS df -i &&
+                       error "OST $n has fewer objects vs. OST $nlast" \
+                             " (${objs[$n]} < ${objs[$nlast]}"; }
+               (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
+                       { $LFS df && $LFS df -i &&
+                       error "OST $n has fewer objects vs. OST $nlast" \
+                             " (${objs[$n]} < ${objs[$nlast]}"; }
+
+               (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
+                       { $LFS df && $LFS df -i &&
+                       error "OST $n has fewer #0 objects vs. OST $nlast" \
+                             " (${objs0[$n]} < ${objs0[$nlast]}"; }
+               (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
+                       { $LFS df && $LFS df -i &&
+                       error "OST $n has fewer #0 objects vs. OST $nlast" \
+                             " (${objs0[$n]} < ${objs0[$nlast]}"; }
+               nlast=$n
        done
-       rm -f $TMP/$tfile
 }
 run_test 51d "check object distribution"
 
@@ -8816,6 +8812,138 @@ test_64f() {
 }
 run_test 64f "check grant consumption (with grant allocation)"
 
+test_64g() {
+       #[ $MDS1_VERSION -lt $(version_code 2.14.54) ] &&
+       #       skip "Need MDS version at least 2.14.54"
+
+       local mdts=$(comma_list $(mdts_nodes))
+
+       local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
+                       tr '\n' ' ')
+       stack_trap "$LCTL set_param $old"
+
+       # generate dirty pages and increase dirty granted on MDT
+       stack_trap "rm -f $DIR/$tfile-*"
+       for (( i = 0; i < 10; i++)); do
+               $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
+                       error "can't set stripe"
+               dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
+                       error "can't dd"
+               $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
+                       $LFS getstripe $DIR/$tfile-$i
+                       error "not DoM file"
+               }
+       done
+
+       # flush dirty pages
+       sync
+
+       # wait until grant shrink reset grant dirty on MDTs
+       for ((i = 0; i < 120; i++)); do
+               grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
+                       awk '{sum=sum+$1} END {print sum}')
+               vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
+               echo "$grant_dirty grants, $vm_dirty pages"
+               (( grant_dirty + vm_dirty == 0 )) && break
+               (( i == 3 )) && sync &&
+                       $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
+               sleep 1
+       done
+
+       grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
+               awk '{sum=sum+$1} END {print sum}')
+       (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
+}
+run_test 64g "grant shrink on MDT"
+
+test_64h() {
+       local instance=$($LFS getname -i $DIR)
+       local osc_tgt="$FSNAME-OST0000-osc-$instance"
+       local num_exps=$(do_facet ost1 \
+           $LCTL get_param -n obdfilter.*OST0000*.num_exports)
+       local max_brw_size=$(import_param $osc_tgt max_brw_size)
+       local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
+       local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
+
+       # 10MiB is for file to be written, max_brw_size * 16 *
+       # num_exps is space reserve so that tgt_grant_shrink() decided
+       # to not shrink
+       local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
+       (( avail * 1024 < expect )) &&
+               skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
+
+       save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
+       save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
+       stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
+       $LCTL set_param osc.*OST0000*.grant_shrink=1
+       $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
+
+       $LFS setstripe -c 1 -i 0 $DIR/$tfile
+       dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
+
+       # drop cache so that coming read would do rpc
+       cancel_lru_locks osc
+
+       # shrink interval is set to 10, pause for 7 seconds so that
+       # grant thread did not wake up yet but coming read entered
+       # shrink mode for rpc (osc_should_shrink_grant())
+       sleep 7
+
+       declare -a cur_grant_bytes
+       declare -a tot_granted
+       cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
+       tot_granted[0]=$(do_facet ost1 \
+           $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
+
+       dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
+
+       cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
+       tot_granted[1]=$(do_facet ost1 \
+           $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
+
+       # grant change should be equal on both sides
+       (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
+               tot_granted[0] - tot_granted[1])) ||
+               error "grant change mismatch, "                                \
+                       "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
+                       "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
+}
+run_test 64h "grant shrink on read"
+
+test_64i() {
+       (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
+               skip "need OST at least 2.14.55 to avoid grant shrink on replay"
+
+       [ $PARALLEL == "yes" ] && skip "skip parallel run"
+       remote_ost_nodsh && skip "remote OSTs with nodsh"
+
+       $LFS setstripe -c 1 -i 0 $DIR/$tfile
+
+       dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
+
+       # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
+       local instance=$($LFS getname -i $DIR)
+
+       local osc_tgt="$FSNAME-OST0000-osc-$instance"
+       local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
+
+       # shrink grants and simulate rpc loss
+       #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
+       do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
+       $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
+
+       fail ost1
+
+       dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
+
+       local testid=$(echo $TESTNAME | tr '_' ' ')
+
+       do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
+               grep "GRANT, real grant" &&
+               error "client has more grants then it owns" || true
+}
+run_test 64i "shrink on reconnect"
+
 # bug 1414 - set/get directories' stripe info
 test_65a() {
        [ $PARALLEL == "yes" ] && skip "skip parallel run"
@@ -9840,6 +9968,36 @@ test_77n() {
 }
 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
 
+test_77o() {
+       (( $CLIENT_VERSION >= $(version_code 2.14.54) )) ||
+               skip "Need at least version 2.14.54"
+       local ofd=obdfilter
+       local mdt=mdt
+
+       # print OST checksum_type
+       echo "$ofd.$FSNAME-*.checksum_type:"
+       do_nodes $(comma_list $(osts_nodes)) \
+               $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
+
+       # print MDT checksum_type
+       echo "$mdt.$FSNAME-*.checksum_type:"
+       do_nodes $(comma_list $(mdts_nodes)) \
+               $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
+
+       local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
+                  $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
+
+       (( $o_count == $OSTCOUNT )) ||
+               error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
+
+       local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
+                  $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
+
+       (( $m_count == $MDSCOUNT )) ||
+               error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
+}
+run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
+
 cleanup_test_78() {
        trap 0
        rm -f $DIR/$tfile
@@ -11698,7 +11856,7 @@ test_116a() { # was previously test_116()
 
        [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
        [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
-       trap simple_cleanup_common EXIT
+       stack_trap simple_cleanup_common
 
        # Check if we need to generate uneven OSTs
        test_mkdir -p $DIR/$tdir/OST${MINI}
@@ -11743,8 +11901,6 @@ test_116a() { # was previously test_116()
        if [ $DIFF2 -gt $threshold ]; then
                echo "ok"
        else
-               echo "failed - QOS mode won't be used"
-               simple_cleanup_common
                skip "QOS imbalance criteria not met"
        fi
 
@@ -11802,7 +11958,6 @@ test_116a() { # was previously test_116()
        fi
        [[ $MAXC -gt $MINC ]] ||
                error_ignore LU-9 "stripe QOS didn't balance free space"
-       simple_cleanup_common
 }
 run_test 116a "stripe QOS: free space balance ==================="
 
@@ -15891,14 +16046,11 @@ run_test 160f "changelog garbage collect (timestamped users)"
 
 test_160g() {
        remote_mds_nodsh && skip "remote MDS with nodsh"
-       [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
-               skip "Need MDS version at least 2.10.56"
+       [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
+               skip "Need MDS version at least 2.14.55"
 
        local mdts=$(comma_list $(mdts_nodes))
 
-       #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
-       do_nodes $mdts $LCTL set_param fail_loc=0x1314
-
        # Create a user
        changelog_register || error "first changelog_register failed"
        changelog_register || error "second changelog_register failed"
@@ -15923,10 +16075,9 @@ test_160g() {
        (( $nbcl > 0 )) || error "no changelogs found"
 
        # reduce the max_idle_indexes value to make sure we exceed it
-       for param in "changelog_max_idle_indexes=1" \
+       for param in "changelog_max_idle_indexes=2" \
                     "changelog_gc=1" \
-                    "changelog_min_gc_interval=2" \
-                    "changelog_min_free_cat_entries=3"; do
+                    "changelog_min_gc_interval=2"; do
                local MDT0=$(facet_svc $SINGLEMDS)
                local var="${param%=*}"
                local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
@@ -15936,10 +16087,6 @@ test_160g() {
                        error "unable to set mdd.*.$param"
        done
 
-       # simulate changelog catalog almost full
-       #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
-       do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
-
        local start=$SECONDS
        for i in $(seq $MDSCOUNT); do
                cl_users=(${CL_USERS[mds$i]})
@@ -15947,38 +16094,37 @@ test_160g() {
                cl_user2[mds$i]="${cl_users[1]}"
 
                [ -n "${cl_user1[mds$i]}" ] ||
-                       error "mds$i: no user registered"
+                       error "mds$i: user1 is not registered"
                [ -n "${cl_user2[mds$i]}" ] ||
                        error "mds$i: only ${cl_user1[mds$i]} is registered"
 
                user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
                [ -n "$user_rec1" ] ||
-                       error "mds$i: User ${cl_user1[mds$i]} not registered"
+                       error "mds$i: user1 ${cl_user1[mds$i]} not found"
                __changelog_clear mds$i ${cl_user1[mds$i]} +2
                user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
                [ -n "$user_rec2" ] ||
-                       error "mds$i: User ${cl_user1[mds$i]} not registered"
-               echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
+                       error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
+               echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
                     "$user_rec1 + 2 == $user_rec2"
                [ $((user_rec1 + 2)) == $user_rec2 ] ||
-                       error "mds$i: user ${cl_user1[mds$i]} index expected " \
-                             "$user_rec1 + 2, but is $user_rec2"
+                       error "mds$i: user1 ${cl_user1[mds$i]} index " \
+                             "expected $user_rec1 + 2, but is $user_rec2"
                user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
                [ -n "$user_rec2" ] ||
-                       error "mds$i: User ${cl_user2[mds$i]} not registered"
+                       error "mds$i: user2 ${cl_user2[mds$i]} not found"
                [ $user_rec1 == $user_rec2 ] ||
-                       error "mds$i: user ${cl_user2[mds$i]} index expected " \
-                             "$user_rec1, but is $user_rec2"
+                       error "mds$i: user2 ${cl_user2[mds$i]} index " \
+                             "expected $user_rec1, but is $user_rec2"
        done
 
        # ensure we are past the previous changelog_min_gc_interval set above
        local sleep2=$((start + 2 - SECONDS))
        (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
-
        # Generate one more changelog to trigger GC at fail_loc for cl_user2.
        # cl_user1 should be OK because it recently processed records.
        for ((i = 0; i < MDSCOUNT; i++)); do
-               $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
+               $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
                        error "create $DIR/$tdir/d$i.3 failed"
        done
 
@@ -15992,15 +16138,15 @@ test_160g() {
        for (( i = 1; i <= MDSCOUNT; i++ )); do
                # check cl_user1 still registered
                changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
-                       error "mds$i: User ${cl_user1[mds$i]} not registered"
+                       error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
                # check cl_user2 unregistered
                changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
-                       error "mds$i: User ${cl_user2[mds$i]} still registered"
+                       error "mds$i: user2 ${cl_user2[mds$i]} is registered"
 
                # check changelogs are present and starting at $user_rec1 + 1
                user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
                [ -n "$user_rec1" ] ||
-                       error "mds$i: User ${cl_user1[mds$i]} not registered"
+                       error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
                first_rec=$($LFS changelog $(facet_svc mds$i) |
                            awk '{ print $1; exit; }')
 
@@ -16009,7 +16155,7 @@ test_160g() {
                        error "mds$i: rec $first_rec != $user_rec1 + 1"
        done
 }
-run_test 160g "changelog garbage collect (old users)"
+run_test 160g "changelog garbage collect on idle records"
 
 test_160h() {
        remote_mds_nodsh && skip "remote MDS with nodsh" && return
@@ -16585,6 +16731,89 @@ test_160q() {
 }
 run_test 160q "changelog effective mask is DEFMASK if not set"
 
+test_160s() {
+       remote_mds_nodsh && skip "remote MDS with nodsh"
+       (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
+               skip "Need MDS version at least 2.14.55"
+
+       local mdts=$(comma_list $(mdts_nodes))
+
+       #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
+       do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
+                                      fail_val=$((24 * 3600 * 10))
+
+       # Create a user which is 10 days old
+       changelog_register || error "first changelog_register failed"
+       local cl_users
+       declare -A cl_user1
+       local i
+
+       # generate some changelog records to accumulate on each MDT
+       # use all_char because created files should be evenly distributed
+       test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
+               error "test_mkdir $tdir failed"
+       for ((i = 0; i < MDSCOUNT; i++)); do
+               $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
+                       error "create $DIR/$tdir/d$i.1 failed"
+       done
+
+       # check changelogs have been generated
+       local nbcl=$(changelog_dump | wc -l)
+       (( nbcl > 0 )) || error "no changelogs found"
+
+       # reduce the max_idle_indexes value to make sure we exceed it
+       for param in "changelog_max_idle_indexes=2097446912" \
+                    "changelog_max_idle_time=2592000" \
+                    "changelog_gc=1" \
+                    "changelog_min_gc_interval=2"; do
+               local MDT0=$(facet_svc $SINGLEMDS)
+               local var="${param%=*}"
+               local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
+
+               stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
+               do_nodes $mdts $LCTL set_param mdd.*.$param ||
+                       error "unable to set mdd.*.$param"
+       done
+
+       local start=$SECONDS
+       for i in $(seq $MDSCOUNT); do
+               cl_users=(${CL_USERS[mds$i]})
+               cl_user1[mds$i]="${cl_users[0]}"
+
+               [[ -n "${cl_user1[mds$i]}" ]] ||
+                       error "mds$i: no user registered"
+       done
+
+       #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
+       do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
+
+       # ensure we are past the previous changelog_min_gc_interval set above
+       local sleep2=$((start + 2 - SECONDS))
+       (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
+
+       # Generate one more changelog to trigger GC
+       for ((i = 0; i < MDSCOUNT; i++)); do
+               $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
+                       error "create $DIR/$tdir/d$i.3 failed"
+       done
+
+       # ensure gc thread is done
+       for node in $(mdts_nodes); do
+               wait_update $node "pgrep chlg_gc_thread" "" 20 ||
+                       error "$node: GC-thread not done"
+       done
+
+       do_nodes $mdts $LCTL set_param fail_loc=0
+
+       for (( i = 1; i <= MDSCOUNT; i++ )); do
+               # check cl_user1 is purged
+               changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
+                       error "mds$i: User ${cl_user1[mds$i]} is registered"
+       done
+       return 0
+}
+run_test 160s "changelog garbage collect on idle records * time"
+
 test_161a() {
        [ $PARALLEL == "yes" ] && skip "skip parallel run"
 
@@ -18791,26 +19020,48 @@ run_test 223 "osc reenqueue if without AGL lock granted ======================="
 
 test_224a() { # LU-1039, MRP-303
        [ $PARALLEL == "yes" ] && skip "skip parallel run"
-
        #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
        $LCTL set_param fail_loc=0x508
-       dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
+       dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
        $LCTL set_param fail_loc=0
        df $DIR
 }
 run_test 224a "Don't panic on bulk IO failure"
 
-test_224b() { # LU-1039, MRP-303
+test_224bd_sub() { # LU-1039, MRP-303
        [ $PARALLEL == "yes" ] && skip "skip parallel run"
+       local timeout=$1
 
-       dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
+       shift
+       dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
+
+       $LFS setstripe -c 1 -i 0 $DIR/$tfile
+
+       dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
        cancel_lru_locks osc
+       set_checksums 0
+       stack_trap "set_checksums $ORIG_CSUM" EXIT
+       local at_max_saved=0
+
+       # adaptive timeouts may prevent seeing the issue
+       if at_is_enabled; then
+               at_max_saved=$(at_max_get mds)
+               at_max_set 0 mds client
+               stack_trap "at_max_set $at_max_saved mds client" EXIT
+       fi
+
        #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
-       $LCTL set_param fail_loc=0x515
-       dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
-       $LCTL set_param fail_loc=0
+       do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
+       dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
+
+       do_facet ost1 $LCTL set_param fail_loc=0
+       cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
        df $DIR
 }
+
+test_224b() {
+       test_224bd_sub 3 error "dd failed"
+}
 run_test 224b "Don't panic on bulk IO failure"
 
 test_224c() { # LU-6441
@@ -18851,6 +19102,11 @@ test_224c() { # LU-6441
 }
 run_test 224c "Don't hang if one of md lost during large bulk RPC"
 
+test_224d() { # LU-11169
+       test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
+}
+run_test 224d "Don't corrupt data on bulk IO timeout"
+
 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
 test_225a () {
        [ $PARALLEL == "yes" ] && skip "skip parallel run"
@@ -19530,7 +19786,7 @@ test_230d() {
                error "migrate remote dir error"
 
        echo "Finish migration, then checking.."
-       for file in $(find $migrate_dir); do
+       for file in $(find $migrate_dir -maxdepth 1); do
                mdt_index=$($LFS getstripe -m $file)
                if [ $mdt_index -lt $new_index ] ||
                   [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
@@ -20087,6 +20343,66 @@ test_230t()
 }
 run_test 230t "migrate directory with project ID set"
 
+test_230u()
+{
+       (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
+       (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
+               skip "Need MDS version at least 2.14.53"
+
+       local count
+
+       mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
+       mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
+       $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
+       for i in $(seq 0 $((MDSCOUNT - 1))); do
+               count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
+               echo "$count dirs migrated to MDT$i"
+       done
+       count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
+       (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
+}
+run_test 230u "migrate directory by QOS"
+
+test_230v()
+{
+       (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
+       (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
+               skip "Need MDS version at least 2.14.53"
+
+       local count
+
+       mkdir $DIR/$tdir || error "mkdir $tdir failed"
+       mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
+       $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
+       for i in $(seq 0 $((MDSCOUNT - 1))); do
+               count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
+               echo "$count subdirs migrated to MDT$i"
+               (( i == 3 )) && (( count > 0 )) &&
+                       error "subdir shouldn't be migrated to MDT3"
+       done
+       count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
+       (( count == 3 )) || error "dirs migrated to $count MDTs"
+}
+run_test 230v "subdir migrated to the MDT where its parent is located"
+
+test_230w() {
+       (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
+       (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
+               skip "Need MDS version at least 2.14.53"
+
+       mkdir -p $DIR/$tdir/sub || error "mkdir failed"
+
+       $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
+               error "migrate failed"
+
+       (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
+               error "$tdir stripe count mismatch"
+
+       (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
+               error "$tdir/sub is striped"
+}
+run_test 230w "non-recursive mode dir migration"
+
 test_231a()
 {
        # For simplicity this test assumes that max_pages_per_rpc
@@ -20986,18 +21302,20 @@ run_test 253 "Check object allocation limit"
 test_254() {
        [ $PARALLEL == "yes" ] && skip "skip parallel run"
        remote_mds_nodsh && skip "remote MDS with nodsh"
-       do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
+
+       local mdt=$(facet_svc $SINGLEMDS)
+
+       do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
                skip "MDS does not support changelog_size"
 
        local cl_user
-       local MDT0=$(facet_svc $SINGLEMDS)
 
        changelog_register || error "changelog_register failed"
 
        changelog_clear 0 || error "changelog_clear failed"
 
        local size1=$(do_facet $SINGLEMDS \
-                     $LCTL get_param -n mdd.$MDT0.changelog_size)
+                     $LCTL get_param -n mdd.$mdt.changelog_size)
        echo "Changelog size $size1"
 
        rm -rf $DIR/$tdir
@@ -21012,7 +21330,7 @@ test_254() {
        rm $DIR/$tdir/pics/desktop.jpg
 
        local size2=$(do_facet $SINGLEMDS \
-                     $LCTL get_param -n mdd.$MDT0.changelog_size)
+                     $LCTL get_param -n mdd.$mdt.changelog_size)
        echo "Changelog size after work $size2"
 
        (( $size2 > $size1 )) ||
@@ -21941,6 +22259,16 @@ test_270h() {
 }
 run_test 270h "DoM: DoM stripe removal when disabled on server"
 
+test_270i() {
+       (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
+               skip "Need MDS version at least 2.14.54"
+
+       mkdir $DIR/$tdir
+       $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
+               error "setstripe should fail" || true
+}
+run_test 270i "DoM: setting invalid DoM striping should fail"
+
 test_271a() {
        [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
                skip "Need MDS version at least 2.10.55"
@@ -23669,19 +23997,19 @@ test_317() {
 
        #
        # sparse file test
-       # Create file with a hole and write actual two blocks. Block count
-       # must be 16.
+       # Create file with a hole and write actual 65536 bytes which aligned
+       # with 4K and 64K PAGE_SIZE. Block count must be 128.
        #
-       dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
-               conv=fsync || error "Create file : $DIR/$tfile"
-
-       # Calculate the final truncate size.
-       trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
+       local bs=65536
+       dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
+               error "Create file : $DIR/$tfile"
 
        #
-       # truncate to size $trunc_sz bytes. Strip the last block
-       # The block count must drop to 8
+       # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
+       # blocks. The block count must drop to 8.
        #
+       trunc_sz=$(($(stat --format=%s $DIR/$tfile) - \
+               ((bs - grant_blk_size) + 1)))
        $TRUNCATE $DIR/$tfile $trunc_sz ||
                error "truncate $tfile to $trunc_sz failed"
 
@@ -24769,6 +25097,8 @@ run_test 412 "mkdir on specific MDTs"
 
 generate_uneven_mdts() {
        local threshold=$1
+       local lmv_qos_maxage
+       local lod_qos_maxage
        local ffree
        local bavail
        local max
@@ -24778,6 +25108,17 @@ generate_uneven_mdts() {
        local tmp
        local i
 
+       lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
+       $LCTL set_param lmv.*.qos_maxage=1
+       stack_trap "$LCTL set_param \
+               lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
+       lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
+               lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
+       do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
+               lod.*.mdt_qos_maxage=1
+       stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
+               lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
+
        echo
        echo "Check for uneven MDTs: "
 
@@ -24801,9 +25142,15 @@ generate_uneven_mdts() {
                fi
        done
 
+       (( ${ffree[min_index]} > 0 )) ||
+               skip "no free files in MDT$min_index"
+       (( ${ffree[min_index]} < 10000000 )) ||
+               skip "too many free files in MDT$min_index"
+
        # Check if we need to generate uneven MDTs
        local diff=$(((max - min) * 100 / min))
        local testdir=$DIR/$tdir-fillmdt
+       local start
 
        mkdir -p $testdir
 
@@ -24811,17 +25158,21 @@ generate_uneven_mdts() {
        while (( diff < threshold )); do
                # generate uneven MDTs, create till $threshold% diff
                echo -n "weight diff=$diff% must be > $threshold% ..."
-               echo "Fill MDT$min_index with 100 files: loop $i"
+               echo "Fill MDT$min_index with 1000 files: loop $i"
                testdir=$DIR/$tdir-fillmdt/$i
                [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
                        error "mkdir $testdir failed"
                $LFS setstripe -E 1M -L mdt $testdir ||
                        error "setstripe $testdir failed"
-               for F in f.{0..99}; do
-                       dd if=/dev/zero of=$testdir/$F bs=1M count=1 > \
+               start=$SECONDS
+               for F in f.{0..999}; do
+                       dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
                                /dev/null 2>&1 || error "dd $F failed"
                done
 
+               # wait for QOS to update
+               (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
+
                ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
                bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
                max=$(((${ffree[max_index]} >> 8) * \
@@ -24888,7 +25239,6 @@ test_qos_mkdir() {
        local stripe_index=$($LFS getstripe -m $testdir)
        local test_mkdir_rr=true
 
-       echo "dirstripe: '$($LFS getdirstripe $testdir)'"
        getfattr -d -m dmv -e hex $testdir | grep dmv
        if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
                echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
@@ -24965,7 +25315,7 @@ test_qos_mkdir() {
 
        (( ${ffree[min_index]} > 0 )) ||
                skip "no free files in MDT$min_index"
-       (( ${ffree[min_index]} < 100000000 )) ||
+       (( ${ffree[min_index]} < 10000000 )) ||
                skip "too many free files in MDT$min_index"
 
        echo "MDT filesfree available: ${ffree[@]}"
@@ -24993,32 +25343,33 @@ test_qos_mkdir() {
                        error "$mkdir_cmd subdir$i failed"
        done
 
+       max=0
        for (( i = 0; i < $MDSCOUNT; i++ )); do
                count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
+               (( count > max )) && max=$count
                echo "$count directories created on MDT$i"
-
-               if [ $stripe_count -gt 1 ]; then
-                       count=$($LFS getdirstripe $testdir/* |
-                               grep -c -P "^\s+$i\t")
-                       echo "$count stripes created on MDT$i"
-               fi
        done
 
-       max=$($LFS getdirstripe -i $testdir/* | grep -c "^$max_index$")
        min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
 
        # D-value should > 10% of averge
-       (( max - min >= num / 10 )) ||
+       (( max - min > num / 10 )) ||
                error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
 
-       # 5% for stripes
+       # ditto for stripes
        if (( stripe_count > 1 )); then
-               max=$($LFS getdirstripe $testdir/* |
-                     grep -c -P "^\s+$max_index\t")
+               max=0
+               for (( i = 0; i < $MDSCOUNT; i++ )); do
+                       count=$($LFS getdirstripe $testdir/* |
+                               grep -c -P "^\s+$i\t")
+                       (( count > max )) && max=$count
+                       echo "$count stripes created on MDT$i"
+               done
+
                min=$($LFS getdirstripe $testdir/* |
                        grep -c -P "^\s+$min_index\t")
-               (( max - min >= num * stripe_count / 20 )) ||
-                       error "stripes shouldn't be evenly distributed: $max - $min < $((num / 20)) * $stripe_count"
+               (( max - min > num * stripe_count / 10 )) ||
+                       error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
        fi
 }
 
@@ -25162,7 +25513,7 @@ test_413z() {
        local pid
 
        for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
-               unlinkmany $subdir/f. 100 &
+               unlinkmany $subdir/f. 1000 &
                pids="$pids $!"
        done
 
@@ -25287,7 +25638,8 @@ check_lfs_df() {
        [ "$1" == "blocks" ] && inodes= || inodes="-i"
 
        for count in {1..100}; do
-               do_rpc_nodes "$CLIENTS" cancel_lru_locks
+               do_nodes "$CLIENTS" \
+                       $LCTL set_param ldlm.namespaces.*.lru_size=clear
                sync; sleep 0.2
 
                # read the lines of interest
@@ -25300,7 +25652,9 @@ check_lfs_df() {
                # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
                # compare the two outputs
                passed=true
-               for i in {1..5}; do
+               #  skip "available" on MDT until LU-13997 is fixed.
+               #for i in {1..5}; do
+               for i in 1 2 4 5; do
                        [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
                done
                $passed && break
@@ -27219,15 +27573,24 @@ test_817() {
 run_test 817 "nfsd won't cache write lock for exec file"
 
 test_818() {
-       mkdir $DIR/$tdir
-       $LFS setstripe -c1 -i0 $DIR/$tfile
-       $LFS setstripe -c1 -i1 $DIR/$tfile
+       test_mkdir -i0 -c1 $DIR/$tdir
+       $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
+       $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
        stop $SINGLEMDS
+
+       # restore osp-syn threads
+       stack_trap "fail $SINGLEMDS"
+
        #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
        do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
        start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
                error "start $SINGLEMDS failed"
        rm -rf $DIR/$tdir
+
+       local testid=$(echo $TESTNAME | tr '_' ' ')
+
+       do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
+               grep "run LFSCK" || error "run LFSCK is not suggested"
 }
 run_test 818 "unlink with failed llog"
 
@@ -27325,6 +27688,78 @@ test_822() {
 }
 run_test 822 "test precreate failure"
 
+test_823() {
+       local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
+       local OST_MAX_PRECREATE=20000
+
+       save_lustre_params mds1 \
+               "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
+       do_facet $SINGLEMDS "$LCTL set_param -n \
+               osp.$FSNAME-OST*MDT0000.max_create_count=0"
+       do_facet $SINGLEMDS "$LCTL set_param -n \
+               osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
+
+       stack_trap "restore_lustre_params < $p; rm $p"
+
+       do_facet $SINGLEMDS "$LCTL set_param -n \
+               osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
+
+       local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
+                     osp.$FSNAME-OST0000*MDT0000.create_count")
+       local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
+                   osp.$FSNAME-OST0000*MDT0000.max_create_count")
+       local expect_count=$(((($max/2)/256) * 256))
+
+       log "setting create_count to 100200:"
+       log " -result- count: $count with max: $max, expecting: $expect_count"
+
+       [[ $count -eq expect_count ]] ||
+               error "Create count not set to max precreate."
+}
+run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
+
+test_831() {
+       local sync_changes=$(do_facet $SINGLEMDS \
+               $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
+
+       [ "$sync_changes" -gt 100 ] &&
+               skip "Sync changes $sync_changes > 100 already"
+
+       local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
+
+       $LFS mkdir -i 0 $DIR/$tdir
+       $LFS setstripe -c 1 -i 0 $DIR/$tdir
+
+       save_lustre_params mds1 \
+               "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
+       save_lustre_params mds1 \
+               "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
+
+       do_facet mds1 "$LCTL set_param -n \
+               osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
+               osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
+       stack_trap "restore_lustre_params < $p" EXIT
+
+       createmany -o $DIR/$tdir/f- 1000
+       unlinkmany $DIR/$tdir/f- 1000 &
+       local UNLINK_PID=$!
+
+       while sleep 1; do
+               sync_changes=$(do_facet mds1 \
+               $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
+               # the check in the code is racy, fail the test
+               # if the value above the limit by 10.
+               [ $sync_changes -gt 110 ] && {
+                       kill -2 $UNLINK_PID
+                       wait
+                       error "osp changes throttling failed, $sync_changes>110"
+               }
+               kill -0 $UNLINK_PID 2> /dev/null || break
+       done
+       wait
+}
+run_test 831 "throttling unlink/setattr queuing on OSP"
+
 #
 # tests that do cleanup/setup should be run at the end
 #