Whamcloud - gitweb
LU-16023 tests: sanity-quota/8 should return success
[fs/lustre-release.git] / lustre / tests / sanity-quota.sh
index 7785428..b38f191 100755 (executable)
@@ -13,8 +13,8 @@ init_test_env $@
 init_logging
 
 ALWAYS_EXCEPT="$SANITY_QUOTA_EXCEPT "
-# Bug number for skipped test:  LU-5152
-ALWAYS_EXCEPT+="                55"
+# Bug number for skipped test:
+ALWAYS_EXCEPT+=""
 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
 
 # Test duration:                   30 min
@@ -39,7 +39,6 @@ BLK_SZ=1024
 MAX_DQ_TIME=604800
 MAX_IQ_TIME=604800
 QTYPE="ugp"
-# QP exists since this version. Should be finally set before landing.
 VERSION_WITH_QP="2.13.53"
 mds_supports_qp() {
        [ $MDS1_VERSION -lt $(version_code $VERSION_WITH_QP) ] &&
@@ -129,17 +128,20 @@ resetquota() {
 quota_scan() {
        local local_ugp=$1
        local local_id=$2
+       local count
 
        if [ "$local_ugp" == "a" -o "$local_ugp" == "u" ]; then
                $LFS quota -v -u $local_id $DIR
-               log "Files for user ($local_id):"
+               count=$($LFS find --user $local_id $DIR | wc -l)
+               log "Files for user ($local_id), count=$count:"
                ($LFS find --user $local_id $DIR | head -n 4 |
                        xargs stat 2>/dev/null)
        fi
 
        if [ "$local_ugp" == "a" -o "$local_ugp" == "g" ]; then
                $LFS quota -v -g $local_id $DIR
-               log "Files for group ($local_id):"
+               count=$($LFS find --group $local_id $DIR | wc -l)
+               log "Files for group ($local_id), count=$count:"
                ($LFS find --group $local_id $DIR | head -n 4 |
                        xargs stat 2>/dev/null)
        fi
@@ -147,7 +149,8 @@ quota_scan() {
        is_project_quota_supported || return 0
        if [ "$local_ugp" == "a" -o "$local_ugp" == "p" ]; then
                $LFS quota -v -p $TSTPRJID $DIR
-               log "Files for project ($TSTPRJID):"
+               count=$($LFS find --projid $TSTPRJID $DIR | wc -l)
+               log "Files for project ($TSTPRJID), count=$count:"
                ($LFS find --projid $TSTPRJID $DIR | head -n 4 |
                        xargs stat 2>/dev/null)
        fi
@@ -216,7 +219,7 @@ set_mdt_qtype() {
 
        if [[ $PERM_CMD == *"set_param -P"* ]]; then
                do_facet mgs $PERM_CMD \
-                       osd-*.$FSNAME-MDT*.quota_slave.enable=$qtype
+                       osd-*.$FSNAME-MDT*.quota_slave.enabled=$qtype
        else
                do_facet mgs $PERM_CMD $FSNAME.quota.mdt=$qtype
        fi
@@ -246,7 +249,7 @@ set_ost_qtype() {
 
        if [[ $PERM_CMD == *"set_param -P"* ]]; then
                do_facet mgs $PERM_CMD \
-                       osd-*.$FSNAME-OST*.quota_slave.enable=$qtype
+                       osd-*.$FSNAME-OST*.quota_slave.enabled=$qtype
        else
                do_facet mgs $PERM_CMD $FSNAME.quota.ost=$qtype
        fi
@@ -355,50 +358,66 @@ wait_grace_time() {
        case $flavour in
                block)
                        time=$(lfs quota -$qtype $qarg $parg $DIR|
-                                  awk 'NR == 3{ print $5 }'| sed 's/s$//')
+                                  awk 'NR == 3{ print $5 }')
                        ;;
                file)
                        time=$(lfs quota -$qtype $qarg $DIR|
-                                  awk 'NR == 3{ print $9 }'| sed 's/s$//')
+                                  awk 'NR == 3{ print $9 }')
                        ;;
                *)
                        error "Unknown quota type: $flavour"
                        ;;
        esac
 
+       local sleep_seconds=0
+       local orig_time=$time
+
+       echo "Grace time is $time"
        # from lfs.c:__sec2str()
        # const char spec[] = "smhdw";
        # {1, 60, 60*60, 24*60*60, 7*24*60*60};
-       [[ $time == *m* ]] && time=${time//m/} && time=$((time*60));
-       [[ $time == *h* ]] && time=${time//h/} && time=$((time*60*60));
-       [[ $time == *d* ]] && time=${time//d/} && time=$((time*24*60*60));
-       [[ $time == *w* ]] && time=${time//w/} && time=$((time*7*24*60*60));
+       [[ $time == *w* ]] && w_time=${time%w*} &&
+               let sleep_seconds+=$((w_time*7*24*60*60));
+       time=${time#*w}
+       [[ $time == *d* ]] && d_time=${time%d*} &&
+               let sleep_seconds+=$((d_time*24*60*60));
+       time=${time#*d}
+       [[ $time == *h* ]] && h_time=${time%h*} &&
+               let sleep_seconds+=$((h_time*60*60));
+       time=${time#*h}
+       [[ $time == *m* ]] && m_time=${time%m*} &&
+               let sleep_seconds+=$((m_time*60));
+       time=${time#*m}
+       [[ $time == *s* ]] && s_time=${time%s*} &&
+               let sleep_seconds+=$s_time
 
        echo "Sleep through grace ..."
-       [ "$time" == "-" ] &&
+       [ "$orig_time" == "-" ] &&
            error "Grace timeout was not set or quota not exceeded"
-       if [ "$time" == "none" ]; then
+       if [ "$orig_time" == "none" ]; then
            echo "...Grace timeout already expired"
        else
-               let time+=$extrasleep
-               echo "...sleep $time seconds"
-               sleep $time
+               let sleep_seconds+=$extrasleep
+               echo "...sleep $sleep_seconds seconds"
+               sleep $sleep_seconds
        fi
 }
 
 setup_quota_test() {
        wait_delete_completed
        echo "Creating test directory"
-       mkdir $DIR/$tdir || return 1
+       mkdir_on_mdt0 $DIR/$tdir || return 1
        chmod 0777 $DIR/$tdir || return 2
        # always clear fail_loc in case of fail_loc isn't cleared
        # properly when previous test failed
        lustre_fail mds_ost 0
+       stack_trap cleanup_quota_test EXIT
 }
 
 cleanup_quota_test() {
        echo "Delete files..."
        rm -rf $DIR/$tdir
+       [ -d $DIR/${tdir}_dom ] && rm -rf $DIR/${tdir}_dom
        echo "Wait for unlink objects finished..."
        wait_delete_completed
        sync_all_data || true
@@ -476,7 +495,8 @@ reset_quota_settings() {
 
 # enable quota debug
 quota_init() {
-       do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=+quota+trace"
+       do_nodes $(comma_list $(nodes_list)) \
+               "$LCTL set_param -n debug=+quota,trace"
 }
 quota_init
 reset_quota_settings
@@ -510,7 +530,7 @@ test_quota_performance() {
 
 # test basic quota performance b=21696
 test_0() {
-       local MB=100 # 100M
+       local MB=100 # MB
        [ "$SLOW" = "no" ] && MB=10
 
        local free_space=$(lfs_df | grep "summary" | awk '{print $4}')
@@ -518,7 +538,6 @@ test_0() {
                skip "not enough space ${free_space} KB, " \
                        "required $((MB * 1024)) KB"
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        set_ost_qtype "none" || error "disable ost quota failed"
        test_quota_performance $MB
@@ -527,8 +546,6 @@ test_0() {
        $LFS setquota -u $TSTUSR -b 0 -B 10G -i 0 -I 0 $DIR ||
                error "set quota failed"
        test_quota_performance $MB
-
-       cleanup_quota_test
 }
 run_test 0 "Test basic quota performance"
 
@@ -550,12 +567,13 @@ test_1_check_write() {
        cancel_lru_locks osc
        sync; sync_all_data || true
        # sync means client wrote all it's cache, but id doesn't
-       # garantee that slave got new edquot trough glimpse.
+       # guarantee that slave received new edquot through glimpse.
        # so wait a little to be sure slave got it.
        sleep 5
        $RUNAS $DD of=$testfile count=1 seek=$limit &&
                quota_error $short_qtype $TSTUSR \
                        "user write success, but expect EDQUOT"
+       return 0
 }
 
 check_write_fallocate() {
@@ -582,11 +600,10 @@ check_write_fallocate() {
 
 # test block hardlimit
 test_1a() {
-       local limit=10  # 10M
+       local limit=10 # MB
        local testfile="$DIR/$tdir/$tfile-0"
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        # enable ost quota
        set_ost_qtype $QTYPE || error "enable ost quota failed"
@@ -638,7 +655,6 @@ test_1a() {
 
        if ! is_project_quota_supported; then
                echo "Project quota is not supported"
-               cleanup_quota_test
                return 0
        fi
 
@@ -672,14 +688,13 @@ test_1a() {
 run_test 1a "Block hard limit (normal use and out of quota)"
 
 test_1b() {
-       local limit=10  # 10M
-       local global_limit=20  # 100M
+       local limit=10 # MB
+       local global_limit=20 # MB
        local testfile="$DIR/$tdir/$tfile-0"
        local qpool="qpool1"
 
        mds_supports_qp
        setup_quota_test || error "setup quota failed with $?"
-       stack_trap cleanup_quota_test EXIT
 
        # enable ost quota
        set_ost_qtype $QTYPE || error "enable ost quota failed"
@@ -693,6 +708,12 @@ test_1b() {
        pool_add_targets $qpool 0 $(($OSTCOUNT - 1)) ||
                error "pool_add_targets failed"
 
+       # check qmt_pool_add dmesg error
+       local msg_rgx="QMT0000: can't add to $FSNAME-OST0000.*pool.*$qpool"
+       local dmesg_err
+       dmesg_err=$(do_facet mds1 dmesg | grep "$msg_rgx" | tail -1)
+       [[ -z "$dmesg_err" ]] || error "found qmt_pool_add error: $dmesg_err"
+
        $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR ||
                error "set user quota failed"
 
@@ -745,7 +766,6 @@ test_1b() {
 
        if ! is_project_quota_supported; then
                echo "Project quota is not supported"
-               cleanup_quota_test
                return 0
        fi
 
@@ -781,14 +801,13 @@ test_1b() {
 run_test 1b "Quota pools: Block hard limit (normal use and out of quota)"
 
 test_1c() {
-       local global_limit=20  # 100M
+       local global_limit=20 # MB
        local testfile="$DIR/$tdir/$tfile-0"
        local qpool1="qpool1"
        local qpool2="qpool2"
 
        mds_supports_qp
        setup_quota_test || error "setup quota failed with $?"
-       stack_trap cleanup_quota_test EXIT
 
        # enable ost quota
        set_ost_qtype $QTYPE || error "enable ost quota failed"
@@ -833,26 +852,21 @@ test_1c() {
        sync_all_data || true
 
        used=$(getquota -u $TSTUSR global curspace $qpool1)
-       [ $used -ne 0 ] && quota_error u $TSTUSR \
+       [ $used -eq 0 ] || quota_error u $TSTUSR \
                "user quota isn't released after deletion"
-       resetquota -u $TSTUSR
-
-       # cleanup
-       cleanup_quota_test
 }
 run_test 1c "Quota pools: check 3 pools with hardlimit only for global"
 
 test_1d() {
-       local limit1=10  # 10M
-       local limit2=12  # 12M
-       local global_limit=20  # 100M
+       local limit1=10 # MB
+       local limit2=12 # MB
+       local global_limit=20 # MB
        local testfile="$DIR/$tdir/$tfile-0"
        local qpool1="qpool1"
        local qpool2="qpool2"
 
        mds_supports_qp
        setup_quota_test || error "setup quota failed with $?"
-       stack_trap cleanup_quota_test EXIT
 
        # enable ost quota
        set_ost_qtype $QTYPE || error "enable ost quota failed"
@@ -895,25 +909,20 @@ test_1d() {
        sync_all_data || true
 
        used=$(getquota -u $TSTUSR global curspace $qpool1)
-       [ $used -ne 0 ] && quota_error u $TSTUSR \
+       [ $used -eq 0 ] || quota_error u $TSTUSR \
                "user quota isn't released after deletion"
-       resetquota -u $TSTUSR
-
-       # cleanup
-       cleanup_quota_test
 }
 run_test 1d "Quota pools: check block hardlimit on different pools"
 
 test_1e() {
-       local limit1=10  # 10M
-       local global_limit=200  # 200M
+       local limit1=10 # MB
+       local global_limit=53000000 # MB
        local testfile="$DIR/$tdir/$tfile-0"
        local testfile2="$DIR/$tdir/$tfile-1"
        local qpool1="qpool1"
 
        mds_supports_qp
        setup_quota_test || error "setup quota failed with $?"
-       stack_trap cleanup_quota_test EXIT
 
        # enable ost quota
        set_ost_qtype $QTYPE || error "enable ost quota failed"
@@ -957,25 +966,20 @@ test_1e() {
        sync_all_data || true
 
        used=$(getquota -u $TSTUSR global curspace $qpool1)
-       [ $used -ne 0 ] && quota_error u $TSTUSR \
+       [ $used -eq 0 ] || quota_error u $TSTUSR \
                "user quota isn't released after deletion"
-       resetquota -u $TSTUSR
-
-       # cleanup
-       cleanup_quota_test
 }
 run_test 1e "Quota pools: global pool high block limit vs quota pool with small"
 
 test_1f() {
-       local global_limit=200  # 200M
-       local limit1=10  # 10M
+       local global_limit=200 # MB
+       local limit1=10 # MB
        local TESTDIR="$DIR/$tdir/"
        local testfile="$TESTDIR/$tfile-0"
        local qpool1="qpool1"
 
        mds_supports_qp
        setup_quota_test || error "setup quota failed with $?"
-       stack_trap cleanup_quota_test EXIT
 
        # enable ost quota
        set_ost_qtype $QTYPE || error "enable ost quota failed"
@@ -1015,15 +1019,12 @@ test_1f() {
        # became > 10M. QMT returned EINPROGRESS in a loop.
        # Check that it doesn't hung anymore.
        test_1_check_write $testfile "user" $limit1
-
-       # cleanup
-       cleanup_quota_test
 }
 run_test 1f "Quota pools: correct qunit after removing/adding OST"
 
 test_1g() {
-       local limit=20  # 20M
-       local global_limit=40  # 40M
+       local limit=20 # MB
+       local global_limit=40 # MB
        local testfile="$DIR/$tdir/$tfile-0"
        local qpool="qpool1"
        local mdmb_param="osc.*.max_dirty_mb"
@@ -1031,7 +1032,6 @@ test_1g() {
 
        mds_supports_qp
        setup_quota_test || error "setup quota failed with $?"
-       stack_trap cleanup_quota_test EXIT
        $LCTL set_param $mdmb_param=1
        stack_trap "$LCTL set_param $mdmb_param=$max_dirty_mb" EXIT
 
@@ -1085,13 +1085,12 @@ test_1g() {
 run_test 1g "Quota pools: Block hard limit with wide striping"
 
 test_1h() {
-       local limit=10  # 10M
+       local limit=10 # MB
        local testfile="$DIR/$tdir/$tfile-0"
 
-       check_for_fallocate
+       check_set_fallocate_or_skip
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        # enable ost quota
        set_ost_qtype $QTYPE || error "enable ost quota failed"
@@ -1114,117 +1113,195 @@ test_1h() {
        wait_delete_completed || error "wait_delete_completed failed"
        sync_all_data || true
        used=$(getquota -u $TSTUSR global curspace)
-       [ $used -ne 0 ] && quota_error u $TSTUSR \
+       [ $used -eq 0 ] || quota_error u $TSTUSR \
                "user quota isn't released after deletion"
-       resetquota -u $TSTUSR
 }
 run_test 1h "Block hard limit test using fallocate"
 
+test_1i() {
+       local global_limit=200  # 200M
+       local limit1=10  # 10M
+       local TESTDIR="$DIR/$tdir/"
+       local testfile="$TESTDIR/$tfile-0"
+       local testfile1="$TESTDIR/$tfile-1"
+       local testfile2="$TESTDIR/$tfile-2"
+       local qpool1="qpool1"
+
+       mds_supports_qp
+       setup_quota_test || error "setup quota failed with $?"
+       stack_trap cleanup_quota_test EXIT
+
+       # enable ost quota
+       set_ost_qtype $QTYPE || error "enable ost quota failed"
+
+       log "User quota (block hardlimit:$global_limit MB)"
+       $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
+               error "set user quota failed"
+
+       pool_add $qpool1 || error "pool_add failed"
+       pool_add_targets $qpool1 0 0 ||
+               error "pool_add_targets failed"
+
+       $LFS setquota -u $TSTUSR -B ${limit1}M --pool $qpool1 $DIR ||
+               error "set user quota failed"
+
+       # make sure the system is clean
+       local used=$(getquota -u $TSTUSR global curspace)
+       [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
+
+       $LFS setstripe $TESTDIR -c 1 -i 0 || error "setstripe $TESTDIR failed"
+
+       # hit pool limit
+       test_1_check_write $testfile "user" $limit1
+       $LFS setquota -u $TSTUSR -B 0 --pool $qpool1 $DIR ||
+               error "set user quota failed"
+
+       $LFS quota -uv $TSTUSR --pool $qpool1 $DIR
+       $RUNAS $DD of=$testfile1 count=$((limit1/2)) ||
+               quota_error u $TSTUSR "write failure, but expect success"
+
+       rm -f $testfile
+       rm -f $testfile1
+       wait_delete_completed || error "wait_delete_completed failed"
+       sync_all_data || true
+
+       $LFS setquota -u $TSTUSR -B ${limit1}M --pool $qpool1 $DIR ||
+               error "set user quota failed"
+       test_1_check_write $testfile "user" $limit1
+       local tmp_limit=$(($limit1*2))
+       # increase pool limit
+       $LFS setquota -u $TSTUSR -B ${tmp_limit}M --pool $qpool1 $DIR ||
+               error "set user quota failed"
+       # now write shouldn't fail
+       $RUNAS $DD of=$testfile1 count=$((limit1/3)) ||
+               quota_error u $TSTUSR "write failure, but expect success"
+       # decrease pool limit
+       $LFS setquota -u $TSTUSR -B ${limit1}M --pool $qpool1 $DIR ||
+               error "set user quota failed"
+       $RUNAS $DD of=$testfile2 count=$((limit1/3))
+       # flush cache, ensure noquota flag is set on client
+       cancel_lru_locks osc
+       sync; sync_all_data || true
+       $RUNAS $DD of=$testfile2 seek=$((limit1/3)) count=1 &&
+               quota_error u $TSTUSR "write success, but expect failure"
+       return 0
+}
+run_test 1i "Quota pools: different limit and usage relations"
+
 # test inode hardlimit
 test_2() {
-       local TESTFILE="$DIR/$tdir/$tfile-0"
-       local LIMIT=$(do_facet mds1 $LCTL get_param -n \
+       local testfile="$DIR/$tdir/$tfile-0"
+       local least_qunit=$(do_facet mds1 $LCTL get_param -n \
                qmt.$FSNAME-QMT0000.md-0x0.info |
-               awk '/least qunit/{ print $3 }')
-       local L2=$(do_facet mds1 $LCTL get_param -n \
-               qmt.$FSNAME-QMT0000.md-0x0.soft_least_qunit)
-
-       [ $L2 -le $LIMIT ] || LIMIT=$L2
+               sed -e 's/least qunit/least_qunit/' |
+               awk '/least_qunit/{ print $2 }')
+       local limit
 
-       [ "$SLOW" = "no" ] || LIMIT=$((LIMIT * 1024))
+       [ "$SLOW" = "no" ] && limit=$((least_qunit * 2)) ||
+               limit=$((least_qunit * 1024))
+       echo "least_qunit: '$least_qunit', limit: '$limit'"
 
-       local FREE_INODES=$(mdt_free_inodes 0)
-       echo "$FREE_INODES free inodes on master MDT"
-       [ $FREE_INODES -lt $LIMIT ] &&
-               skip "not enough free inodes $FREE_INODES required $LIMIT"
+       local free_inodes=$(mdt_free_inodes 0)
+       echo "$free_inodes free inodes on master MDT"
+       [ $free_inodes -lt $limit ] &&
+               skip "not enough free inodes $free_inodes required $limit"
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        # enable mdt quota
        set_mdt_qtype $QTYPE || error "enable mdt quota failed"
 
        # test for user
-       log "User quota (inode hardlimit:$LIMIT files)"
-       $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I $LIMIT $DIR ||
+       log "User quota (inode hardlimit:$limit files)"
+       $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I $limit $DIR ||
                error "set user quota failed"
 
        # make sure the system is clean
-       local USED=$(getquota -u $TSTUSR global curinodes)
-       [ $USED -ne 0 ] && error "Used inodes($USED) for user $TSTUSR isn't 0."
+       local used=$(getquota -u $TSTUSR global curinodes)
+       [ $used -ne 0 ] && error "Used inodes($used) for user $TSTUSR isn't 0."
 
-       log "Create $LIMIT files ..."
-       $RUNAS createmany -m ${TESTFILE} $LIMIT ||
+       log "Create $((limit - least_qunit)) files ..."
+       $RUNAS createmany -m ${testfile} $((limit - least_qunit)) ||
                quota_error u $TSTUSR "user create failure, but expect success"
+       # it is ok, if it fails on the last qunit
+       $RUNAS createmany -m ${testfile}_yyy $least_qunit || true
        log "Create out of file quota ..."
-       $RUNAS touch ${TESTFILE}_xxx &&
+       $RUNAS touch ${testfile}_xxx &&
                quota_error u $TSTUSR "user create success, but expect EDQUOT"
 
        # cleanup
-       unlinkmany ${TESTFILE} $LIMIT || error "unlinkmany $TESTFILE failed"
-       rm -f ${TESTFILE}_xxx
+       unlinkmany ${testfile} $((limit - least_qunit)) ||
+               error "unlinkmany $testfile failed"
+       # if 2nd createmany got EDQUOT, not all of nodes would be created
+       unlinkmany ${testfile}_yyy $least_qunit || true
+       rm -f ${testfile}_xxx
        wait_delete_completed
 
-       USED=$(getquota -u $TSTUSR global curinodes)
-       [ $USED -ne 0 ] && quota_error u $TSTUSR \
+       used=$(getquota -u $TSTUSR global curinodes)
+       [ $used -ne 0 ] && quota_error u $TSTUSR \
                "user quota isn't released after deletion"
        resetquota -u $TSTUSR
 
        # test for group
        log "--------------------------------------"
-       log "Group quota (inode hardlimit:$LIMIT files)"
-       $LFS setquota -g $TSTUSR -b 0 -B 0 -i 0 -I $LIMIT $DIR ||
+       log "Group quota (inode hardlimit:$limit files)"
+       $LFS setquota -g $TSTUSR -b 0 -B 0 -i 0 -I $limit $DIR ||
                error "set group quota failed"
 
-       TESTFILE=$DIR/$tdir/$tfile-1
+       testfile=$DIR/$tdir/$tfile-1
        # make sure the system is clean
-       USED=$(getquota -g $TSTUSR global curinodes)
-       [ $USED -ne 0 ] && error "Used inodes($USED) for group $TSTUSR isn't 0."
+       used=$(getquota -g $TSTUSR global curinodes)
+       [ $used -ne 0 ] && error "Used inodes($used) for group $TSTUSR isn't 0."
 
-       log "Create $LIMIT files ..."
-       $RUNAS createmany -m ${TESTFILE} $LIMIT ||
+       log "Create $limit files ..."
+       $RUNAS createmany -m ${testfile} $((limit - least_qunit)) ||
                quota_error g $TSTUSR "group create failure, but expect success"
+       $RUNAS createmany -m ${testfile}_yyy $least_qunit ||
        log "Create out of file quota ..."
-       $RUNAS touch ${TESTFILE}_xxx &&
+       $RUNAS touch ${testfile}_xxx &&
                quota_error g $TSTUSR "group create success, but expect EDQUOT"
 
        # cleanup
-       unlinkmany ${TESTFILE} $LIMIT || error "unlinkmany $TESTFILE failed"
-       rm -f ${TESTFILE}_xxx
+       unlinkmany ${testfile} $((limit - least_qunit)) ||
+               error "unlinkmany $testfile failed"
+       unlinkmany ${testfile}_yyy $least_qunit || true
+       rm -f ${testfile}_xxx
        wait_delete_completed
 
-       USED=$(getquota -g $TSTUSR global curinodes)
-       [ $USED -ne 0 ] && quota_error g $TSTUSR \
+       used=$(getquota -g $TSTUSR global curinodes)
+       [ $used -ne 0 ] && quota_error g $TSTUSR \
                "user quota isn't released after deletion"
 
        resetquota -g $TSTUSR
-       ! is_project_quota_supported && cleanup_quota_test &&
+       ! is_project_quota_supported &&
                echo "Skip project quota is not supported" && return 0
 
        # test for project
        log "--------------------------------------"
-       log "Project quota (inode hardlimit:$LIMIT files)"
-       $LFS setquota -p $TSTPRJID -b 0 -B 0 -i 0 -I $LIMIT $DIR ||
+       log "Project quota (inode hardlimit:$limit files)"
+       $LFS setquota -p $TSTPRJID -b 0 -B 0 -i 0 -I $limit $DIR ||
                error "set project quota failed"
 
-       TESTFILE=$DIR/$tdir/$tfile-1
+       testfile=$DIR/$tdir/$tfile-1
        # make sure the system is clean
-       USED=$(getquota -p $TSTPRJID global curinodes)
-       [ $USED -ne 0 ] &&
-               error "Used inodes($USED) for project $TSTPRJID isn't 0"
+       used=$(getquota -p $TSTPRJID global curinodes)
+       [ $used -ne 0 ] &&
+               error "Used inodes($used) for project $TSTPRJID isn't 0"
 
        change_project -sp $TSTPRJID $DIR/$tdir
-       log "Create $LIMIT files ..."
-       $RUNAS createmany -m ${TESTFILE} $((LIMIT-1)) || quota_error p \
-               $TSTPRJID "project create fail, but expect success"
+       log "Create $limit files ..."
+       $RUNAS createmany -m ${testfile} $((limit-least_qunit)) ||
+               quota_error p $TSTPRJID \
+                       "project create fail, but expect success"
+       $RUNAS createmany -m ${testfile}_yyy $least_qunit || true
        log "Create out of file quota ..."
-       $RUNAS touch ${TESTFILE}_xxx && quota_error p $TSTPRJID \
+       $RUNAS touch ${testfile}_xxx && quota_error p $TSTPRJID \
                "project create success, but expect EDQUOT"
        change_project -C $DIR/$tdir
 
        cleanup_quota_test
-       USED=$(getquota -p $TSTPRJID global curinodes)
-       [ $USED -eq 0 ] || quota_error p $TSTPRJID \
+       used=$(getquota -p $TSTPRJID global curinodes)
+       [ $used -eq 0 ] || quota_error p $TSTPRJID \
                "project quota isn't released after deletion"
 
 }
@@ -1237,9 +1314,10 @@ test_block_soft() {
        local OFFSET=0
        local qtype=$4
        local pool=$5
+       local soft_limit=$(do_facet $SINGLEMDS $LCTL get_param -n \
+               qmt.$FSNAME-QMT0000.dt-0x0.soft_least_qunit)
 
        setup_quota_test
-       stack_trap cleanup_quota_test EXIT
 
        $LFS setstripe $testfile -c 1 -i 0
        chown $TSTUSR.$TSTUSR $testfile
@@ -1287,8 +1365,11 @@ test_block_soft() {
 
        log "Write after timer goes off"
        # maybe cache write, ignore.
-       $RUNAS dd if=/dev/zero of=$testfile bs=1K count=10 seek=$OFFSET || true
-       OFFSET=$((OFFSET + 1024))
+       # write up to soft least quint to consume all
+       # possible slave granted space.
+       $RUNAS dd if=/dev/zero of=$testfile bs=1K \
+               count=$soft_limit seek=$OFFSET || true
+       OFFSET=$((OFFSET + soft_limit))
        cancel_lru_locks osc
        log "Write after cancel lru locks"
        $RUNAS dd if=/dev/zero of=$testfile bs=1K count=10 seek=$OFFSET &&
@@ -1326,7 +1407,7 @@ test_block_soft() {
 
 # block soft limit
 test_3a() {
-       local grace=20 # 20s
+       local grace=20 # seconds
        if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
            grace=60
        fi
@@ -1393,7 +1474,7 @@ test_3a() {
 run_test 3a "Block soft limit (start timer, timer goes off, stop timer)"
 
 test_3b() {
-       local grace=20 # 20s
+       local grace=20 # seconds
        local qpool="qpool1"
        if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
                grace=60
@@ -1492,7 +1573,7 @@ test_3b() {
 run_test 3b "Quota pools: Block soft limit (start timer, expires, stop timer)"
 
 test_3c() {
-       local grace=20 # 20s
+       local grace=20 # seconds
        local qpool="qpool1"
        local qpool2="qpool2"
        if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
@@ -1539,8 +1620,8 @@ test_3c() {
                error "set user quota failed"
        $LFS setquota -u $TSTUSR -b ${limit}M -B 0 --pool $qpool $DIR ||
                error "set user quota failed"
-       # qpool has minimum soft limit, but it's grace is grater than
-       # grace period of qpool2. Thus write shouldn't fail when
+       # qpool has minimum soft limit, but its grace is greater than
+       # the grace period of qpool2. Thus write shouldn't fail when
        # hit qpool soft limit - only when reaches up qpool2 limit
        # after grace2 seconds.
        $LFS setquota -u $TSTUSR -b ${limit2}M -B 0 --pool $qpool2 $DIR ||
@@ -1567,7 +1648,6 @@ test_file_soft() {
                qmt.$FSNAME-QMT0000.md-0x0.soft_least_qunit)
 
        setup_quota_test
-       trap cleanup_quota_test EXIT
        is_project_quota_supported && change_project -sp $TSTPRJID $DIR/$tdir
 
        echo "Create files to exceed soft limit"
@@ -1631,6 +1711,7 @@ test_4a() {
        local TESTFILE=$DIR/$tdir/$tfile-0
        local GRACE=12
 
+       [ "$mds1_FSTYPE" = zfs ] && GRACE=20
        set_mdt_qtype $QTYPE || error "enable mdt quota failed"
 
        echo "User quota (soft limit:$LIMIT files  grace:$GRACE seconds)"
@@ -1643,8 +1724,6 @@ test_4a() {
        $LFS setquota -u $TSTUSR -b 0 -B 0 -i $LIMIT -I 0 $DIR ||
                error "set user quota failed"
 
-       [ "$mds1_FSTYPE" = zfs ] && GRACE=20
-
        test_file_soft $TESTFILE $LIMIT $GRACE "u"
 
        echo "Group quota (soft limit:$LIMIT files  grace:$GRACE seconds)"
@@ -1726,11 +1805,10 @@ run_test 4b "Grace time strings handling"
 
 # chown & chgrp (chown & chgrp successfully even out of block/file quota)
 test_5() {
-       local BLIMIT=10 # 10M
-       local ILIMIT=10 # 10 inodes
+       local BLIMIT=10 # MB
+       local ILIMIT=10 # inodes
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        set_mdt_qtype $QTYPE || error "enable mdt quota failed"
        set_ost_qtype $QTYPE || error "enable ost quota failed"
@@ -1782,20 +1860,18 @@ test_5() {
        # cleanup
        unlinkmany $DIR/$tdir/$tfile-0_ $((ILIMIT + 1)) ||
                error "unlinkmany $DIR/$tdir/$tfile-0_ failed"
-       cleanup_quota_test
 }
 run_test 5 "Chown & chgrp successfully even out of block/file quota"
 
 # test dropping acquire request on master
 test_6() {
-       local LIMIT=3 # 3M
+       local LIMIT=3 # MB
 
        # Clear dmesg so watchdog is not triggered by previous
        # test output
        do_facet ost1 dmesg -c > /dev/null
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        # make sure the system is clean
        local USED=$(getquota -u $TSTUSR global curspace)
@@ -1892,20 +1968,17 @@ test_6() {
                fi
                sleep 1
        done
-
-       cleanup_quota_test
 }
 run_test 6 "Test dropping acquire request on master"
 
 # quota reintegration (global index)
 test_7a() {
        local TESTFILE=$DIR/$tdir/$tfile
-       local LIMIT=20 # 20M
+       local LIMIT=20 # MB
 
        [ "$SLOW" = "no" ] && LIMIT=5
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        # make sure the system is clean
        local USED=$(getquota -u $TSTUSR global curspace)
@@ -1964,18 +2037,15 @@ test_7a() {
        # hardlimit should be cleared on slave during reintegration
        $RUNAS $DD of=$TESTFILE count=$((LIMIT + 1)) oflag=sync ||
                quota_error u $TSTUSR "write error, but expect success"
-
-       cleanup_quota_test
 }
 run_test 7a "Quota reintegration (global index)"
 
 # quota reintegration (slave index)
 test_7b() {
-       local LIMIT="100G"
+       local limit=100000 # MB
        local TESTFILE=$DIR/$tdir/$tfile
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        # make sure the system is clean
        local USED=$(getquota -u $TSTUSR global curspace)
@@ -2004,7 +2074,7 @@ test_7b() {
        lustre_fail mds 0xa02
 
        set_ost_qtype $QTYPE || error "enable ost quota failed"
-       $LFS setquota -u $TSTUSR -b 0 -B $LIMIT -i 0 -I 0 $DIR ||
+       $LFS setquota -u $TSTUSR -b 0 -B ${limit}M -i 0 -I 0 $DIR ||
                error "set quota failed"
 
        # ignore the write error
@@ -2031,13 +2101,12 @@ run_test 7b "Quota reintegration (slave index)"
 
 # quota reintegration (restart mds during reintegration)
 test_7c() {
-       local LIMIT=20 # 20M
+       local LIMIT=20 # MB
        local TESTFILE=$DIR/$tdir/$tfile
 
        [ "$SLOW" = "no" ] && LIMIT=5
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        # make sure the system is clean
        local USED=$(getquota -u $TSTUSR global curspace)
@@ -2075,8 +2144,7 @@ test_7c() {
        # reintegration, write will exceed quota
        $RUNAS $DD of=$TESTFILE count=$((LIMIT + 1)) oflag=sync &&
                quota_error u $TSTUSR "write success, but expect EDQUOT"
-
-       cleanup_quota_test
+       return 0
 }
 run_test 7c "Quota reintegration (restart mds during reintegration)"
 
@@ -2084,10 +2152,9 @@ run_test 7c "Quota reintegration (restart mds during reintegration)"
 test_7d(){
        local TESTFILE=$DIR/$tdir/$tfile
        local TESTFILE1="$DIR/$tdir/$tfile"-1
-       local limit=20 #20M
+       local limit=20 # MB
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        set_ost_qtype "none" || error "disable ost quota failed"
        $LFS setquota -u $TSTUSR -B ${limit}M $DIR ||
@@ -2111,8 +2178,7 @@ test_7d(){
 
        $RUNAS2 $DD of=$TESTFILE1 count=$((limit + 1)) oflag=sync &&
                quota_error u $TSTUSR2 "$TSTUSR2 write success, expect EDQUOT"
-
-       cleanup_quota_test
+       return 0
 }
 run_test 7d "Quota reintegration (Transfer index in multiple bulks)"
 
@@ -2131,11 +2197,10 @@ test_7e() {
                        skip "requires zpool with active userobj_accounting"
        }
 
-       local ilimit=$((1024 * 2)) # 2k inodes
+       local ilimit=$((1024 * 2)) # inodes
        local TESTFILE=$DIR/${tdir}-1/$tfile
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        # make sure the system is clean
        local USED=$(getquota -u $TSTUSR global curinodes)
@@ -2197,8 +2262,6 @@ test_7e() {
 
        $RUNAS unlinkmany $TESTFILE $((ilimit + 1)) || error "unlink failed"
        rmdir $DIR/${tdir}-1 || error "unlink remote dir failed"
-
-       cleanup_quota_test
 }
 run_test 7e "Quota reintegration (inode limits)"
 
@@ -2208,7 +2271,6 @@ test_8() {
        local FILE_LIMIT=1000000
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        set_mdt_qtype $QTYPE || error "enable mdt quota failed"
        set_ost_qtype $QTYPE || error "enable ost quota failed"
@@ -2233,7 +2295,7 @@ test_8() {
                quota_error a $TSTUSR "dbench failed!"
 
        is_project_quota_supported && change_project -C $DIR/$tdir
-       cleanup_quota_test
+       return 0
 }
 run_test 8 "Run dbench with quota enabled"
 
@@ -2258,7 +2320,6 @@ test_9() {
        check_whether_skip && return 0
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        set_ost_qtype "ug" || error "enable ost quota failed"
 
@@ -2303,7 +2364,6 @@ test_10() {
        local TESTFILE=$DIR/$tdir/$tfile
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        # set limit to root user should fail
        $LFS setquota -u root -b 100G -B 500G -i 1K -I 1M $DIR &&
@@ -2325,15 +2385,12 @@ test_10() {
 
        runas -u 0 -g 0 $DD of=$TESTFILE count=3 oflag=sync ||
                error "write failure, expect success"
-
-       cleanup_quota_test
 }
 run_test 10 "Test quota for root user"
 
 test_11() {
        local TESTFILE=$DIR/$tdir/$tfile
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        set_mdt_qtype "ug" || error "enable mdt quota failed"
        $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I 1 $DIR ||
@@ -2348,26 +2405,23 @@ test_11() {
        $SHOW_QUOTA_USER
        local USED=$(getquota -u $TSTUSR global curinodes)
        [ $USED -ge 2 ] || error "Used inodes($USED) is less than 2"
-
-       cleanup_quota_test
 }
 run_test 11 "Chown/chgrp ignores quota"
 
 test_12a() {
        [ "$OSTCOUNT" -lt "2" ] && skip "needs >= 2 OSTs"
 
-       local blimit=22 # 22M
+       local blimit=22 # MB
        local blk_cnt=$((blimit - 5))
        local TESTFILE0="$DIR/$tdir/$tfile"-0
        local TESTFILE1="$DIR/$tdir/$tfile"-1
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        set_ost_qtype "u" || error "enable ost quota failed"
        quota_show_check b u $TSTUSR
 
-       $LFS setquota -u $TSTUSR -b 0 -B "$blimit"M -i 0 -I 0 $DIR ||
+       $LFS setquota -u $TSTUSR -b 0 -B ${blimit}M -i 0 -I 0 $DIR ||
                error "set quota failed"
 
        $LFS setstripe $TESTFILE0 -c 1 -i 0 || error "setstripe $TESTFILE0 failed"
@@ -2391,20 +2445,17 @@ test_12a() {
        echo "Write to ost1 after space freed from ost0..."
        $RUNAS $DD of=$TESTFILE1 count=$blk_cnt oflag=sync ||
                quota_error a $TSTUSR "rebalancing failed"
-
-       cleanup_quota_test
 }
 run_test 12a "Block quota rebalancing"
 
 test_12b() {
        [ "$MDSCOUNT" -lt "2" ] && skip "needs >= 2 MDTs"
 
-       local ilimit=$((1024 * 2)) # 2k inodes
+       local ilimit=$((1024 * 2)) # inodes
        local TESTFILE0=$DIR/$tdir/$tfile
        local TESTFILE1=$DIR/${tdir}-1/$tfile
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        $LFS mkdir -i 1 $DIR/${tdir}-1 || error "create remote dir failed"
        chmod 0777 $DIR/${tdir}-1
@@ -2435,8 +2486,6 @@ test_12b() {
        $RUNAS unlinkmany $TESTFILE1 $((ilimit / 2)) ||
                error "unlink mdt1 files failed"
        rmdir $DIR/${tdir}-1 || error "unlink remote dir failed"
-
-       cleanup_quota_test
 }
 run_test 12b "Inode quota rebalancing"
 
@@ -2446,7 +2495,6 @@ test_13(){
        local procf="ldlm.namespaces.*MDT0000-lwp-OST0000.lru_size"
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        set_ost_qtype "u" || error "enable ost quota failed"
        quota_show_check b u $TSTUSR
@@ -2484,8 +2532,6 @@ test_13(){
        local space=$(getquota -u $TSTUSR $OSTUUID curspace)
        [ $limit -le $space ] ||
                error "spare quota isn't released, limit:$limit, space:$space"
-
-       cleanup_quota_test
 }
 run_test 13 "Cancel per-ID lock in the LRU list"
 
@@ -2513,13 +2559,114 @@ test_15(){
 }
 run_test 15 "Set over 4T block quota"
 
+test_16a()
+{
+       (( $CLIENT_VERSION < $(version_code 2.14.55) )) &&
+               skip "Not supported Lustre client before 2.14.55"
+
+       setup_quota_test || error "setup quota failed with $?"
+
+       $LFS setquota -u $TSTUSR -B 500M -I 10K $MOUNT ||
+               error "failed to set quota for user $TSTUSR"
+       $LFS setquota -g $TSTUSR -B 500M -I 10K $MOUNT ||
+               error "failed to set quota for group $TSTUSR"
+
+       $RUNAS $DD of=$DIR/$tdir/$tfile bs=1M count=50 ||
+               quota_error u $TSTUSR "write failure"
+
+       $LFS quota -u $TSTUSR $MOUNT ||
+               quota_error u $TSTUSR "failed to get quota"
+
+       local OSC=$($LCTL dl | grep OST0000-osc-[^M] | awk '{print $4}')
+
+       $LCTL --device %$OSC deactivate
+       stack_trap "$LCTL --device %$OSC activate"
+
+       $LFS quota -v -u $TSTUSR $MOUNT ||
+               quota_error u $TSTUSR "failed to get quota after deactivate OSC"
+       $LFS quota -v -g $TSTUSR $MOUNT ||
+               quota_error g $TSTUSR "failed to get quota after deactivate OSC"
+
+       (( $MDSCOUNT > 1 )) || return 0
+
+       local MDC=$($LCTL dl | grep MDT0001-mdc-[^M] | awk '{print $4}')
+
+       $LCTL --device %$MDC deactivate
+       stack_trap "$LCTL --device %$MDC activate"
+
+       $LFS quota -v -u $TSTUSR $MOUNT ||
+               quota_error u $TSTUSR "failed to get quota after deactivate MDC"
+       $LFS quota -v -g $TSTUSR $MOUNT ||
+               quota_error g $TSTUSR "failed to get quota after deactivate OSC"
+}
+run_test 16a "lfs quota should skip the inactive MDT/OST"
+
+cleanup_16b()
+{
+       stopall
+       formatall
+       setupall
+}
+
+test_16b()
+{
+       (( $CLIENT_VERSION < $(version_code 2.14.55) )) &&
+               skip "Not supported Lustre client before 2.14.55"
+
+       (( $MDSCOUNT >= 3 )) || skip "needs >= 3 MDTs"
+
+       stopall
+       if ! combined_mgs_mds ; then
+               format_mgs
+               start_mgs
+       fi
+
+       add mds1 $(mkfs_opts mds1 $(mdsdevname 1)) --index=0 --reformat \
+               $(mdsdevname 1) $(mdsvdevname 1)
+       add mds2 $(mkfs_opts mds2 $(mdsdevname 2)) --index=1 --reformat \
+               $(mdsdevname 2) $(mdsvdevname 2)
+       add mds3 $(mkfs_opts mds3 $(mdsdevname 3)) --index=100 --reformat \
+               $(mdsdevname 3) $(mdsvdevname 3)
+
+       add ost1 $(mkfs_opts ost1 $(ostdevname 1)) --index=0 --reformat \
+               $(ostdevname 1) $(ostvdevname 1)
+       add ost2 $(mkfs_opts ost2 $(ostdevname 2)) --index=100 --reformat \
+               $(ostdevname 2) $(ostvdevname 2)
+
+       stack_trap cleanup_16b
+
+       start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS || error "MDT1 start failed"
+       start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS || error "MDT2 start failed"
+       start mds3 $(mdsdevname 3) $MDS_MOUNT_OPTS || error "MDT3 start failed"
+       start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "OST1 start failed"
+       start ost2 $(ostdevname 2) $OST_MOUNT_OPTS || error "OST2 start failed"
+
+       mount_client $MOUNT || error "Unable to mount client"
+
+       setup_quota_test || error "setup quota failed with $?"
+       stack_trap cleanup_quota_test EXIT
+
+       $LFS setquota -u $TSTUSR -B 100M -I 10K $MOUNT ||
+               error "failed to set quota for user $TSTUSR"
+       $LFS setquota -g $TSTUSR -B 100M -I 10K $MOUNT ||
+               error "failed to set quota for group $TSTUSR"
+
+       $RUNAS $DD of=$DIR/$tdir/$tfile bs=1M count=10 ||
+               quota_error u $TSTUSR "write failure"
+
+       cnt=$($LFS quota -v -u $TSTUSR $MOUNT | grep -ce "^$FSNAME-[MD|OS]T*")
+       [ $cnt -le 5 ] || quota_error u $TSTUSR "failed to get user quota"
+       cnt=$($LFS quota -v -g $TSTUSR $MOUNT | grep -ce "^$FSNAME-[MD|OS]T*")
+       [ $cnt -le 5 ] || quota_error g $TSTUSR "failed to get group quota"
+}
+run_test 16b "lfs quota should skip the nonexistent MDT/OST"
+
 test_17sub() {
        local err_code=$1
        local BLKS=1    # 1M less than limit
        local TESTFILE=$DIR/$tdir/$tfile
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        # make sure the system is clean
        local USED=$(getquota -u $TSTUSR global curspace)
@@ -2592,15 +2739,14 @@ run_test 17 "DQACQ return recoverable error"
 
 test_18_sub () {
        local io_type=$1
-       local blimit="200m" # 200M
+       local blimit=200 # MB
        local TESTFILE="$DIR/$tdir/$tfile"
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        set_ost_qtype "u" || error "enable ost quota failed"
        log "User quota (limit: $blimit)"
-       $LFS setquota -u $TSTUSR -b 0 -B $blimit -i 0 -I 0 $MOUNT ||
+       $LFS setquota -u $TSTUSR -b 0 -B ${blimit}M -i 0 -I 0 $MOUNT ||
                error "set quota failed"
        quota_show_check b u $TSTUSR
 
@@ -2671,11 +2817,10 @@ test_18() {
 run_test 18 "MDS failover while writing, no watchdog triggered (b14840)"
 
 test_19() {
-       local blimit=5 # 5M
+       local blimit=5 # MB
        local TESTFILE=$DIR/$tdir/$tfile
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        set_ost_qtype $QTYPE || error "enable ost quota failed"
 
@@ -2684,11 +2829,11 @@ test_19() {
        chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
 
        echo "Set user quota (limit: ${blimit}M)"
-       $LFS setquota -u $TSTUSR -b 0 -B "$blimit"M -i 0 -I 0 $MOUNT ||
+       $LFS setquota -u $TSTUSR -b 0 -B ${blimit}M -i 0 -I 0 $MOUNT ||
                error "set user quota failed"
        quota_show_check b u $TSTUSR
        echo "Update quota limits"
-       $LFS setquota -u $TSTUSR -b 0 -B "$blimit"M -i 0 -I 0 $MOUNT ||
+       $LFS setquota -u $TSTUSR -b 0 -B ${blimit}M -i 0 -I 0 $MOUNT ||
                error "set group quota failed"
        quota_show_check b u $TSTUSR
 
@@ -2699,8 +2844,6 @@ test_19() {
        $RUNAS $DD of=$TESTFILE count=$((blimit + 1)) seek=$((blimit + 1)) &&
                quota_error u $TSTUSR "Write success, expect failure"
        $SHOW_QUOTA_USER
-
-       cleanup_quota_test
 }
 run_test 19 "Updating admin limits doesn't zero operational limits(b14790)"
 
@@ -2751,7 +2894,6 @@ test_21() {
        local ILIMIT=1000000
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        set_ost_qtype $QTYPE || error "Enable ost quota failed"
 
@@ -2815,8 +2957,6 @@ test_21() {
                sleep 1
        done
        echo "(dd_pid=$DDPID2, time=$count)successful"
-
-       cleanup_quota_test
 }
 run_test 21 "Setquota while writing & deleting (b16053)"
 
@@ -2864,7 +3004,6 @@ test_23_sub() {
        local LIMIT=$1
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        set_ost_qtype $QTYPE || error "Enable ost quota failed"
 
@@ -2923,11 +3062,10 @@ test_23() {
 run_test 23 "Quota should be honored with directIO (b16125)"
 
 test_24() {
-       local blimit=5 # 5M
+       local blimit=5 # MB
        local TESTFILE="$DIR/$tdir/$tfile"
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        set_ost_qtype $QTYPE || error "enable ost quota failed"
 
@@ -2946,8 +3084,6 @@ test_24() {
        sync_all_data || true
 
        $SHOW_QUOTA_USER | grep '*' || error "no matching *"
-
-       cleanup_quota_test
 }
 run_test 24 "lfs draws an asterix when limit is reached (b16646)"
 
@@ -3026,12 +3162,11 @@ test_27d() {
 run_test 27d "lfs setquota should support fraction block limit"
 
 test_30() {
-       local LIMIT=4 # 4MB
+       local LIMIT=4 # MB
        local TESTFILE="$DIR/$tdir/$tfile"
        local GRACE=10
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        set_ost_qtype "u" || error "enable ost quota failed"
 
@@ -3055,8 +3190,6 @@ test_30() {
        $SHOW_QUOTA_USER
        $RUNAS $DD of=$TESTFILE conv=notrunc oflag=append count=4 &&
                error "grace times were reset"
-       # cleanup
-       cleanup_quota_test
        $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
                $MAX_IQ_TIME $DIR || error "restore grace time failed"
 }
@@ -3064,12 +3197,11 @@ run_test 30 "Hard limit updates should not reset grace times"
 
 # basic usage tracking for user & group
 test_33() {
-       local INODES=10 # 10 files
-       local BLK_CNT=2 # of 2M each
+       local INODES=10 # files
+       local BLK_CNT=2 # MB each
        local TOTAL_BLKS=$((INODES * BLK_CNT * 1024))
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        # make sure the system is clean
        local USED=$(getquota -u $TSTID global curspace)
@@ -3149,12 +3281,11 @@ run_test 33 "Basic usage tracking for user & group & project"
 
 # usage transfer test for user & group & project
 test_34() {
-       local BLK_CNT=2 # 2MB
+       local BLK_CNT=2 # MB
        local project_supported="no"
 
        is_project_quota_supported && project_supported="yes"
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        # make sure the system is clean
        local USED=$(getquota -u $TSTID global curspace)
@@ -3234,17 +3365,15 @@ test_34() {
                [ $USED -lt $BLK_CNT ] && error \
                        "Used space for group $TSTPRJID is $USED, expected $BLK_CNT"
        fi
-
-       cleanup_quota_test
+       return 0
 }
 run_test 34 "Usage transfer for user & group & project"
 
 # usage is still accessible across restart
 test_35() {
-       local BLK_CNT=2 # MB
+       local BLK_CNT=2 # MB
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        echo "Write file..."
        $RUNAS $DD of=$DIR/$tdir/$tfile count=$BLK_CNT 2>/dev/null ||
@@ -3339,8 +3468,6 @@ test_35() {
                        error "Used space for project $TSTPRJID isn't " \
                                "increased orig:$ORIG_PRJ_SPACE, now:$USED"
        fi
-
-       cleanup_quota_test
 }
 run_test 35 "Usage is still accessible across reboot"
 
@@ -3351,7 +3478,6 @@ test_37() {
                skip "Old server doesn't have LU-5006 fix."
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        # make sure the system is clean
        local USED=$(getquota -u $TSTID global curspace)
@@ -3372,8 +3498,6 @@ test_37() {
 
        USED=$(getquota -u $TSTID global curspace)
        [ $USED -ne 0 ] || quota_error u $TSTUSR "Used space is 0"
-
-       cleanup_quota_test
 }
 run_test 37 "Quota accounted properly for file created by 'lfs setstripe'"
 
@@ -3385,7 +3509,6 @@ test_38() {
        [ "$UID" != 0 ] && skip_env "must run as root" && return
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        # make sure the system is clean
        local USED=$(getquota -u $TSTID global curspace)
@@ -3410,7 +3533,7 @@ test_38() {
 
        local procf="osd-$mds1_FSTYPE.$FSNAME-MDT0000"
        procf=${procf}.quota_slave.acct_user
-       local accnt_cnt
+       local acct_cnt
 
        acct_cnt=$(do_facet mds1 $LCTL get_param $procf | grep "id:" | \
                   awk '{if ($3 < 10000) {print $3}}' | wc -l)
@@ -3420,8 +3543,6 @@ test_38() {
                do_facet mds1 $LCTL get_param $procf
                error "skipped id entries"
        }
-
-       cleanup_quota_test
 }
 run_test 38 "Quota accounting iterator doesn't skip id entries"
 
@@ -3445,10 +3566,8 @@ test_39() {
        mount
        setupall
        projectid=$(lfs project $TESTFILE | awk '{print $1}')
-       [ $projectid -ne 1024 ] &&
+       [ $projectid -eq 1024 ] ||
                error "Project id should be 1024 not $projectid"
-
-       cleanup_quota_test
 }
 run_test 39 "Project ID interface works correctly"
 
@@ -3466,9 +3585,7 @@ test_40a() {
 
        ln $dir1/1 $dir2/1_link &&
                error "Hard link across different project quota should fail"
-       rm -rf $dir1 $dir2
-
-       cleanup_quota_test
+       return 0
 }
 run_test 40a "Hard link across different project ID"
 
@@ -3485,11 +3602,7 @@ test_40b() {
 
        mv $dir1/1 $dir2/2 || error "mv failed $?"
        local projid=$(lfs project $dir2/2 | awk '{print $1}')
-       if [ "$projid" != "2" ]; then
-               error "project id expected 2 not $projid"
-       fi
-       rm -rf $dir1 $dir2
-       cleanup_quota_test
+       [ "$projid" -eq 2 ] || error "project id expected 2 not $projid"
 }
 run_test 40b "Mv across different project ID"
 
@@ -3512,13 +3625,9 @@ test_40c() {
                error "file under remote dir expected 1 not $projid"
 
        #Agent inode should be ignored for project quota
-       USED=$(getquota -p 1 global curinodes)
-       [ "$USED" != "3" ] &&
-               error "file count expected 3 got $USED"
-
-       rm -rf $dir
-       cleanup_quota_test
-       return 0
+       local used=$(getquota -p 1 global curinodes)
+       [ $used -eq 3 ] ||
+               error "file count expected 3 got $used"
 }
 run_test 40c "Remote child Dir inherit project quota properly"
 
@@ -3548,12 +3657,9 @@ test_40d() {
        done
 
        # account should be 1 + (2 + 1) *10 + 1 * 5
-       USED=$(getquota -p $TSTPRJID global curinodes)
-       [ "$USED" == "36" ] ||
-               error "file count expected 36 got $USED"
-
-       rm -rf $dir
-       cleanup_quota_test
+       local used=$(getquota -p $TSTPRJID global curinodes)
+       [ $used -eq 36 ] ||
+               error "file count expected 36 got $used"
 }
 run_test 40d "Stripe Directory inherit project quota properly"
 
@@ -3561,7 +3667,6 @@ test_41() {
        is_project_quota_supported ||
                skip "Project quota is not supported"
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
        local dir="$DIR/$tdir/dir"
        local blimit=102400
        local ilimit=4096
@@ -3596,10 +3701,70 @@ test_41() {
                 awk '/$FSNAME/ { printf \\\"%d %d \\\", \\\$2,\\\$3 }'" \
                "$expected" ||
                error "failed to get correct statfs for project quota"
+}
+run_test 41 "df should return projid-specific values"
+
+test_delete_qid()
+{
+       local qslv_file=$1
+       local qtype_file=$2
+       local qtype=$3
+       local qid=$4
+       local osd="osd-ldiskfs"
+
+       [ "$ost1_FSTYPE" = zfs ] && osd="osd-zfs"
+
+       rm -f $DIR/$tdir/$tfile
+       $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile
+       chmod a+rw $DIR/$tdir/$tfile
+
+       $LFS setquota $qtype $qid -B 300M $MOUNT
+       $RUNAS dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 ||
+               error "failed to dd"
+
+       do_facet $SINGLEMDS \
+               "cat /proc/fs/lustre/qmt/$FSNAME-QMT0000/dt-0x0/$qtype_file |
+                grep -E 'id: *$qid'" || error "QMT: no qid $qid is found"
+       echo $osd
+       do_facet ost1 \
+               "cat /proc/fs/lustre/$osd/$FSNAME-OST0000/$qslv_file |
+                grep -E 'id: *$qid'" || error "QSD: no qid $qid is found"
+
+       $LFS setquota $qtype $qid --delete $MOUNT
+       do_facet $SINGLEMDS \
+               "cat /proc/fs/lustre/qmt/$FSNAME-QMT0000/dt-0x0/$qtype_file |
+                grep -E 'id: *$qid'" && error "QMT: qid $qid is not deleted"
+       sleep 5
+       do_facet ost1 \
+               "cat /proc/fs/lustre/$osd/$FSNAME-OST0000/$qslv_file |
+                grep -E 'id: *$qid'" && error "QSD: qid $qid is not deleted"
+
+       $LFS setquota $qtype $qid -B 500M $MOUNT
+       $RUNAS dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 ||
+               error "failed to dd"
+       do_facet $SINGLEMDS \
+               "cat /proc/fs/lustre/qmt/$FSNAME-QMT0000/dt-0x0/$qtype_file |
+                grep -E 'id: *$qid'" || error "QMT: qid $pid is not recreated"
+       cat /proc/fs/lustre/$osd/$FSNAME-OST0000/$qslv_file
+       do_facet ost1 \
+               "cat /proc/fs/lustre/$osd/$FSNAME-OST0000/$qslv_file |
+                grep -E 'id: *$qid'" || error "QSD: qid $qid is not recreated"
+}
+
+test_48()
+{
+       setup_quota_test || error "setup quota failed with $?"
+       set_ost_qtype $QTYPE || error "enable ost quota failed"
+       quota_init
+
+       test_delete_qid "quota_slave/limit_user" "glb-usr" "-u" $TSTID
+       test_delete_qid "quota_slave/limit_group" "glb-grp" "-g" $TSTID
+       is_project_quota_supported &&
+           test_delete_qid "quota_slave/limit_project" "glb-prj" "-p" "10000"
 
        cleanup_quota_test
 }
-run_test 41 "df should return projid-specific values"
+run_test 48 "lfs quota --delete should delete quota project ID"
 
 test_50() {
        ! is_project_quota_supported &&
@@ -3622,10 +3787,7 @@ test_50() {
 
        # 1(projid 0 dir) + 1(projid 2 dir) + 20(projid 2 files)
        count=$($LFS find ! --projid 1 $DIR/$tdir | wc -l)
-       [ "$count" != 22 ] && error "expected 22 but got $count"
-
-       rm -rf $dir1 $dir2
-       cleanup_quota_test
+       [ $count -eq 22 ] || error "expected 22 but got $count"
 }
 run_test 50 "Test if lfs find --projid works"
 
@@ -3654,57 +3816,95 @@ test_51() {
        #try mv to dir
        mv $DIR/$tdir/6 $dir/7
        used=$(getquota -p 1 global curinodes)
-       [ $used != "6" ] && error "expected 6 got $used"
-
-       rm -rf $dir
-       cleanup_quota_test
+       [ $used -eq 6 ] || error "expected 6 got $used"
 }
 run_test 51 "Test project accounting with mv/cp"
 
 test_52() {
        ! is_project_quota_supported &&
                skip "Project quota is not supported"
-       setup_quota_test || error "setup quota failed with $?"
-       local dir="$DIR/$tdir/dir"
-       mkdir $dir && change_project -sp 1 $dir
 
-       touch $DIR/$tdir/file
-       #Try renaming a file into the project.  This should fail.
-       for num in $(seq 1 2000); do
-               mrename $DIR/$tdir/file $dir/file >&/dev/null &&
-                       error "rename should fail"
-       done
-       rm -rf $dir
-       cleanup_quota_test
-}
-run_test 52 "Rename across different project ID"
+       (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
+               skip "Need MDS version at least 2.14.55"
 
-test_53() {
-       ! is_project_quota_supported &&
-               skip "Project quota is not supported"
        setup_quota_test || error "setup quota failed with $?"
-       local dir="$DIR/$tdir/dir"
-       mkdir $dir && change_project -s $dir
-       lfs project -d $dir | grep P || error "inherit attribute should be set"
 
-       change_project -C $dir
-       lfs project -d $dir | grep P &&
-               error "inherit attribute should be cleared"
+       local dir1=$DIR/$tdir/t52_dir1
+       local dir2=$DIR/$tdir/t52_dir2
 
-       rm -rf $dir
-       cleanup_quota_test
-}
-run_test 53 "Project inherit attribute could be cleared"
+       mkdir $dir1 || error "failed to mkdir $dir1"
+       mkdir $dir2 || error "failed to mkdir $dir2"
 
-test_54() {
-       ! is_project_quota_supported &&
-               skip "Project quota is not supported"
-       setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
-       local testfile="$DIR/$tdir/$tfile-0"
+       $LFS project -sp 1000 $dir1 || error "fail to set project on $dir1"
+       $LFS project -sp 1001 $dir2 || error "fail to set project on $dir2"
 
-       #set project ID/inherit attribute
-       change_project -sp $TSTPRJID $DIR/$tdir
+       $DD if=/dev/zero of=/$dir1/$tfile bs=1M count=100 ||
+               error "failed to create and write $tdir1/$tfile"
+
+       cancel_lru_locks osc
+       sync; sync_all_data || true
+
+       local attrs=($(lsattr -p $dir1/$tfile))
+       (( ${attrs[0]} == 1000 )) ||
+               error "project ID on $dir1/$tfile is not inherited"
+
+       $LFS quota -p 1000 $DIR
+       $LFS quota -p 1001 $DIR
+
+       local prev_used=$(getquota -p 1000 global curspace)
+       local prev_used2=$(getquota -p 1001 global curspace)
+
+       mrename $dir1 $dir2/tdir || log "rename directory return $?"
+
+       local inum_before=$(ls -i $dir1/$tfile | awk '{print $1}')
+       mrename $dir1/$tfile $dir2/$tfile || error "failed to rename file"
+       local inum_after=$(ls -i $dir2/$tfile | awk '{print $1}')
+
+       attrs=($(lsattr -p $dir2/$tfile))
+       (( ${attrs[0]} == 1001 )) ||
+               error "project ID is not updated after rename"
+
+       (( $inum_before == $inum_after )) ||
+               error "inode is changed after rename: $inum_before, $inum_after"
+
+       sync_all_data || true
+
+       $LFS quota -p 1000 $DIR
+       $LFS quota -p 1001 $DIR
+
+       local new_used=$(getquota -p 1000 global curspace)
+       local new_used2=$(getquota -p 1001 global curspace)
+
+       (( $prev_used >= $new_used + 102400 )) ||
+               error "quota is not deducted from old project ID"
+       (( $prev_used2 <= $new_used2 - 102400 )) ||
+               error "quota is not added for the new project ID"
+}
+run_test 52 "Rename normal file across project ID"
+
+test_53() {
+       ! is_project_quota_supported &&
+               skip "Project quota is not supported"
+       setup_quota_test || error "setup quota failed with $?"
+       local dir="$DIR/$tdir/dir"
+       mkdir $dir && change_project -s $dir
+       [[ $($LFS project -d $dir) =~ " P " ]] ||
+               error "inherit attribute should be set"
+
+       change_project -C $dir
+       [[ $($LFS project -d $dir) =~ " - " ]] ||
+               error "inherit attribute should be cleared"
+}
+run_test 53 "Project inherit attribute could be cleared"
+
+test_54() {
+       ! is_project_quota_supported &&
+               skip "Project quota is not supported"
+       setup_quota_test || error "setup quota failed with $?"
+       local testfile="$DIR/$tdir/$tfile-0"
+
+       #set project ID/inherit attribute
+       change_project -sp $TSTPRJID $DIR/$tdir
        $RUNAS createmany -m ${testfile} 100 ||
                error "create many files failed"
 
@@ -3745,8 +3945,6 @@ test_54() {
        #cleanup
        unlinkmany ${testfile} 100 ||
                error "unlink many files failed"
-
-       cleanup_quota_test
 }
 run_test 54 "basic lfs project interface test"
 
@@ -3788,8 +3986,6 @@ test_55() {
        error "chgrp should succeed"
 
        $LFS quota -v -g $TSTUSR2 $DIR
-
-       cleanup_quota_test
 }
 run_test 55 "Chgrp should be affected by group quota"
 
@@ -3807,8 +4003,6 @@ test_56() {
                $LFS quota -t -u $DIR
                error "expected grace time: 10s;10s, got:$grace_time"
        fi
-
-       cleanup_quota_test
 }
 run_test 56 "lfs quota -t should work well"
 
@@ -3818,20 +4012,15 @@ test_57() {
        local dir="$DIR/$tdir/dir"
        mkdir -p $dir
        mkfifo $dir/pipe
-       #try to change pipe file should not hang and return failure
-       wait_update_facet client "$LFS project -sp 1 $dir/pipe 2>&1 |
-               awk -F ':' '{ print \\\$2 }'" \
-                       " unable to get xattr for fifo '$dir/pipe'" || return 1
        #command can process further if it hit some errors
+       $LFS project -sp 1 $dir/pipe
        touch $dir/aaa $dir/bbb
        mkdir $dir/subdir -p
        touch $dir/subdir/aaa $dir/subdir/bbb
        #create one invalid link file
        ln -s $dir/not_exist_file $dir/ccc
        local cnt=$(lfs project -r $dir 2>/dev/null | wc -l)
-       [ $cnt -eq 5 ] || error "expected 5 got $cnt"
-
-       cleanup_quota_test
+       [ $cnt -eq 7 ] || error "expected 7 got $cnt"
 }
 run_test 57 "lfs project could tolerate errors"
 
@@ -3847,7 +4036,6 @@ test_59() {
        touch $testfile && lfs project -sp 1 $testfile
 
        enable_project_quota
-       cleanup_quota_test
 }
 run_test 59 "lfs project dosen't crash kernel with project disabled"
 
@@ -3855,7 +4043,6 @@ test_60() {
        [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
                skip "Needs MDS version 2.11.53 or later."
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        local testfile=$DIR/$tdir/$tfile
        local limit=100
@@ -3876,8 +4063,6 @@ test_60() {
        # root user can overrun quota
        runas -u 0 -g 0 touch $DIR/$tdir/foo ||
                error "root user should succeed"
-
-       cleanup_quota_test
 }
 run_test 60 "Test quota for root with setgid"
 
@@ -3887,7 +4072,7 @@ test_default_quota() {
                skip "Not supported before 2.11.51."
 
        local qtype=$1
-       local qpool=$2
+       local qres_type=$2
        local qid=$TSTUSR
        local qprjid=$TSTPRJID
        local qdtype="-U"
@@ -3895,6 +4080,7 @@ test_default_quota() {
        local qh="-B"
        local LIMIT=20480 #20M disk space
        local TESTFILE="$DIR/$tdir/$tfile-0"
+       local $qpool_cmd
 
        [ $qtype == "-p" ] && ! is_project_quota_supported &&
                echo "Project quota is not supported" && return 0
@@ -3906,14 +4092,19 @@ test_default_quota() {
                qid=$qprjid
        }
 
-       [ $qpool == "meta" ] && {
+       [ $qres_type == "meta" ] && {
                LIMIT=10240 #10K inodes
                qs="-i"
                qh="-I"
        }
+       [ ! -z "$3" ] && {
+               qpool_cmd="--pool $3"
+               # pool quotas don't work properly without global limit
+               $LFS setquota $qtype $qid -B1T -b1T $DIR ||
+                       error "set global limit failed"
+       }
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        quota_init
 
@@ -3922,19 +4113,19 @@ test_default_quota() {
        set_ost_qtype $QTYPE || error "enable ost quota failed"
 
        log "set to use default quota"
-       $LFS setquota $qtype $qid -d $DIR ||
+       $LFS setquota $qtype $qid -d $qpool_cmd $DIR ||
                error "set $qid to use default quota failed"
 
        log "set default quota"
-       $LFS setquota $qdtype $qs ${LIMIT} $qh ${LIMIT} $DIR ||
+       $LFS setquota $qdtype $qpool_cmd $qs ${LIMIT} $qh ${LIMIT} $DIR ||
                error "set $qid default quota failed"
 
        log "get default quota"
        $LFS quota $qdtype $DIR || error "get default quota failed"
 
-       if [ $qpool == "data" ]; then
-               local SLIMIT=$($LFS quota $qdtype $DIR | grep "$MOUNT" | \
-                                                       awk '{print $2}')
+       if [ $qres_type == "data" ]; then
+               local SLIMIT=$($LFS quota $qpool_cmd $qdtype $DIR | \
+                               grep "$MOUNT" | awk '{print $2}')
                [ $SLIMIT -eq $LIMIT ] ||
                        error "the returned default quota is wrong"
        else
@@ -3948,13 +4139,14 @@ test_default_quota() {
        local USED=$(getquota $qtype $qid global curspace)
        [ $USED -ne 0 ] && error "Used space for $qid isn't 0."
 
-       $LFS setstripe $TESTFILE -c 1 || error "setstripe $TESTFILE failed"
+       $LFS setstripe $TESTFILE -c 1 $qpool_cmd ||
+                       error "setstripe $TESTFILE failed"
        chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
 
        [ $qtype == "-p" ] && change_project -sp $TSTPRJID $DIR/$tdir
 
        log "Test not out of quota"
-       if [ $qpool == "data" ]; then
+       if [ $qres_type == "data" ]; then
                $RUNAS $DD of=$TESTFILE count=$((LIMIT/2 >> 10)) oflag=sync ||
                        quota_error $qtype $qid "write failed, expect succeed"
        else
@@ -3969,7 +4161,7 @@ test_default_quota() {
        cancel_lru_locks osc
        cancel_lru_locks mdc
        sync; sync_all_data || true
-       if [ $qpool == "data" ]; then
+       if [ $qres_type == "data" ]; then
                $RUNAS $DD of=$TESTFILE count=$((LIMIT*2 >> 10)) oflag=sync &&
                        quota_error $qtype $qid "write succeed, expect EDQUOT"
        else
@@ -3979,15 +4171,24 @@ test_default_quota() {
                unlinkmany $TESTFILE $((LIMIT*2))
        fi
 
+       rm -f $TESTFILE
+       $LFS setstripe $TESTFILE -c 1 $qpool_cmd ||
+                       error "setstripe $TESTFILE failed"
+       chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
+
        log "Increase default quota"
+
+       # LU-4505: sleep 5 seconds to enable quota acquire
+       sleep 5
+
        # increase default quota
-       $LFS setquota $qdtype $qs $((LIMIT*3)) $qh $((LIMIT*3)) $DIR ||
-               error "set default quota failed"
+       $LFS setquota $qdtype $qpool_cmd $qs $((LIMIT*3)) \
+               $qh $((LIMIT*3)) $DIR || error "set default quota failed"
 
        cancel_lru_locks osc
        cancel_lru_locks mdc
        sync; sync_all_data || true
-       if [ $qpool == "data" ]; then
+       if [ $qres_type == "data" ]; then
                $RUNAS $DD of=$TESTFILE count=$((LIMIT*2 >> 10)) oflag=sync ||
                        quota_error $qtype $qid "write failed, expect succeed"
        else
@@ -3998,13 +4199,13 @@ test_default_quota() {
        fi
 
        log "Set quota to override default quota"
-       $LFS setquota $qtype $qid $qs ${LIMIT} $qh ${LIMIT} $DIR ||
+       $LFS setquota $qtype $qid $qpool_cmd $qs ${LIMIT} $qh ${LIMIT} $DIR ||
                error "set $qid quota failed"
 
        cancel_lru_locks osc
        cancel_lru_locks mdc
        sync; sync_all_data || true
-       if [ $qpool == "data" ]; then
+       if [ $qres_type == "data" ]; then
                $RUNAS $DD of=$TESTFILE count=$((LIMIT*2 >> 10)) oflag=sync &&
                        quota_error $qtype $qid "write succeed, expect EQUOT"
        else
@@ -4015,13 +4216,17 @@ test_default_quota() {
        fi
 
        log "Set to use default quota again"
-       $LFS setquota $qtype $qid -d $DIR ||
+
+       # LU-4505: sleep 5 seconds to enable quota acquire
+       sleep 5
+
+       $LFS setquota $qtype $qid -d $qpool_cmd $DIR ||
                error "set $qid to use default quota failed"
 
        cancel_lru_locks osc
        cancel_lru_locks mdc
        sync; sync_all_data || true
-       if [ $qpool == "data" ]; then
+       if [ $qres_type == "data" ]; then
                $RUNAS $DD of=$TESTFILE count=$((LIMIT*2 >> 10)) oflag=sync ||
                        quota_error $qtype $qid "write failed, expect succeed"
        else
@@ -4035,11 +4240,11 @@ test_default_quota() {
        rm -f $TESTFILE
        wait_delete_completed || error "wait_delete_completed failed"
        sync_all_data || true
-       $LFS setquota $qdtype -b 0 -B 0 -i 0 -I 0 $DIR ||
+
+       $LFS setquota $qdtype $qpool_cmd $qs 0 $qh 0 $DIR ||
                error "reset default quota failed"
-       $LFS setquota $qtype $qid -b 0 -B 0 -i 0 -I 0 $DIR ||
+       $LFS setquota $qtype $qid $qpool_cmd $qs 0 $qh 0 $DIR ||
                error "reset quota failed"
-
        cleanup_quota_test
 }
 
@@ -4056,7 +4261,8 @@ run_test 61 "default quota tests"
 test_62() {
        ! is_project_quota_supported &&
                skip "Project quota is not supported"
-        [[ "$(chattr -h 2>&1)" =~ "project" ]] ||
+       [[ "$(chattr -h 2>&1)" =~ "project" ||
+          "$(chattr -h 2>&1)" =~ "pRVf" ]] ||
                skip "chattr did not support project quota"
        setup_quota_test || error "setup quota failed with $?"
        local testdir=$DIR/$tdir/
@@ -4073,7 +4279,7 @@ test_62() {
        chattr -P $testdir || error "root failed to clear inherit"
        [[ $($LFS project -d $testdir) =~ "P" ]] &&
                error "inherit attribute should be cleared"
-       cleanup_quota_test
+       return 0
 }
 run_test 62 "Project inherit should be only changed by root"
 
@@ -4093,7 +4299,6 @@ test_dom() {
        [ $qtype == "p" ] && qid=$TSTPRJID
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        quota_init
 
@@ -4173,13 +4378,11 @@ test_dom() {
        $RUNAS $DD of=$DIR/$tdir/file count=$((LIMIT/2048 + 10)) oflag=sync &&
                quota_error $qtype $qid "write succeed, expect EDQUOT"
 
-       rm -f $DIR/$tdir/*
+       rm -fr $DIR/$tdir
        rm -fr $DIR/$tdir_dom
 
        $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I 0 $DIR ||
                error "reset usr quota failed"
-
-       cleanup_quota_test
 }
 
 test_63() {
@@ -4197,19 +4400,23 @@ test_64() {
 
        touch $dir1/file
        ln -s $dir1/file $dir1/file_link
+       mkfifo $dir1/fifo
 
-       $LFS project -sp $TSTPRJID $dir1/file_link >&/dev/null &&
-               error "set symlink file's project should fail"
+       $LFS project -srp $TSTPRJID $dir1 >&/dev/null ||
+               error "set project should succeed"
 
-       $LFS project $TSTPRJID $dir1/file_link >&/dev/null &&
-               error "get symlink file's project should fail"
+       used=$(getquota -p $TSTPRJID global curinodes)
+       [ $used -eq 4 ] || error "expected 4 got $used"
+       $LFS project -rC $dir1 >&/dev/null ||
+               error "clear project should succeed"
 
-       cleanup_quota_test
+       used=$(getquota -p $TSTPRJID global curinodes)
+       [ $used -eq 0 ] || error "expected 0 got $used"
 }
-run_test 64 "lfs project on symlink files should fail"
+run_test 64 "lfs project on non dir/files should succeed"
 
 test_65() {
-       local SIZE=10 #10M
+       local SIZE=10 # MB
        local TESTFILE="$DIR/$tdir/$tfile-0"
 
        setup_quota_test || error "setup quota failed with $?"
@@ -4227,14 +4434,10 @@ test_65() {
        local quota_g=$($LFS quota -g $TSTUSR $DIR)
        local quota_all=$($RUNAS $LFS quota $DIR)
 
-       [ "$(echo "$quota_all" | head -n3)" != "$quota_u" ] &&
+       [ "$(echo "$quota_all" | head -n3)" == "$quota_u" ] ||
                error "usr quota not match"
-       [ "$(echo "$quota_all" | tail -n3)" != "$quota_g" ] &&
+       [ "$(echo "$quota_all" | tail -n3)" == "$quota_g" ] ||
                error "grp quota not match"
-
-       rm -f $TESTFILE
-       # cleanup
-       cleanup_quota_test
 }
 run_test 65 "Check lfs quota result"
 
@@ -4244,16 +4447,15 @@ test_66() {
        [ "$MDS1_VERSION" -lt $(version_code 2.12.4) ] &&
                skip "Not supported before 2.12.4"
        setup_quota_test || error "setup quota failed with $?"
-       stack_trap cleanup_quota_test EXIT
        local old=$(do_facet mds1 $LCTL get_param -n \
                    mdt.*.enable_chprojid_gid | head -1)
        local testdir=$DIR/$tdir/foo
 
        do_facet mds1 $LCTL set_param mdt.*.enable_chprojid_gid=0
-       stack_trap "do_facet mds1 $LCTL set_param mdt.*.enable_chprojid_gid=0" \
-               EXIT
+       stack_trap "do_facet mds1 $LCTL \
+               set_param mdt.*.enable_chprojid_gid=$old" EXIT
 
-       test_mkdir -i 0 -c 1 $testdir || error "failed to mkdir"
+       mkdir_on_mdt0 $testdir || error "failed to mkdir"
        chown -R $TSTID:$TSTID $testdir
        change_project -sp $TSTPRJID $testdir
        $RUNAS mkdir $testdir/foo || error "failed to mkdir foo"
@@ -4279,8 +4481,6 @@ test_66() {
 
        change_project -p $TSTPRJID $testdir/bar || error \
                "root should be able to change its own file's projid"
-
-       cleanup_quota_test
 }
 run_test 66 "nonroot user can not change project state in default"
 
@@ -4323,7 +4523,7 @@ getgranted() {
 }
 
 test_67() {
-       local limit=20  # 20M
+       local limit=20 # MB
        local testfile="$DIR/$tdir/$tfile-0"
        local testfile2="$DIR/$tdir/$tfile-1"
        local testfile3="$DIR/$tdir/$tfile-2"
@@ -4337,7 +4537,6 @@ test_67() {
                skip "ZFS grants some block space together with inode"
 
        setup_quota_test || error "setup quota failed with $?"
-       trap cleanup_quota_test EXIT
 
        # enable ost quota
        set_ost_qtype $QTYPE || error "enable ost quota failed"
@@ -4437,11 +4636,8 @@ test_67() {
        wait_delete_completed || error "wait_delete_completed failed"
        sync_all_data || true
        used=$(getquota -u $TSTUSR global curspace)
-       [ $used -ne 0 ] && quota_error u $TSTUSR \
+       [ $used -eq 0 ] || quota_error u $TSTUSR \
                "user quota isn't released after deletion"
-       resetquota -u $TSTUSR
-
-       cleanup_quota_test
 }
 run_test 67 "quota pools recalculation"
 
@@ -4450,6 +4646,11 @@ get_slave_nr() {
        local qtype=$2
        local nr
 
+       wait_update_facet mds1 \
+               "$LCTL get_param -n qmt.$FSNAME-QMT0000.dt-$pool.info \
+                       >/dev/null 2>&1 || echo foo" "" ||
+       error "mds1: failed to create quota pool $pool"
+
        do_facet mds1 $LCTL get_param -n qmt.$FSNAME-QMT0000.dt-$pool.info |
                awk '/usr/ {getline; print $2}'
 }
@@ -4460,7 +4661,6 @@ test_68()
 
        mds_supports_qp
        setup_quota_test || error "setup quota failed with $?"
-       stack_trap cleanup_quota_test EXIT
 
        # enable ost quota
        set_ost_qtype $QTYPE || error "enable ost quota failed"
@@ -4498,24 +4698,21 @@ test_68()
 
        # Check again that all is fine with global pool
        nr=$(get_slave_nr "0x0" "usr")
-       [[ $nr != $((OSTCOUNT + MDSCOUNT)) ]] &&
+       [[ $nr == $((OSTCOUNT + MDSCOUNT)) ]] ||
                error "Slave_nr $nr for global pool != ($OSTCOUNT + $MDSCOUNT)"
-
-       cleanup_quota_test
 }
 run_test 68 "slave number in quota pool changed after each add/remove OST"
 
 test_69()
 {
-       local global_limit=200  # 200M
-       local limit=10  # 10M
+       local global_limit=200 # MB
+       local limit=10 # MB
        local testfile="$DIR/$tdir/$tfile-0"
        local dom0="$DIR/$tdir/dom0"
        local qpool="qpool1"
 
        mds_supports_qp
        setup_quota_test || error "setup quota failed with $?"
-       stack_trap cleanup_quota_test EXIT
 
        # enable ost quota
        set_ost_qtype $QTYPE || error "enable ost quota failed"
@@ -4563,15 +4760,13 @@ test_69()
 
        $RUNAS dd if=/dev/zero of="$dom0/f1" bs=1K count=512 seek=512 \
                oflag=sync || quota_error u $TSTUSR "write failed"
-
-       cleanup_quota_test
 }
 run_test 69 "EDQUOT at one of pools shouldn't affect DOM"
 
-test_70()
+test_70a()
 {
        local qpool="qpool1"
-       local limit=20
+       local limit=20 # MB
        local err=0
        local bhard
 
@@ -4579,7 +4774,6 @@ test_70()
                skip "Needs a client >= $VERSION_WITH_QP"
 
        setup_quota_test || error "setup quota failed with $?"
-       stack_trap cleanup_quota_test EXIT
 
        # MDS returns EFAULT for unsupported quotactl command
        [[ $MDS1_VERSION -lt $(version_code $VERSION_WITH_QP) ]] && err=14
@@ -4603,15 +4797,37 @@ test_70()
        $LFS quota -u $TSTUSR --pool $qpool $DIR
        rc=$?
        [ $rc -eq $err ] || error "quota res $rc != $err"
+}
+run_test 70a "check lfs setquota/quota with a pool option"
 
-       cleanup_quota_test
+test_70b()
+{
+       local glbl_hard=200 # 200M
+       local glbl_soft=100 # 100M
+       local pool_hard=10 # 10M
+       local qpool="qpool1"
+
+       pool_add $qpool || error "pool_add failed"
+       pool_add_targets $qpool 0 1 || error "pool_add_targets failed"
+
+       $LFS setquota -u $TSTUSR -b ${glbl_soft}M -B ${glbl_hard}M $DIR ||
+               error "set user quota failed"
+       $LFS setquota -u $TSTUSR -B ${pool_hard}M --pool $qpool $DIR ||
+               error "set user quota failed"
+
+       local tmp=$(getquota -u $TSTUSR global bhardlimit $qpool)
+       [ $tmp -eq $((pool_hard * 1024)) ] ||
+               error "wrong block hard limit $tmp for $qpool"
+       local tmp=$(getquota -u $TSTUSR global bsoftlimit $qpool)
+       # soft limit hasn't been set and should be zero
+       [ $tmp -eq 0 ] || error "wrong soft block limit $tmp for $qpool"
 }
-run_test 70 "check lfs setquota/quota with a pool option"
+run_test 70b "lfs setquota pool works properly"
 
 test_71a()
 {
-       local limit=10  # 10M
-       local global_limit=100  # 100M
+       local limit=10 # MB
+       local global_limit=100 # MB
        local testfile="$DIR/$tdir/$tfile-0"
        local qpool="qpool1"
        local qpool2="qpool2"
@@ -4621,7 +4837,6 @@ test_71a()
        [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs"
        mds_supports_qp
        setup_quota_test || error "setup quota failed with $?"
-       stack_trap cleanup_quota_test EXIT
 
        # enable ost quota
        set_ost_qtype $QTYPE || error "enable ost quota failed"
@@ -4687,16 +4902,14 @@ test_71a()
        # write to the 1st component - OST0 is empty
        $RUNAS $DD of=$testfile count=$limit seek=0 ||
                quota_error u $TSTUSR "write failed"
-
-       cleanup_quota_test
 }
 run_test 71a "Check PFL with quota pools"
 
 test_71b()
 {
-       local global_limit=1000 # 1G
-       local limit1=160 # 160M
-       local limit2=10 # 10M
+       local global_limit=1000 # MB
+       local limit1=160 # MB
+       local limit2=10 # MB
        local testfile="$DIR/$tdir/$tfile-0"
        local qpool="qpool1"
        local qpool2="qpool2"
@@ -4706,7 +4919,6 @@ test_71b()
        [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs" && return
        mds_supports_qp
        setup_quota_test || error "setup quota failed with $?"
-       stack_trap cleanup_quota_test EXIT
 
        # enable ost quota
        set_ost_qtype $QTYPE || error "enable ost quota failed"
@@ -4754,21 +4966,19 @@ test_71b()
        # write over limit in qpool2
        $RUNAS $DD of=$testfile count=2 seek=$((128 + limit2)) &&
                quota_error u $TSTUSR "user write success, but expect EDQUOT"
-
-       cleanup_quota_test
+       return 0
 }
 run_test 71b "Check SEL with quota pools"
 
 test_72()
 {
-       local limit=10  # 10M
-       local global_limit=50  # 50M
+       local limit=10 # MB
+       local global_limit=50 # MB
        local testfile="$DIR/$tdir/$tfile-0"
        local qpool="qpool1"
 
        mds_supports_qp
        setup_quota_test || error "setup quota failed with $?"
-       stack_trap cleanup_quota_test EXIT
 
        # enable ost quota
        set_ost_qtype $QTYPE || error "enable ost quota failed"
@@ -4801,14 +5011,556 @@ test_72()
        # was added in a pool
        lfs quota -v -u quota_usr --pool $qpool $DIR | grep -v "OST0001" |
                grep "OST\|MDT" && error "$qpool consists wrong targets"
-
-       cleanup_quota_test
+       return 0
 }
 run_test 72 "lfs quota --pool prints only pool's OSTs"
 
+test_73a()
+{
+       local qpool="qpool1"
+
+       mds_supports_qp
+
+       pool_add $qpool || error "pool_add failed"
+       pool_add_targets $qpool 0 $((OSTCOUNT - 1)) ||
+               error "pool_add_targets failed"
+
+       test_default_quota "-u" "data" "qpool1"
+}
+run_test 73a "default limits at OST Pool Quotas"
+
+test_73b()
+{
+       local TESTFILE1="$DIR/$tdir/$tfile-1"
+       local limit=20 #20M
+       local qpool="qpool1"
+
+       mds_supports_qp
+
+       setup_quota_test || error "setup quota failed with $?"
+       quota_init
+       set_ost_qtype $QTYPE || error "enable ost quota failed"
+
+       # pool quotas don't work properly without global limit
+       $LFS setquota -u $TSTUSR -b 0 -B ${limit}M -i 0 -I 0 $DIR ||
+               error "set global limit failed"
+
+       pool_add $qpool || error "pool_add failed"
+       pool_add_targets $qpool 0 $((OSTCOUNT - 1)) ||
+               error "pool_add_targets failed"
+
+       log "set default quota for $qpool"
+       $LFS setquota -U --pool $qpool -b ${limit}M -B ${limit}M $DIR ||
+               error "set default quota failed"
+
+       log "Write from user that hasn't lqe"
+       # Check that it doesn't cause a panic or a deadlock
+       # due to nested lqe lookups that rewrite 1st lqe in qti_lqes array.
+       # Have to use RUNAS_ID as resetquota creates lqes in
+       # the beginning for TSTUSR/TSTUSR2 when sets limits to 0.
+       runas -u $RUNAS_ID -g $RUNAS_GID $DD of=$TESTFILE1 count=10
+
+       cancel_lru_locks osc
+       sync; sync_all_data || true
+}
+run_test 73b "default OST Pool Quotas limit for new user"
+
+test_74()
+{
+       local global_limit=200 # 200M
+       local limit=10 # 10M
+       local limit2=50 # 50M
+       local qpool="qpool1"
+       local qpool2="qpool2"
+       local tmp=0
+
+       mds_supports_qp
+       setup_quota_test || error "setup quota failed with $?"
+
+       # enable ost quota
+       set_ost_qtype $QTYPE || error "enable ost quota failed"
+
+       $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
+               error "set user quota failed"
+
+       pool_add $qpool || error "pool_add failed"
+       pool_add_targets $qpool 0 1 ||
+               error "pool_add_targets failed"
+
+       $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR ||
+               error "set user quota failed"
+
+       pool_add $qpool2 || error "pool_add failed"
+       pool_add_targets $qpool2 1 1 ||
+               error "pool_add_targets failed"
+
+       $LFS setquota -u $TSTUSR -B ${limit2}M --pool $qpool2 $DIR ||
+               error "set user quota failed"
+
+       tmp=$(getquota -u $TSTUSR global bhardlimit)
+       [ $tmp -eq $((global_limit * 1024)) ] ||
+               error "wrong global limit $global_limit"
+
+       tmp=$(getquota -u $TSTUSR global bhardlimit $qpool)
+       [ $tmp -eq $((limit * 1024)) ] || error "wrong limit $tmp for $qpool"
+
+       tmp=$(getquota -u $TSTUSR global bhardlimit $qpool2)
+       [ $tmp -eq $((limit2 * 1024)) ] || error "wrong limit $tmp for $qpool2"
+
+       # check limits in pools
+       tmp=$($LFS quota -u $TSTUSR --pool $DIR | \
+             grep -A4 $qpool | awk 'NR == 4{print $4}')
+       echo "pool limit for $qpool $tmp"
+       [ $tmp -eq $((limit * 1024)) ] || error "wrong limit:tmp for $qpool"
+       tmp=$($LFS quota -u $TSTUSR --pool $DIR | \
+             grep -A4 $qpool2 | awk 'NR == 4{print $4}')
+       echo "pool limit for $qpool2 $tmp"
+       [ $tmp -eq $((limit2 * 1024)) ] || error "wrong limit:$tmp for $qpool2"
+}
+run_test 74 "check quota pools per user"
+
+function cleanup_quota_test_75()
+{
+       do_facet mgs $LCTL nodemap_modify --name default \
+               --property admin --value 1
+       do_facet mgs $LCTL nodemap_modify --name default \
+               --property trusted --value 1
+       do_facet mgs $LCTL nodemap_modify --name default \
+               --property squash_uid --value 99
+       do_facet mgs $LCTL nodemap_modify --name default \
+               --property squash_gid --value 99
+
+       wait_nm_sync default admin_nodemap
+       wait_nm_sync default trusted_nodemap
+
+       do_facet mgs $LCTL nodemap_activate 0
+       wait_nm_sync active
+
+       resetquota -u $TSTUSR
+}
+
+test_dom_75() {
+       local dd_failed=false
+       local LIMIT=20480 #20M
+       local qid=$TSTID
+
+       for ((i = 0; i < $((LIMIT/2048-1)); i++)); do
+               $DD of=$DIR/$tdir_dom/$tfile-$i count=1 \
+                       oflag=sync || dd_failed=true
+       done
+
+       $dd_failed && quota_error u $qid "write failed, expect succeed (1)"
+
+       for ((i = $((LIMIT/2048-1)); i < $((LIMIT/1024 + 10)); i++)); do
+               $DD of=$DIR/$tdir_dom/$tfile-$i count=1 \
+                       oflag=sync || dd_failed=true
+       done
+
+       $dd_failed || quota_error u $qid "write succeed, expect EDQUOT (1)"
+
+       rm -f $DIR/$tdir_dom/*
+
+       # flush cache, ensure noquota flag is set on client
+       cancel_lru_locks
+       sync; sync_all_data || true
+
+       dd_failed=false
+
+       $DD of=$DIR/$tdir/file count=$((LIMIT/2048-1)) oflag=sync ||
+               quota_error u $qid "write failed, expect succeed (2)"
+
+       for ((i = 0; i < $((LIMIT/2048 + 10)); i++)); do
+               $DD of=$DIR/$tdir_dom/$tfile-$i count=1 \
+                       oflag=sync || dd_failed=true
+       done
+
+       $dd_failed || quota_error u $TSTID "write succeed, expect EDQUOT (2)"
+
+       rm -f $DIR/$tdir/*
+       rm -f $DIR/$tdir_dom/*
+
+       # flush cache, ensure noquota flag is set on client
+       cancel_lru_locks
+       sync; sync_all_data || true
+
+       dd_failed=false
+
+       for ((i = 0; i < $((LIMIT/2048-1)); i++)); do
+               $DD of=$DIR/$tdir_dom/$tfile-$i count=1 \
+                       oflag=sync || dd_failed=true
+       done
+
+       $dd_failed && quota_error u $qid "write failed, expect succeed (3)"
+
+       $DD of=$DIR/$tdir/file count=$((LIMIT/2048 + 10)) oflag=sync &&
+               quota_error u $qid "write succeed, expect EDQUOT (3)"
+       true
+}
+
+test_75()
+{
+       local soft_limit=10 # MB
+       local hard_limit=20 # MB
+       local limit=$soft_limit
+       local testfile="$DIR/$tdir/$tfile-0"
+       local grace=20 # seconds
+       local tdir_dom=${tdir}_dom
+
+       if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
+           grace=60
+       fi
+
+       setup_quota_test || error "setup quota failed with $?"
+       stack_trap cleanup_quota_test_75 EXIT
+
+       # enable ost quota
+       set_ost_qtype $QTYPE || error "enable ost quota failed"
+       set_mdt_qtype $QTYPE || error "enable mdt quota failed"
+
+       local used=$(getquota -u $TSTID global curspace)
+       $LFS setquota -t -u --block-grace $grace --inode-grace \
+               $MAX_IQ_TIME $DIR || error "set user grace time failed"
+       $LFS setquota -u $TSTUSR -b $((soft_limit+used/1024))M \
+                       -B $((hard_limit+used/1024))M -i 0 -I 0 $DIR ||
+               error "set user quota failed"
+
+       chmod 777 $DIR/$tdir || error "chmod 777 $DIR/$tdir failed"
+       mkdir $DIR/$tdir_dom
+       chmod 777 $DIR/$tdir_dom
+       $LFS setstripe -E 1M -L mdt $DIR/$tdir_dom ||
+               error "setstripe $tdir_dom failed"
+
+       do_facet mgs $LCTL nodemap_activate 1
+       wait_nm_sync active
+       do_facet mgs $LCTL nodemap_modify --name default \
+               --property admin --value 0
+       do_facet mgs $LCTL nodemap_modify --name default \
+               --property trusted --value 0
+       do_facet mgs $LCTL nodemap_modify --name default \
+               --property deny_unknown --value 0
+       do_facet mgs $LCTL nodemap_modify --name default \
+               --property squash_uid --value $TSTID
+       do_facet mgs $LCTL nodemap_modify --name default \
+               --property squash_gid --value $TSTID
+       cancel_lru_locks mdc
+       wait_nm_sync default admin_nodemap
+       wait_nm_sync default trusted_nodemap
+       wait_nm_sync default squash_uid
+
+       # mmap write when over soft limit
+       limit=$soft_limit
+       $DD of=$testfile count=${limit} ||
+               quota_error a  "root write failure, but expect success (1)"
+       OFFSET=$((limit * 1024))
+       cancel_lru_locks osc
+
+       echo "Write to exceed soft limit"
+       dd if=/dev/zero of=$testfile bs=1K count=10 seek=$OFFSET ||
+             quota_error a $TSTUSR "root write failure, but expect success (2)"
+       OFFSET=$((OFFSET + 1024)) # make sure we don't write to same block
+       cancel_lru_locks osc
+
+       echo "mmap write when over soft limit"
+       $MULTIOP $testfile.mmap OT40960SMW ||
+               quota_error a $TSTUSR "mmap write failure, but expect success"
+       cancel_lru_locks osc
+       rm -f $testfile*
+       wait_delete_completed || error "wait_delete_completed failed (1)"
+       sync_all_data || true
+
+       # test for user hard limit
+       limit=$hard_limit
+       log "Write..."
+       $DD of=$testfile bs=1M count=$((limit/2)) ||
+               quota_error u $TSTID \
+                       "root write failure, but expect success (3)"
+
+       log "Write out of block quota ..."
+       # possibly a cache write, ignore failure
+       $DD of=$testfile bs=1M count=$((limit/2)) seek=$((limit/2)) || true
+       # flush cache, ensure noquota flag is set on client
+       cancel_lru_locks osc
+       sync; sync_all_data || true
+       # sync forced cache flush, but did not guarantee that slave
+       # got new edquot through glimpse, so wait to make sure
+       sleep 5
+       $DD of=$testfile bs=1M count=1 seek=$limit conv=fsync &&
+               quota_error u $TSTID \
+                       "user write success, but expect EDQUOT"
+       rm -f $testfile
+       wait_delete_completed || error "wait_delete_completed failed (2)"
+       sync_all_data || true
+       [ $(getquota -u $TSTUSR global curspace) -eq $used ] ||
+               quota_error u $TSTID "user quota not released after deletion"
+
+       test_dom_75
+}
+run_test 75 "nodemap squashed root respects quota enforcement"
+
+test_76() {
+       ! is_project_quota_supported &&
+               skip "skip project quota unsupported"
+
+       setup_quota_test || error "setup quota failed with $?"
+       quota_init
+
+       local testfile="$DIR/$tdir/$tfile-0"
+
+       touch $testfile
+       $LFS project -p 4294967295 $testfile &&
+               error "set project ID should fail"
+       return 0
+}
+run_test 76 "project ID 4294967295 should be not allowed"
+
+test_77()
+{
+       mount_client $MOUNT2 "ro"
+       lfs setquota -u quota_usr -b 100M -B 100M -i 10K -I 10K $MOUNT2 &&
+               error "lfs setquota should fail in read-only Lustre mount"
+       umount $MOUNT2
+}
+run_test 77 "lfs setquota should fail in Lustre mount with 'ro'"
+
+test_78()
+{
+       (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
+               skip "need OST at least 2.14.55"
+       check_set_fallocate_or_skip
+
+       setup_quota_test || error "setup quota failed with $?"
+
+       # enable ost quota
+       set_ost_qtype $QTYPE || error "enable ost quota failed"
+
+       mkdir -p $DIR/$tdir || error "failed to create $tdir"
+       chown $TSTUSR $DIR/$tdir || error "failed to chown $tdir"
+
+       # setup quota limit
+       $LFS setquota -u $TSTUSR -b25M -B25M $DIR/$tdir ||
+               error "lfs setquota failed"
+
+       # call fallocate
+       runas -u $TSTUSR -g $TSTUSR fallocate -l 204800 $DIR/$tdir/$tfile
+
+       kbytes=$(lfs quota -u $TSTUSR $DIR |
+               awk -v pattern=$DIR 'match($0, pattern) {printf $2}')
+       echo "kbytes returned:$kbytes"
+
+       # For file size of 204800. We should be having roughly 200 kbytes
+       # returned. Anything alarmingly low (50 taken as arbitrary value)
+       # would bail out this TC. Also this also avoids $kbytes of 0
+       # to be used in calculation below.
+       (( $kbytes > 50 )) ||
+               error "fallocate did not use quota. kbytes returned:$kbytes"
+
+       local expect_lo=$(($kbytes * 95 / 100)) # 5% below
+       local expect_hi=$(($kbytes * 105 / 100)) # 5% above
+
+       # Verify kbytes is 200 (204800/1024). With a permited  5% drift
+       (( $kbytes >= $expect_lo && $kbytes <= $expect_hi )) ||
+               error "fallocate did not use quota correctly"
+}
+run_test 78 "Check fallocate increase quota usage"
+
+test_78a()
+{
+       (( $CLIENT_VERSION >= $(version_code 2.15.0) )) ||
+               skip "need client at least 2.15.0"
+       (( $OST1_VERSION >= $(version_code 2.15.0) )) ||
+               skip "need OST at least 2.15.0"
+       check_set_fallocate_or_skip
+
+       setup_quota_test || error "setup quota failed with $?"
+
+       # enable ost quota
+       set_ost_qtype $QTYPE || error "enable ost quota failed"
+
+       mkdir -p $DIR/$tdir || error "failed to create $tdir"
+
+       local projectid=5200 # Random project id to test
+
+       change_project -sp $projectid $DIR/$tdir
+
+       # setup quota limit
+       $LFS setquota -p $projectid -b25M -B25M $DIR/$tdir ||
+               error "lfs setquota project failed"
+
+       # call fallocate
+       fallocate -l 204800 $DIR/$tdir/$tfile
+
+       # Get curspace (kbytes) for $projectid
+       local kbytes=$(getquota -p $projectid global curspace)
+
+       echo "kbytes returned:$kbytes"
+
+       # For file size of 204800. We should be having roughly 200 kbytes
+       # returned. Anything alarmingly low (50 taken as arbitrary value)
+       # would bail out this TC. Also this also avoids $kbytes of 0
+       # to be used in calculation below.
+       (( $kbytes > 50 )) ||
+               error "fallocate did not use projectid. kbytes returned:$kbytes"
+
+       local expect_lo=$(($kbytes * 95 / 100)) # 5% below
+       local expect_hi=$(($kbytes * 105 / 100)) # 5% above
+
+       # Verify kbytes is 200 (204800/1024). With a permited  5% drift
+       (( $kbytes >= $expect_lo && $kbytes <= $expect_hi )) ||
+               error "fallocate did not use quota projectid correctly"
+}
+run_test 78a "Check fallocate increase projectid usage"
+
+test_79()
+{
+       local qpool="qpool1"
+       local cmd="$LCTL get_param -n qmt.$FSNAME-QMT0000.dt-$qpool.info"
+       local stopf=$TMP/$tfile
+
+       do_facet mds1 "touch $stopf"
+       stack_trap "do_facet mds1 'rm -f $stopf'"
+       do_facet mds1 "while [ -e $stopf ]; do $cmd &>/dev/null; done"&
+       local pid=$!
+       pool_add $qpool || error "pool_add failed"
+       do_facet mds1 "rm $stopf"
+       wait $pid
+}
+run_test 79 "access to non-existed dt-pool/info doesn't cause a panic"
+
+test_80()
+{
+       local dir1="$DIR/$tdir/dir1"
+       local dir2="$DIR/$tdir/dir2"
+       local TESTFILE0="$dir1/$tfile-0"
+       local TESTFILE1="$dir1/$tfile-1"
+       local TESTFILE2="$dir1/$tfile-2"
+       local TESTFILE3="$dir2/$tfile-0"
+       local global_limit=100 # 100M
+       local limit=10 # 10M
+       local qpool="qpool1"
+
+       [ "$OSTCOUNT" -lt "2" ] && skip "needs >= 2 OSTs"
+       mds_supports_qp
+       [ "$ost1_FSTYPE" == zfs ] &&
+               skip "ZFS grants some block space together with inode"
+       setup_quota_test || error "setup quota failed with $?"
+       set_ost_qtype $QTYPE || error "enable ost quota failed"
+
+       # make sure the system is clean
+       local used=$(getquota -u $TSTUSR global curspace)
+       [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR is not 0."
+
+       pool_add $qpool || error "pool_add failed"
+       pool_add_targets $qpool 0 1 ||
+               error "pool_add_targets failed"
+
+       $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
+               error "set user quota failed"
+
+       $LFS setquota -u $TSTUSR -B ${global_limit}M --pool $qpool $DIR ||
+               error "set user quota failed"
+       $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR ||
+               error "set user quota failed"
+
+       mkdir -p $dir1 || error "failed to mkdir"
+       chown $TSTUSR.$TSTUSR $dir1 || error "chown $dir1 failed"
+       mkdir -p $dir2 || error "failed to mkdir"
+       chown $TSTUSR.$TSTUSR $dir2 || error "chown $dir2 failed"
+
+       $LFS setstripe $dir1 -i 1 -c 1|| error "setstripe $testfile failed"
+       $LFS setstripe $dir2 -i 0 -c 1|| error "setstripe $testfile failed"
+       lfs getstripe $dir1
+       lfs getstripe $dir2
+       sleep 3
+
+       $LFS quota -uv $TSTUSR $DIR
+       #define OBD_FAIL_QUOTA_PREACQ            0xA06
+       do_facet mds1 $LCTL set_param fail_loc=0xa06
+       $RUNAS $DD of=$TESTFILE3 count=3 ||
+               quota_error u $TSTUSR "write failed"
+       $RUNAS $DD of=$TESTFILE2 count=7 ||
+               quota_error u $TSTUSR "write failed"
+       $RUNAS $DD of=$TESTFILE1 count=1 oflag=direct ||
+               quota_error u $TSTUSR "write failed"
+       sync
+       sleep 3
+       $LFS quota -uv --pool $qpool $TSTUSR $DIR
+
+       rm -f $TESTFILE2
+       stop ost2
+       do_facet mds1 $LCTL set_param fail_loc=0
+       start ost2 $(ostdevname 2) $OST_MOUNT_OPTS || error "start ost2 failed"
+       $LFS quota -uv $TSTUSR --pool $qpool $DIR
+       # OST0 needs some time to update quota usage after removing TESTFILE2
+       sleep 4
+       $LFS quota -uv $TSTUSR --pool $qpool $DIR
+       $RUNAS $DD of=$TESTFILE0 count=2 oflag=direct ||
+               quota_error u $TSTUSR "write failure, but expect success"
+}
+run_test 80 "check for EDQUOT after OST failover"
+
+test_81() {
+       local global_limit=20  # 100M
+       local testfile="$DIR/$tdir/$tfile-0"
+       local qpool="qpool1"
+
+       mds_supports_qp
+       setup_quota_test || error "setup quota failed with $?"
+
+       # enable ost quota
+       set_ost_qtype $QTYPE || error "enable ost quota failed"
+
+       # test for user
+       log "User quota (block hardlimit:$global_limit MB)"
+       $LFS setquota -u $TSTUSR -B 1G $DIR || error "set user quota failed"
+
+       pool_add $qpool || error "pool_add failed"
+       #define OBD_FAIL_QUOTA_RECALC   0xA07
+       do_facet mds1 $LCTL set_param fail_loc=0x80000A07 fail_val=30
+       # added OST casues to start pool recalculation
+       pool_add_targets $qpool 0 0 1
+       stop mds1 -f || error "MDS umount failed"
+
+       #start mds1 back to destroy created pool
+       start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
+       clients_up || true
+}
+run_test 81 "Race qmt_start_pool_recalc with qmt_pool_free"
+
+test_82()
+{
+       (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
+               skip "need MDS 2.14.55 or later"
+       is_project_quota_supported ||
+               skip "skip project quota unsupported"
+
+       setup_quota_test || error "setup quota failed with $?"
+       stack_trap cleanup_quota_test
+       quota_init
+
+       local parent_dir="$DIR/$tdir.parent"
+       local child_dir="$parent_dir/child"
+
+       mkdir -p $child_dir
+       stack_trap "chown -R 0:0 $parent_dir"
+
+       chown $TSTUSR:$TSTUSR $parent_dir ||
+               error "failed to chown on $parent_dir"
+       chown $TSTUSR2:$TSTUSRS2 $child_dir ||
+               error "failed to chown on $parent_dir"
+
+       $LFS project -p 1000 $parent_dir ||
+               error "failed to set project id on $parent_dir"
+       $LFS project -p 1001 $child_dir ||
+               error "failed to set project id on $child_dir"
+
+       rmdir $child_dir || error "cannot remove child dir, test failed"
+}
+run_test 82 "verify more than 8 qids for single operation"
+
 quota_fini()
 {
-       do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=-quota"
+       do_nodes $(comma_list $(nodes_list)) \
+               "lctl set_param -n debug=-quota,trace"
        if $PQ_CLEANUP; then
                disable_project_quota
        fi