Whamcloud - gitweb
LU-14286 osd-ldiskfs: fallocate with unwritten extents
[fs/lustre-release.git] / lustre / tests / sanity-quota.sh
index 921f67e..7785428 100755 (executable)
@@ -3,22 +3,32 @@
 # Run select tests by setting ONLY, or as arguments to the script.
 # Skip specific tests by setting EXCEPT.
 #
-# Run test by setting NOSETUP=true when ltest has setup env for us
 set -e
 
-SRCDIR=$(dirname $0)
-export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/../utils:$PATH:/sbin
-
 ONLY=${ONLY:-"$*"}
-# Bug number for skipped test:      LU-5152
-ALWAYS_EXCEPT="$SANITY_QUOTA_EXCEPT 55"
+
+LUSTRE=${LUSTRE:-$(dirname $0)/..}
+. $LUSTRE/tests/test-framework.sh
+init_test_env $@
+init_logging
+
+ALWAYS_EXCEPT="$SANITY_QUOTA_EXCEPT "
+# Bug number for skipped test:  LU-5152
+ALWAYS_EXCEPT+="                55"
 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
 
-[ "$ALWAYS_EXCEPT$EXCEPT" ] &&
-       echo "Skipping tests: $ALWAYS_EXCEPT $EXCEPT"
+# Test duration:                   30 min
+[ "$SLOW" = "no" ] && EXCEPT_SLOW="61"
+
+if [ "$mds1_FSTYPE" = zfs ]; then
+       # bug number:                        LU-2887
+       # Test duration:                     21      9 min"
+       [ "$SLOW" = "no" ] && EXCEPT_SLOW+=" 12a     9"
+fi
 
-TMP=${TMP:-/tmp}
+build_test_filter
 
+DIRECTIO=${DIRECTIO:-$LUSTRE/tests/directio}
 ORIG_PWD=${PWD}
 TSTID=${TSTID:-60000}
 TSTID2=${TSTID2:-60001}
@@ -29,35 +39,21 @@ BLK_SZ=1024
 MAX_DQ_TIME=604800
 MAX_IQ_TIME=604800
 QTYPE="ugp"
-
-LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
-. $LUSTRE/tests/test-framework.sh
-init_test_env $@
-. ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
-get_lustre_env
-init_logging
-DIRECTIO=${DIRECTIO:-$LUSTRE/tests/directio}
+# 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) ] &&
+               skip "Needs MDS version $VERSION_WITH_QP or later."
+}
 
 require_dsh_mds || exit 0
 require_dsh_ost || exit 0
 
 # Does e2fsprogs support quota feature?
-if [ $(facet_fstype $SINGLEMDS) == ldiskfs ] &&
+if [ "$mds1_FSTYPE" == ldiskfs ] &&
        do_facet $SINGLEMDS "! $DEBUGFS -c -R supported_features |
                grep -q 'quota'"; then
-       skip_env "e2fsprogs doesn't support quota" && exit 0
-fi
-
-# Test duration:                   30 min
-[ "$SLOW" = "no" ] && EXCEPT_SLOW="61"
-
-if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
-       # bug number for skipped test:
-       ALWAYS_EXCEPT="$ALWAYS_EXCEPT"
-
-       # bug number:                        LU-2887
-       # Test duration:                     21      9 min"
-       [ "$SLOW" = "no" ] && EXCEPT_SLOW+=" 12a     9"
+       skip_env "e2fsprogs doesn't support quota"
 fi
 
 QUOTALOG=${TESTSUITELOG:-$TMP/$(basename $0 .sh).log}
@@ -73,23 +69,6 @@ export QUOTA_AUTO=0
 check_and_setup_lustre
 
 ENABLE_PROJECT_QUOTAS=${ENABLE_PROJECT_QUOTAS:-true}
-is_project_quota_supported() {
-       $ENABLE_PROJECT_QUOTAS || return 1
-       [ "$(facet_fstype $SINGLEMDS)" == "ldiskfs" ] &&
-               [ $(lustre_version_code $SINGLEMDS) -gt \
-               $(version_code 2.9.55) ] &&
-               lfs --help | grep project >&/dev/null &&
-               egrep -q "7." /etc/redhat-release && return 0
-
-       if [ "$(facet_fstype $SINGLEMDS)" == "zfs" ]; then
-               [ $(lustre_version_code $SINGLEMDS) -le \
-                       $(version_code 2.10.53) ] && return 1
-
-               $ZPOOL upgrade -v | grep project_quota && return 0
-       fi
-
-       return 1
-}
 
 SHOW_QUOTA_USER="$LFS quota -v -u $TSTUSR $DIR"
 SHOW_QUOTA_USERID="$LFS quota -v -u $TSTID $DIR"
@@ -100,8 +79,6 @@ SHOW_QUOTA_INFO_USER="$LFS quota -t -u $DIR"
 SHOW_QUOTA_INFO_GROUP="$LFS quota -t -g $DIR"
 SHOW_QUOTA_INFO_PROJID="eval is_project_quota_supported && $LFS quota -t -p $DIR"
 
-build_test_filter
-
 lustre_fail() {
        local fail_node=$1
        local fail_loc=$2
@@ -167,6 +144,7 @@ quota_scan() {
                        xargs stat 2>/dev/null)
        fi
 
+       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):"
@@ -189,14 +167,17 @@ quota_log() {
 
 # get quota for a user or a group
 # usage: getquota -u|-g|-p <username>|<groupname>|<projid> global|<obd_uuid> \
-#                bhardlimit|bsoftlimit|bgrace|ihardlimit|isoftlimit|igrace
+#                bhardlimit|bsoftlimit|bgrace|ihardlimit|isoftlimit|igrace \
+#                <pool_name>
 getquota() {
        local spec
        local uuid
+       local pool_arg
 
        sync_all_data > /dev/null 2>&1 || true
 
-       [ "$#" != 4 ] && error "getquota: wrong number of arguments: $#"
+       [ "$#" != 4 -a "$#" != 5 ] &&
+               error "getquota: wrong number of arguments: $#"
        [ "$1" != "-u" -a "$1" != "-g" -a "$1" != "-p" ] &&
                error "getquota: wrong u/g/p specifier $1 passed"
 
@@ -214,9 +195,10 @@ getquota() {
                *)          error "unknown quota parameter $4";;
        esac
 
+       [ ! -z "$5" ] && pool_arg="--pool $5 "
        [ "$uuid" = "global" ] && uuid=$DIR
 
-       $LFS quota -v "$1" "$2" $DIR |
+       $LFS quota -v "$1" "$2" $pool_arg $DIR |
                awk 'BEGIN { num='$spec' } { if ($1 == "'$uuid'") \
                { if (NF == 1) { getline } else { num++ } ; print $num;} }' \
                | tr -d "*"
@@ -350,23 +332,58 @@ wait_ost_reint() {
        return 0
 }
 
-disable_project_quota() {
-       is_project_quota_supported || return 0
-       [ "$(facet_fstype $SINGLEMDS)" != "ldiskfs" ] && return 0
-       stopall || error "failed to stopall (1)"
+wait_grace_time() {
+       local qtype=$1
+       local flavour=$2
+       local pool=${3:-}
+       local extrasleep=${4:-5}
+       local qarg
+       local parg
+
+       case $qtype in
+               u|g) qarg=$TSTUSR ;;
+               p) qarg=$TSTPRJID ;;
+               *) error "get_grace_time: Invalid quota type: $qtype"
+       esac
 
-       for num in $(seq $MDSCOUNT); do
-               do_facet mds$num $TUNE2FS -Q ^prj $(mdsdevname $num) ||
-                       error "tune2fs $(mdsdevname $num) failed"
-       done
+       if [ $pool ]; then
+               parg="--pool "$pool
+               echo "Quota info for $pool:"
+               $LFS quota -$qtype $qarg $parg $DIR
+       fi
 
-       for num in $(seq $OSTCOUNT); do
-               do_facet ost$num $TUNE2FS -Q ^prj $(ostdevname $num) ||
-                       error "tune2fs $(ostdevname $num) failed"
-       done
+       case $flavour in
+               block)
+                       time=$(lfs quota -$qtype $qarg $parg $DIR|
+                                  awk 'NR == 3{ print $5 }'| sed 's/s$//')
+                       ;;
+               file)
+                       time=$(lfs quota -$qtype $qarg $DIR|
+                                  awk 'NR == 3{ print $9 }'| sed 's/s$//')
+                       ;;
+               *)
+                       error "Unknown quota type: $flavour"
+                       ;;
+       esac
 
-       mount
-       setupall
+       # 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));
+
+       echo "Sleep through grace ..."
+       [ "$time" == "-" ] &&
+           error "Grace timeout was not set or quota not exceeded"
+       if [ "$time" == "none" ]; then
+           echo "...Grace timeout already expired"
+       else
+               let time+=$extrasleep
+               echo "...sleep $time seconds"
+               sleep $time
+       fi
 }
 
 setup_quota_test() {
@@ -380,7 +397,6 @@ setup_quota_test() {
 }
 
 cleanup_quota_test() {
-       trap 0
        echo "Delete files..."
        rm -rf $DIR/$tdir
        echo "Wait for unlink objects finished..."
@@ -420,34 +436,25 @@ quota_show_check() {
        fi
 }
 
-enable_project_quota() {
-       is_project_quota_supported || return 0
-       [ "$(facet_fstype $SINGLEMDS)" != "ldiskfs" ] && return 0
-       stopall || error "failed to stopall (1)"
-
-       for num in $(seq $MDSCOUNT); do
-               do_facet mds$num $TUNE2FS -O project $(mdsdevname $num) ||
-                       error "tune2fs $(mdsdevname $num) failed"
-       done
-
-       for num in $(seq $OSTCOUNT); do
-               do_facet ost$num $TUNE2FS -O project $(ostdevname $num) ||
-                       error "tune2fs $(ostdevname $num) failed"
-       done
-
-       mount
-       setupall
-}
-
 project_quota_enabled () {
        local rc=0
-       for num in $(seq $MDSCOUNT); do
-               do_facet mds$num $DEBUGFS -R features $(mdsdevname $num) |
-                       grep -q project || rc=1
-       done
-       for num in $(seq $OSTCOUNT); do
-               do_facet ost$num $DEBUGFS -R features $(ostdevname $num) |
-                       grep -q project || rc=1
+       local zfeat="feature@project_quota"
+
+       for facet in $(seq -f mds%g $MDSCOUNT) $(seq -f ost%g $OSTCOUNT); do
+               local facet_fstype=${facet:0:3}1_FSTYPE
+               local devname
+
+               if [ "${!facet_fstype}" = "zfs" ]; then
+                       devname=$(zpool_name ${facet})
+                       do_facet ${facet} $ZPOOL get -H "$zfeat" $devname |
+                               grep -wq active || rc=1
+               else
+                       [ ${facet:0:3} == "mds" ] &&
+                               devname=$(mdsdevname ${facet:3}) ||
+                               devname=$(ostdevname ${facet:3})
+                       do_facet ${facet} $DEBUGFS -R features $devname |
+                               grep -q project || rc=1
+               fi
        done
        [ $rc -eq 0 ] && PQ_CLEANUP=false || PQ_CLEANUP=true
        return $rc
@@ -457,15 +464,19 @@ project_quota_enabled || enable_project_quota
 
 reset_quota_settings() {
        resetquota -u $TSTUSR
+       resetquota -u $TSTID
        resetquota -g $TSTUSR
+       resetquota -g $TSTID
        resetquota -u $TSTUSR2
+       resetquota -u $TSTID2
        resetquota -g $TSTUSR2
+       resetquota -g $TSTID2
        resetquota -p $TSTPRJID
 }
 
 # enable quota debug
 quota_init() {
-       do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=+quota"
+       do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=+quota+trace"
 }
 quota_init
 reset_quota_settings
@@ -484,15 +495,15 @@ test_quota_performance() {
        local etime=$(date +%s)
        delta=$((etime - stime))
        if [ $delta -gt 0 ]; then
-           rate=$((size * 1024 / delta))
-           if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
-               # LU-2872 - see LU-2887 for fix
-               [ $rate -gt 64 ] ||
-                       error "SLOW IO for $TSTUSR (user): $rate KB/sec"
-           else
-               [ $rate -gt 1024 ] ||
-                       error "SLOW IO for $TSTUSR (user): $rate KB/sec"
-           fi
+               rate=$((size * 1024 / delta))
+               if [ "$mds1_FSTYPE" = zfs ]; then
+                       # LU-2872 - see LU-2887 for fix
+                       [ $rate -gt 64 ] ||
+                               error "SLOW IO for $TSTUSR (user): $rate KB/sec"
+               else
+                       [ $rate -gt 1024 ] ||
+                               error "SLOW IO for $TSTUSR (user): $rate KB/sec"
+               fi
        fi
        rm -f $TESTFILE
 }
@@ -521,10 +532,58 @@ test_0() {
 }
 run_test 0 "Test basic quota performance"
 
+# usage: test_1_check_write tfile user|group|project
+test_1_check_write() {
+       local testfile="$1"
+       local qtype="$2"
+       local limit=$3
+       local short_qtype=${qtype:0:1}
+
+       log "Write..."
+       $RUNAS $DD of=$testfile count=$((limit/2)) ||
+               quota_error $short_qtype $TSTUSR \
+                       "$qtype write failure, but expect success"
+       log "Write out of block quota ..."
+       # this time maybe cache write,  ignore it's failure
+       $RUNAS $DD of=$testfile 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 means client wrote all it's cache, but id doesn't
+       # garantee that slave got new edquot trough 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"
+}
+
+check_write_fallocate() {
+       local testfile="$1"
+       local qtype="$2"
+       local limit=$3
+       local short_qtype=${qtype:0:1}
+
+       count=$((limit/2))
+       log "Write ${count}MiB Using Fallocate"
+       $RUNAS fallocate -l${count}MiB $testfile ||
+               quota_error $short_qtype $TSTUSR "Write ${count}MiB fail"
+
+       cancel_lru_locks osc
+       sync; sync_all_data || true
+       sleep 2
+
+       count=$((limit + 1))
+       log "Write ${count}MiB Using Fallocate"
+       $RUNAS fallocate -l${count}MiB $testfile &&
+               quota_error $short_qtype $TSTUSR \
+               "Write success, expect EDQUOT" || true
+}
+
 # test block hardlimit
-test_1() {
-       local LIMIT=10  # 10M
-       local TESTFILE="$DIR/$tdir/$tfile-0"
+test_1a() {
+       local limit=10  # 10M
+       local testfile="$DIR/$tdir/$tfile-0"
 
        setup_quota_test || error "setup quota failed with $?"
        trap cleanup_quota_test EXIT
@@ -533,66 +592,47 @@ test_1() {
        set_ost_qtype $QTYPE || error "enable ost quota failed"
 
        # test for user
-       log "User quota (block hardlimit:$LIMIT MB)"
-       $LFS setquota -u $TSTUSR -b 0 -B ${LIMIT}M -i 0 -I 0 $DIR ||
+       log "User quota (block hardlimit:$limit MB)"
+       $LFS setquota -u $TSTUSR -b 0 -B ${limit}M -i 0 -I 0 $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."
+       local used=$(getquota -u $TSTUSR global curspace)
+       [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
 
-       $LFS setstripe $TESTFILE -c 1 || error "setstripe $TESTFILE failed"
-       chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
+       $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
+       chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
 
-       log "Write..."
-       $RUNAS $DD of=$TESTFILE count=$((LIMIT/2)) ||
-               quota_error u $TSTUSR "user write failure, but expect success"
-       log "Write out of block quota ..."
-       # this time maybe cache write,  ignore it's failure
-       $RUNAS $DD of=$TESTFILE 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
-       $RUNAS $DD of=$TESTFILE count=1 seek=$LIMIT &&
-               quota_error u $TSTUSR "user write success, but expect EDQUOT"
+       test_1_check_write $testfile "user" $limit
 
-       rm -f $TESTFILE
+       rm -f $testfile
        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=$(getquota -u $TSTUSR global curspace)
+       [ $used -ne 0 ] && quota_error u $TSTUSR \
                "user quota isn't released after deletion"
        resetquota -u $TSTUSR
 
        # test for group
        log "--------------------------------------"
-       log "Group quota (block hardlimit:$LIMIT MB)"
-       $LFS setquota -g $TSTUSR -b 0 -B ${LIMIT}M -i 0 -I 0 $DIR ||
+       log "Group quota (block hardlimit:$limit MB)"
+       $LFS setquota -g $TSTUSR -b 0 -B ${limit}M -i 0 -I 0 $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 curspace)
-       [ $USED -ne 0 ] && error "Used space ($USED) for group $TSTUSR isn't 0"
+       used=$(getquota -g $TSTUSR global curspace)
+       [ $used -ne 0 ] && error "Used space ($used) for group $TSTUSR isn't 0"
 
-       $LFS setstripe $TESTFILE -c 1 || error "setstripe $TESTFILE failed"
-       chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
+       $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
+       chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
 
-       log "Write ..."
-       $RUNAS $DD of=$TESTFILE count=$((LIMIT/2)) ||
-               quota_error g $TSTUSR "Group write failure, but expect success"
-       log "Write out of block quota ..."
-       # this time maybe cache write, ignore it's failure
-       $RUNAS $DD of=$TESTFILE count=$((LIMIT/2)) seek=$((LIMIT/2)) || true
-       cancel_lru_locks osc
-       sync; sync_all_data || true
-       $RUNAS $DD of=$TESTFILE count=10 seek=$LIMIT &&
-               quota_error g $TSTUSR "Group write success, but expect EDQUOT"
-       rm -f $TESTFILE
+       test_1_check_write $testfile "group" $limit
+       rm -f $testfile
        wait_delete_completed || error "wait_delete_completed failed"
        sync_all_data || true
-       USED=$(getquota -g $TSTUSR global curspace)
-       [ $USED -ne 0 ] && quota_error g $TSTUSR \
+       used=$(getquota -g $TSTUSR global curspace)
+       [ $used -ne 0 ] && quota_error g $TSTUSR \
                                "Group quota isn't released after deletion"
        resetquota -g $TSTUSR
 
@@ -602,48 +642,496 @@ test_1() {
                return 0
        fi
 
-       TESTFILE="$DIR/$tdir/$tfile-2"
+       testfile="$DIR/$tdir/$tfile-2"
        # make sure the system is clean
-       USED=$(getquota -p $TSTPRJID global curspace)
-       [ $USED -ne 0 ] &&
-               error "used space($USED) for project $TSTPRJID isn't 0"
+       used=$(getquota -p $TSTPRJID global curspace)
+       [ $used -ne 0 ] &&
+               error "used space($used) for project $TSTPRJID isn't 0"
 
        # test for Project
        log "--------------------------------------"
-       log "Project quota (block hardlimit:$LIMIT mb)"
-       $LFS setquota -p $TSTPRJID -b 0 -B ${LIMIT}M -i 0 -I 0 $DIR ||
+       log "Project quota (block hardlimit:$limit mb)"
+       $LFS setquota -p $TSTPRJID -b 0 -B ${limit}M -i 0 -I 0 $DIR ||
                error "set project quota failed"
 
-       $LFS setstripe $TESTFILE -c 1 || error "setstripe $TESTFILE failed"
-       chown $TSTUSR:$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
-       change_project -p $TSTPRJID $TESTFILE
-
-       log "write ..."
-       $RUNAS $DD of=$TESTFILE count=$((LIMIT/2)) || quota_error p $TSTPRJID \
-               "project write failure, but expect success"
-       log "write out of block quota ..."
-       # this time maybe cache write, ignore it's failure
-       $RUNAS $DD of=$TESTFILE count=$((LIMIT/2)) seek=$((LIMIT/2)) || true
-       cancel_lru_locks osc
-       sync; sync_all_data || true
-       $RUNAS $DD of=$TESTFILE count=10 seek=$LIMIT && quota_error p \
-               $TSTPRJID "project write success, but expect EDQUOT"
+       $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
+       chown $TSTUSR:$TSTUSR $testfile || error "chown $testfile failed"
+       change_project -p $TSTPRJID $testfile
+
+       test_1_check_write $testfile "project" $limit
 
        # cleanup
        cleanup_quota_test
 
-       USED=$(getquota -p $TSTPRJID global curspace)
-       [ $USED -eq 0 ] || quota_error p $TSTPRJID \
+       used=$(getquota -p $TSTPRJID global curspace)
+       [ $used -ne 0 ] && quota_error p $TSTPRJID \
                "project quota isn't released after deletion"
+
+       resetquota -p $TSTPRJID
+}
+run_test 1a "Block hard limit (normal use and out of quota)"
+
+test_1b() {
+       local limit=10  # 10M
+       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 $?"
+       stack_trap cleanup_quota_test EXIT
+
+       # 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 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 $(($OSTCOUNT - 1)) ||
+               error "pool_add_targets failed"
+
+       $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR ||
+               error "set user quota failed"
+
+       # make sure the system is clean
+       local used=$(getquota -u $TSTUSR global curspace)
+       echo "used $used"
+       [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
+
+       used=$(getquota -u $TSTUSR global bhardlimit $qpool)
+
+       $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
+       chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
+
+       test_1_check_write $testfile "user" $limit
+
+       rm -f $testfile
+       wait_delete_completed || error "wait_delete_completed failed"
+       sync_all_data || true
+       used=$(getquota -u $TSTUSR global curspace $qpool)
+       [ $used -ne 0 ] && quota_error u $TSTUSR \
+               "user quota isn't released after deletion"
+       resetquota -u $TSTUSR
+
+       # test for group
+       log "--------------------------------------"
+       log "Group quota (block hardlimit:$global_limit MB)"
+       $LFS setquota -g $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
+               error "set group quota failed"
+
+       $LFS setquota -g $TSTUSR -b 0 -B ${limit}M --pool $qpool $DIR ||
+               error "set group quota failed"
+
+       testfile="$DIR/$tdir/$tfile-1"
+       # make sure the system is clean
+       used=$(getquota -g $TSTUSR global curspace $qpool)
+       [ $used -ne 0 ] && error "Used space ($used) for group $TSTUSR isn't 0"
+
+       $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
+       chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
+
+       test_1_check_write $testfile "group" $limit
+
+       rm -f $testfile
+       wait_delete_completed || error "wait_delete_completed failed"
+       sync_all_data || true
+       used=$(getquota -g $TSTUSR global curspace $qpool)
+       [ $used -ne 0 ] && quota_error g $TSTUSR \
+                               "Group quota isn't released after deletion"
+       resetquota -g $TSTUSR
+
+       if ! is_project_quota_supported; then
+               echo "Project quota is not supported"
+               cleanup_quota_test
+               return 0
+       fi
+
+       testfile="$DIR/$tdir/$tfile-2"
+       # make sure the system is clean
+       used=$(getquota -p $TSTPRJID global curspace $qpool)
+       [ $used -ne 0 ] &&
+               error "used space($used) for project $TSTPRJID isn't 0"
+
+       # test for Project
+       log "--------------------------------------"
+       log "Project quota (block hardlimit:$global_limit mb)"
+       $LFS setquota -p $TSTPRJID -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
+               error "set project quota failed"
+
+       $LFS setquota -p $TSTPRJID -b 0 -B ${limit}M --pool $qpool $DIR ||
+               error "set project quota failed"
+
+
+       $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
+       chown $TSTUSR:$TSTUSR $testfile || error "chown $testfile failed"
+       change_project -p $TSTPRJID $testfile
+
+       test_1_check_write $testfile "project" $limit
+
+       # cleanup
+       cleanup_quota_test
+
+       used=$(getquota -p $TSTPRJID global curspace)
+       [ $used -eq 0 ] || quota_error p $TSTPRJID \
+               "project quota isn't released after deletion"
+}
+run_test 1b "Quota pools: Block hard limit (normal use and out of quota)"
+
+test_1c() {
+       local global_limit=20  # 100M
+       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"
+
+       # test for user
+       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 $(($OSTCOUNT - 1)) ||
+               error "pool_add_targets failed"
+
+       pool_add $qpool2 || error "pool_add failed"
+       pool_add_targets $qpool2 0 $(($OSTCOUNT - 1)) ||
+               error "pool_add_targets failed"
+
+       # create pools without hard limit
+       # initially such case raised several bugs
+       $LFS setquota -u $TSTUSR -B 0M --pool $qpool1 $DIR ||
+               error "set user quota failed"
+
+       $LFS setquota -u $TSTUSR -B 0M --pool $qpool2 $DIR ||
+               error "set user quota failed"
+
+       # make sure the system is clean
+       local used=$(getquota -u $TSTUSR global curspace)
+       echo "used $used"
+       [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
+
+       used=$(getquota -u $TSTUSR global bhardlimit $qpool)
+
+       test_1_check_write $testfile "user" $global_limit
+
+       used=$(getquota -u $TSTUSR global curspace $qpool1)
+       echo "qpool1 used $used"
+       used=$(getquota -u $TSTUSR global curspace $qpool2)
+       echo "qpool2 used $used"
+
+       rm -f $testfile
+       wait_delete_completed || error "wait_delete_completed failed"
+       sync_all_data || true
+
+       used=$(getquota -u $TSTUSR global curspace $qpool1)
+       [ $used -ne 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 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"
+
+       # test for user
+       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 $(($OSTCOUNT - 1)) ||
+               error "pool_add_targets failed"
+
+       pool_add $qpool2 || error "pool_add failed"
+       pool_add_targets $qpool2 0 $(($OSTCOUNT - 1)) ||
+               error "pool_add_targets failed"
+
+       $LFS setquota -u $TSTUSR -B ${limit1}M --pool $qpool1 $DIR ||
+               error "set user quota failed"
+
+       $LFS setquota -u $TSTUSR -B ${limit2}M --pool $qpool2 $DIR ||
+       error "set user quota failed"
+
+       # make sure the system is clean
+       local used=$(getquota -u $TSTUSR global curspace)
+       echo "used $used"
+       [ $used -ne 0 ] && error "used space($used) for user $TSTUSR isn't 0."
+
+       used=$(getquota -u $TSTUSR global bhardlimit $qpool)
+
+       test_1_check_write $testfile "user" $limit1
+
+       used=$(getquota -u $TSTUSR global curspace $qpool1)
+       echo "qpool1 used $used"
+       used=$(getquota -u $TSTUSR global curspace $qpool2)
+       echo "qpool2 used $used"
+
+       rm -f $testfile
+       wait_delete_completed || error "wait_delete_completed failed"
+       sync_all_data || true
+
+       used=$(getquota -u $TSTUSR global curspace $qpool1)
+       [ $used -ne 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 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"
+
+       # global_limit is much greater than limit1 to get
+       # different qunit's on osts. Since 1st qunit shrinking
+       # on OST1(that belongs to qpool1), this qunit should
+       # be sent to OST1.
+       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 1 1 ||
+               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 $testfile -c 1 -i 1 || error "setstripe $testfile failed"
+       chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
+
+       test_1_check_write $testfile "user" $limit1
+
+       $LFS setstripe $testfile2 -c 1 -i 0 ||
+               error "setstripe $testfile2 failed"
+       chown $TSTUSR.$TSTUSR $testfile2 || error "chown $testfile2 failed"
+       # Now write to file with a stripe on OST0, that doesn't belong to qpool1
+       log "Write..."
+       $RUNAS $DD of=$testfile2 count=20 ||
+               quota_error u $TSTUSR \
+                       "$qtype write failure, but expect success"
+
+       rm -f $testfile
+       rm -f $testfile2
+       wait_delete_completed || error "wait_delete_completed failed"
+       sync_all_data || true
+
+       used=$(getquota -u $TSTUSR global curspace $qpool1)
+       [ $used -ne 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 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"
+
+       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"
+
+       test_1_check_write $testfile "user" $limit1
+
+       pool_remove_target $qpool1 0
+       rm -f $testfile
+       wait_delete_completed || error "wait_delete_completed failed"
+       sync_all_data || true
+
+       pool_add_targets $qpool1 0 0 || error "pool_add_targets failed"
+       # qunit for appropriate element in lgd array should be set
+       # correctly(4096). Earlier it was not changed continuing to be 1024.
+       # This caused write to hung when it hit limit1 - qunit shrinking to 1024
+       # for qpool1 lqe didn't cause changing qunit for OST0 in gld array
+       # as it already was 1024. As flag "need_update" for this qunit was
+       # not set, new qunit wasn't sent to OST0. Thus revoke was not set
+       # for "qpool1" lqe and it couldn't set EDQUOT despite granted
+       # 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 testfile="$DIR/$tdir/$tfile-0"
+       local qpool="qpool1"
+       local mdmb_param="osc.*.max_dirty_mb"
+       local max_dirty_mb=$($LCTL get_param -n $mdmb_param | head -1)
+
+       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
+
+       # 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 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 $(($OSTCOUNT - 1)) ||
+               error "pool_add_targets failed"
+
+       $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR ||
+               error "set user quota failed"
+
+       # make sure the system is clean
+       local used=$(getquota -u $TSTUSR global curspace)
+       echo "used $used"
+       [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
+
+       $LFS setstripe $testfile -C 200 || error "setstripe $testfile failed"
+       chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
+
+       log "Write..."
+       $RUNAS $DD of=$testfile count=$((limit/2)) ||
+               quota_error u $TSTUSR \
+                       "$qtype write failure, but expect success"
+       log "Write out of block quota ..."
+       # this time maybe cache write,  ignore it's failure
+       $RUNAS $DD of=$testfile 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
+       sleep 5
+       $RUNAS $DD of=$testfile count=$OSTCOUNT seek=$limit &&
+               quota_error u $TSTUSR \
+                       "user write success, but expect EDQUOT"
+
+       rm -f $testfile
+       wait_delete_completed || error "wait_delete_completed failed"
+       sync_all_data || true
+
+       used=$(getquota -u $TSTUSR global curspace $qpool)
+       [ $used -ne 0 ] && quota_error u $TSTUSR \
+               "user quota isn't released after deletion"
+       return 0
+}
+run_test 1g "Quota pools: Block hard limit with wide striping"
+
+test_1h() {
+       local limit=10  # 10M
+       local testfile="$DIR/$tdir/$tfile-0"
+
+       check_for_fallocate
+
+       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"
+
+       # test for user
+       log "User quota (block hardlimit:$limit MB)"
+       $LFS setquota -u $TSTUSR -b 0 -B ${limit}M -i 0 -I 0 $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 $testfile -c 1 || error "setstripe $testfile failed"
+       chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
+
+       check_write_fallocate $testfile "user" $limit
+
+       rm -f $testfile
+       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 \
+               "user quota isn't released after deletion"
+       resetquota -u $TSTUSR
 }
-run_test 1 "Block hard limit (normal use and out of quota)"
+run_test 1h "Block hard limit test using fallocate"
 
 # test inode hardlimit
 test_2() {
-       local LIMIT=$((1024 * 1024)) # 1M inodes
        local TESTFILE="$DIR/$tdir/$tfile-0"
+       local LIMIT=$(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
 
-       [ "$SLOW" = "no" ] && LIMIT=1024 # 1k inodes
+       [ "$SLOW" = "no" ] || LIMIT=$((LIMIT * 1024))
 
        local FREE_INODES=$(mdt_free_inodes 0)
        echo "$FREE_INODES free inodes on master MDT"
@@ -743,32 +1231,38 @@ test_2() {
 run_test 2 "File hard limit (normal use and out of quota)"
 
 test_block_soft() {
-       local TESTFILE=$1
-       local TIMER=$(($2 * 3 / 2))
-       local LIMIT=$3
+       local testfile=$1
+       local grace=$2
+       local limit=$3
        local OFFSET=0
        local qtype=$4
+       local pool=$5
 
        setup_quota_test
-       trap cleanup_quota_test EXIT
+       stack_trap cleanup_quota_test EXIT
 
-       $LFS setstripe $TESTFILE -c 1 -i 0
-       chown $TSTUSR.$TSTUSR $TESTFILE
+       $LFS setstripe $testfile -c 1 -i 0
+       chown $TSTUSR.$TSTUSR $testfile
        [ "$qtype" == "p" ] && is_project_quota_supported &&
-               change_project -p $TSTPRJID $TESTFILE
+               change_project -p $TSTPRJID $testfile
 
        echo "Write up to soft limit"
-       $RUNAS $DD of=$TESTFILE count=$LIMIT ||
+       $RUNAS $DD of=$testfile count=$limit ||
                quota_error a $TSTUSR "write failure, but expect success"
-       OFFSET=$((LIMIT * 1024))
+       OFFSET=$((limit * 1024))
        cancel_lru_locks osc
 
        echo "Write to exceed soft limit"
-       $RUNAS dd if=/dev/zero of=$TESTFILE bs=1K count=10 seek=$OFFSET ||
+       $RUNAS dd if=/dev/zero of=$testfile bs=1K count=10 seek=$OFFSET ||
                quota_error a $TSTUSR "write failure, but expect success"
        OFFSET=$((OFFSET + 1024)) # make sure we don't write to same block
        cancel_lru_locks osc
 
+       echo "mmap write when over soft limit"
+       $RUNAS $MULTIOP $testfile.mmap OT40960SMW ||
+               quota_error a $TSTUSR "mmap write failure, but expect success"
+       cancel_lru_locks osc
+
        $SHOW_QUOTA_USER
        $SHOW_QUOTA_GROUP
        $SHOW_QUOTA_PROJID
@@ -777,13 +1271,12 @@ test_block_soft() {
        $SHOW_QUOTA_INFO_PROJID
 
        echo "Write before timer goes off"
-       $RUNAS dd if=/dev/zero of=$TESTFILE bs=1K count=10 seek=$OFFSET ||
+       $RUNAS dd if=/dev/zero of=$testfile bs=1K count=10 seek=$OFFSET ||
                quota_error a $TSTUSR "write failure, but expect success"
        OFFSET=$((OFFSET + 1024))
        cancel_lru_locks osc
 
-       echo "Sleep $TIMER seconds ..."
-       sleep $TIMER
+       wait_grace_time $qtype "block" $pool
 
        $SHOW_QUOTA_USER
        $SHOW_QUOTA_GROUP
@@ -792,12 +1285,13 @@ test_block_soft() {
        $SHOW_QUOTA_INFO_GROUP
        $SHOW_QUOTA_INFO_PROJID
 
-       echo "Write after timer goes off"
+       log "Write after timer goes off"
        # maybe cache write, ignore.
-       $RUNAS dd if=/dev/zero of=$TESTFILE bs=1K count=10 seek=$OFFSET || true
+       $RUNAS dd if=/dev/zero of=$testfile bs=1K count=10 seek=$OFFSET || true
        OFFSET=$((OFFSET + 1024))
        cancel_lru_locks osc
-       $RUNAS dd if=/dev/zero of=$TESTFILE bs=1K count=10 seek=$OFFSET &&
+       log "Write after cancel lru locks"
+       $RUNAS dd if=/dev/zero of=$testfile bs=1K count=10 seek=$OFFSET &&
                quota_error a $TSTUSR "write success, but expect EDQUOT"
 
        $SHOW_QUOTA_USER
@@ -808,7 +1302,7 @@ test_block_soft() {
        $SHOW_QUOTA_INFO_PROJID
 
        echo "Unlink file to stop timer"
-       rm -f $TESTFILE
+       rm -f $testfile
        wait_delete_completed
        sync_all_data || true
 
@@ -819,65 +1313,71 @@ test_block_soft() {
        $SHOW_QUOTA_INFO_GROUP
        $SHOW_QUOTA_INFO_PROJID
 
-       $LFS setstripe $TESTFILE -c 1 -i 0
-       chown $TSTUSR.$TSTUSR $TESTFILE
-       [ "$qtype" == "p" ] && change_project -p $TSTPRJID $TESTFILE
+       $LFS setstripe $testfile -c 1 -i 0
+       chown $TSTUSR.$TSTUSR $testfile
+       [ "$qtype" == "p" ] && change_project -p $TSTPRJID $testfile
 
        echo "Write ..."
-       $RUNAS $DD of=$TESTFILE count=$LIMIT ||
+       $RUNAS $DD of=$testfile count=$limit ||
                quota_error a $TSTUSR "write failure, but expect success"
        # cleanup
        cleanup_quota_test
 }
 
 # block soft limit
-test_3() {
-       local LIMIT=1  # 1MB
-       local GRACE=20 # 20s
-       local TESTFILE=$DIR/$tdir/$tfile-0
+test_3a() {
+       local grace=20 # 20s
+       if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
+           grace=60
+       fi
+       local testfile=$DIR/$tdir/$tfile-0
+
+       # get minimum soft qunit size
+       local limit=$(( $(do_facet $SINGLEMDS $LCTL get_param -n \
+               qmt.$FSNAME-QMT0000.dt-0x0.soft_least_qunit) / 1024 ))
 
        set_ost_qtype $QTYPE || error "enable ost quota failed"
 
-       echo "User quota (soft limit:$LIMIT MB  grace:$GRACE seconds)"
+       echo "User quota (soft limit:$limit MB  grace:$grace seconds)"
        # 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."
+       local used=$(getquota -u $TSTUSR global curspace)
+       [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
 
-       $LFS setquota -t -u --block-grace $GRACE --inode-grace \
+       $LFS setquota -t -u --block-grace $grace --inode-grace \
                $MAX_IQ_TIME $DIR || error "set user grace time failed"
-       $LFS setquota -u $TSTUSR -b ${LIMIT}M -B 0 -i 0 -I 0 $DIR ||
+       $LFS setquota -u $TSTUSR -b ${limit}M -B 0 -i 0 -I 0 $DIR ||
                error "set user quota failed"
 
-       test_block_soft $TESTFILE $GRACE $LIMIT "u"
+       test_block_soft $testfile $grace $limit "u"
 
-       echo "Group quota (soft limit:$LIMIT MB  grace:$GRACE seconds)"
-       TESTFILE=$DIR/$tdir/$tfile-1
+       echo "Group quota (soft limit:$limit MB  grace:$grace seconds)"
+       testfile=$DIR/$tdir/$tfile-1
        # make sure the system is clean
-       USED=$(getquota -g $TSTUSR global curspace)
-       [ $USED -ne 0 ] && error "Used space($USED) for group $TSTUSR isn't 0."
+       used=$(getquota -g $TSTUSR global curspace)
+       [ $used -ne 0 ] && error "Used space($used) for group $TSTUSR isn't 0."
 
-       $LFS setquota -t -g --block-grace $GRACE --inode-grace \
+       $LFS setquota -t -g --block-grace $grace --inode-grace \
                $MAX_IQ_TIME $DIR || error "set group grace time failed"
-       $LFS setquota -g $TSTUSR -b ${LIMIT}M -B 0 -i 0 -I 0 $DIR ||
+       $LFS setquota -g $TSTUSR -b ${limit}M -B 0 -i 0 -I 0 $DIR ||
                error "set group quota failed"
 
-       test_block_soft $TESTFILE $GRACE $LIMIT "g"
+       test_block_soft $testfile $grace $limit "g"
 
        if is_project_quota_supported; then
-               echo "Project quota (soft limit:$LIMIT MB  grace:$GRACE sec)"
-               TESTFILE=$DIR/$tdir/$tfile-2
+               echo "Project quota (soft limit:$limit MB  grace:$grace sec)"
+               testfile=$DIR/$tdir/$tfile-2
                # make sure the system is clean
-               USED=$(getquota -p $TSTPRJID global curspace)
-               [ $USED -ne 0 ] && error \
-                       "Used space($USED) for project $TSTPRJID isn't 0."
+               used=$(getquota -p $TSTPRJID global curspace)
+               [ $used -ne 0 ] && error \
+                       "Used space($used) for project $TSTPRJID isn't 0."
 
-               $LFS setquota -t -p --block-grace $GRACE --inode-grace \
+               $LFS setquota -t -p --block-grace $grace --inode-grace \
                        $MAX_IQ_TIME $DIR ||
                                error "set project grace time failed"
-               $LFS setquota -p $TSTPRJID -b ${LIMIT}M -B 0 -i 0 -I 0 \
+               $LFS setquota -p $TSTPRJID -b ${limit}M -B 0 -i 0 -I 0 \
                        $DIR || error "set project quota failed"
 
-               test_block_soft $TESTFILE $GRACE $LIMIT "p"
+               test_block_soft $testfile $grace $limit "p"
                resetquota -p $TSTPRJID
                $LFS setquota -t -p --block-grace $MAX_DQ_TIME --inode-grace \
                        $MAX_IQ_TIME $DIR ||
@@ -890,13 +1390,181 @@ test_3() {
        $LFS setquota -t -g --block-grace $MAX_DQ_TIME --inode-grace \
                $MAX_IQ_TIME $DIR || error "restore group grace time failed"
 }
-run_test 3 "Block soft limit (start timer, timer goes off, stop timer)"
+run_test 3a "Block soft limit (start timer, timer goes off, stop timer)"
+
+test_3b() {
+       local grace=20 # 20s
+       local qpool="qpool1"
+       if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
+               grace=60
+       fi
+       local testfile=$DIR/$tdir/$tfile-0
+
+       mds_supports_qp
+       # get minimum soft qunit size
+       local limit=$(( $(do_facet $SINGLEMDS $LCTL get_param -n \
+               qmt.$FSNAME-QMT0000.dt-0x0.soft_least_qunit) / 1024 ))
+       local glbl_limit=$((2*limit))
+       local glbl_grace=$((2*grace))
+       echo "limit $limit glbl_limit $glbl_limit"
+       echo "grace $grace glbl_grace $glbl_grace"
+
+       set_ost_qtype $QTYPE || error "enable ost quota failed"
+
+       echo "User quota in $qpool(soft limit:$limit MB  grace:$grace seconds)"
+       # 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."
+
+       pool_add $qpool || error "pool_add failed"
+       pool_add_targets $qpool 0 1 ||
+               error "pool_add_targets failed"
+
+       $LFS setquota -t -u --block-grace $glbl_grace --inode-grace \
+               $MAX_IQ_TIME $DIR || error "set user grace time failed"
+       $LFS setquota -t -u --block-grace $grace \
+               --pool $qpool $DIR || error "set user grace time failed"
+
+       $LFS setquota -u $TSTUSR -b ${glbl_limit}M -B 0 -i 0 -I 0 $DIR ||
+               error "set user quota failed"
+       $LFS setquota -u $TSTUSR -b ${limit}M -B 0 --pool $qpool $DIR ||
+               error "set user quota failed"
+
+       test_block_soft $testfile $grace $limit "u" $qpool
+
+       echo "Group quota in $qpool(soft limit:$limit MB  grace:$grace seconds)"
+       testfile=$DIR/$tdir/$tfile-1
+       # make sure the system is clean
+       used=$(getquota -g $TSTUSR global curspace)
+       [ $used -ne 0 ] && error "Used space($used) for group $TSTUSR isn't 0."
+
+       $LFS setquota -t -g --block-grace $glbl_grace --inode-grace \
+               $MAX_IQ_TIME $DIR || error "set group grace time failed"
+       $LFS setquota -t -g --block-grace $grace \
+               --pool $qpool $DIR || error "set group grace time failed"
+
+       $LFS setquota -g $TSTUSR -b ${glbl_limit}M -B 0 -i 0 -I 0 $DIR ||
+               error "set group quota failed"
+       $LFS setquota -g $TSTUSR -b ${limit}M -B 0 --pool $qpool $DIR ||
+               error "set group quota failed"
+
+       test_block_soft $testfile $grace $limit "g" $qpool
+
+       if is_project_quota_supported; then
+               echo "Project quota in $qpool(soft:$limit MB  grace:$grace sec)"
+               testfile=$DIR/$tdir/$tfile-2
+               # make sure the system is clean
+               used=$(getquota -p $TSTPRJID global curspace)
+               [ $used -ne 0 ] && error \
+                       "Used space($used) for project $TSTPRJID isn't 0."
+
+               $LFS setquota -t -p --block-grace $glbl_grace --inode-grace \
+                       $MAX_IQ_TIME $DIR ||
+                               error "set project grace time failed"
+               $LFS setquota -t -p --block-grace $grace \
+                       --pool $qpool $DIR ||
+                               error "set project grace time failed"
+
+               $LFS setquota -p $TSTPRJID -b ${glbl_limit}M -B 0 -i 0 -I 0 \
+                       $DIR || error "set project quota failed"
+               $LFS setquota -p $TSTPRJID -b ${limit}M -B 0 \
+                       --pool $qpool $DIR || error "set project quota failed"
+
+               test_block_soft $testfile $grace $limit "p" $qpool
+               resetquota -p $TSTPRJID
+               $LFS setquota -t -p --block-grace $MAX_DQ_TIME --inode-grace \
+                       $MAX_IQ_TIME $DIR ||
+                               error "restore project grace time failed"
+               $LFS setquota -t -p --block-grace $MAX_DQ_TIME --pool $qpool \
+                       $DIR || error "set project grace time failed"
+       fi
+
+       # cleanup
+       $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
+               $MAX_IQ_TIME $DIR || error "restore user grace time failed"
+       $LFS setquota -t -u --block-grace $MAX_DQ_TIME \
+               --pool $qpool $DIR || error "restore user grace time failed"
+       $LFS setquota -t -g --block-grace $MAX_DQ_TIME --inode-grace \
+               $MAX_IQ_TIME $DIR || error "restore group grace time failed"
+       $LFS setquota -t -g --block-grace $MAX_DQ_TIME \
+               --pool $qpool $DIR || error "restore group grace time failed"
+}
+run_test 3b "Quota pools: Block soft limit (start timer, expires, stop timer)"
+
+test_3c() {
+       local grace=20 # 20s
+       local qpool="qpool1"
+       local qpool2="qpool2"
+       if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
+               grace=60
+       fi
+       local testfile=$DIR/$tdir/$tfile-0
+
+       mds_supports_qp
+       # get minimum soft qunit size
+       local limit=$(( $(do_facet $SINGLEMDS $LCTL get_param -n \
+               qmt.$FSNAME-QMT0000.dt-0x0.soft_least_qunit) / 1024 ))
+       local limit2=$((limit+4))
+       local glbl_limit=$((limit+8))
+       local grace1=$((grace+10))
+       local grace2=$grace
+       local glbl_grace=$((grace+20))
+       echo "limit $limit limit2 $limit2 glbl_limit $glbl_limit"
+       echo "grace1 $grace1 grace2 $grace2 glbl_grace $glbl_grace"
+
+       set_ost_qtype $QTYPE || error "enable ost quota failed"
+
+       echo "User quota in qpool2(soft:$limit2 MB grace:$grace2 seconds)"
+       # 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."
+
+       pool_add $qpool || error "pool_add failed"
+       pool_add_targets $qpool 0 1 ||
+               error "pool_add_targets failed"
+
+       pool_add $qpool2 || error "pool_add failed"
+       pool_add_targets $qpool2 0 1 ||
+               error "pool_add_targets failed"
+
+
+       $LFS setquota -t -u --block-grace $glbl_grace --inode-grace \
+               $MAX_IQ_TIME $DIR || error "set user grace time failed"
+       $LFS setquota -t -u --block-grace $grace1 \
+               --pool $qpool $DIR || error "set user grace time failed"
+       $LFS setquota -t -u --block-grace $grace2 \
+               --pool $qpool2 $DIR || error "set user grace time failed"
+
+       $LFS setquota -u $TSTUSR -b ${glbl_limit}M -B 0 -i 0 -I 0 $DIR ||
+               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
+       # 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 ||
+               error "set user quota failed"
+
+       test_block_soft $testfile $grace2 $limit2 "u" $qpool2
+
+       # cleanup
+       $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
+               $MAX_IQ_TIME $DIR || error "restore user grace time failed"
+       $LFS setquota -t -u --block-grace $MAX_DQ_TIME \
+               --pool $qpool $DIR || error "restore user grace time failed"
+       $LFS setquota -t -u --block-grace $MAX_DQ_TIME \
+               --pool $qpool2 $DIR || error "restore user grace time failed"
+}
+run_test 3c "Quota pools: check block soft limit on different pools"
 
 test_file_soft() {
        local TESTFILE=$1
        local LIMIT=$2
        local grace=$3
-       local TIMER=$(($grace * 3 / 2))
+       local qtype=$4
+       local SOFT_LIMIT=$(do_facet $SINGLEMDS $LCTL get_param -n \
+               qmt.$FSNAME-QMT0000.md-0x0.soft_least_qunit)
 
        setup_quota_test
        trap cleanup_quota_test EXIT
@@ -919,8 +1587,7 @@ test_file_soft() {
                        "but expect success. $trigger_time, $cur_time"
        sync_all_data || true
 
-       echo "Sleep $TIMER seconds ..."
-       sleep $TIMER
+       wait_grace_time $qtype "file"
 
        $SHOW_QUOTA_USER
        $SHOW_QUOTA_GROUP
@@ -930,12 +1597,8 @@ test_file_soft() {
        $SHOW_QUOTA_INFO_PROJID
 
        echo "Create file after timer goes off"
-       # There is a window that space is accounted in the quota usage but
-       # hasn't been decreased from the pending write, if we acquire quota
-       # in this window, we'll acquire more than we needed.
-       $RUNAS touch ${TESTFILE}_after_1 ${TESTFILE}_after_2 || true
-       sync_all_data || true
-       $RUNAS touch ${TESTFILE}_after_3 &&
+       # exceed least soft limit is possible
+       $RUNAS createmany -m ${TESTFILE}_after_3 $((SOFT_LIMIT + 1)) &&
                quota_error a $TSTUSR "create after timer expired," \
                        "but expect EDQUOT"
        sync_all_data || true
@@ -963,7 +1626,8 @@ test_file_soft() {
 
 # file soft limit
 test_4a() {
-       local LIMIT=10 # inodes
+       local LIMIT=$(do_facet $SINGLEMDS $LCTL get_param -n \
+               qmt.$FSNAME-QMT0000.md-0x0.soft_least_qunit)
        local TESTFILE=$DIR/$tdir/$tfile-0
        local GRACE=12
 
@@ -979,9 +1643,9 @@ test_4a() {
        $LFS setquota -u $TSTUSR -b 0 -B 0 -i $LIMIT -I 0 $DIR ||
                error "set user quota failed"
 
-       [ $(facet_fstype $SINGLEMDS) = "zfs" ] && GRACE=20
+       [ "$mds1_FSTYPE" = zfs ] && GRACE=20
 
-       test_file_soft $TESTFILE $LIMIT $GRACE
+       test_file_soft $TESTFILE $LIMIT $GRACE "u"
 
        echo "Group quota (soft limit:$LIMIT files  grace:$GRACE seconds)"
        # make sure the system is clean
@@ -994,7 +1658,7 @@ test_4a() {
                error "set group quota failed"
        TESTFILE=$DIR/$tdir/$tfile-1
 
-       test_file_soft $TESTFILE $LIMIT $GRACE
+       test_file_soft $TESTFILE $LIMIT $GRACE "g"
 
        if is_project_quota_supported; then
                echo "Project quota (soft limit:$LIMIT files grace:$GRACE sec)"
@@ -1010,7 +1674,7 @@ test_4a() {
 
                TESTFILE=$DIR/$tdir/$tfile-1
                # one less than limit, because of parent directory included.
-               test_file_soft $TESTFILE $((LIMIT-1)) $GRACE
+               test_file_soft $TESTFILE $((LIMIT-1)) $GRACE "p"
                resetquota -p $TSTPRJID
                $LFS setquota -t -p --block-grace $MAX_DQ_TIME --inode-grace \
                        $MAX_IQ_TIME $DIR ||
@@ -1158,6 +1822,19 @@ test_6() {
                error "write $TESTFILE failure, expect success"
        $RUNAS2 $DD of=$TESTFILE2 count=1 ||
                error "write $TESTFILE2 failure, expect success"
+
+       if at_is_enabled; then
+               at_max_saved=$(at_max_get ost1)
+               at_max_set $TIMEOUT ost1
+
+               # write to enforced ID ($TSTUSR) to exceed limit to make sure
+               # DQACQ is sent, which makes at_max to take effect
+               $RUNAS $DD of=$TESTFILE count=$LIMIT seek=1 oflag=sync \
+                                                               conv=notrunc
+               rm -f $TESTFILE
+               wait_delete_completed
+       fi
+
        sync; sync
        sync_all_data || true
 
@@ -1181,6 +1858,8 @@ test_6() {
        echo "Sleep for $((TIMEOUT * 2 + 1)) seconds ..."
        sleep $((TIMEOUT * 2 + 1))
 
+       [ $at_max_saved -ne 0 ] && at_max_set $at_max_saved ost1
+
        # write should be blocked and never finished
        if ! ps -p $DDPID  > /dev/null 2>&1; then
                lustre_fail mds 0 0
@@ -1191,7 +1870,7 @@ test_6() {
 
        # no watchdog is triggered
        do_facet ost1 dmesg > $TMP/lustre-log-${TESTNAME}.log
-       watchdog=$(awk '/Service thread pid/ && /was inactive/ \
+       watchdog=$(awk '/[Ss]ervice thread pid/ && /was inactive/ \
                        { print; }' $TMP/lustre-log-${TESTNAME}.log)
        [ -z "$watchdog" ] || error "$watchdog"
 
@@ -1374,7 +2053,7 @@ test_7c() {
        # enable ost quota
        set_ost_qtype $QTYPE || error "enable ost quota failed"
        # trigger reintegration
-       local procf="osd-$(facet_fstype ost1).$FSNAME-OST*."
+       local procf="osd-$ost1_FSTYPE.$FSNAME-OST*."
        procf=${procf}quota_slave.force_reint
        do_facet ost1 $LCTL set_param $procf=1 ||
                error "force reintegration failed"
@@ -1443,7 +2122,7 @@ test_7e() {
 
        # LU-2435: skip this quota test if underlying zfs version has not
        # supported native dnode accounting
-       [ "$(facet_fstype mds1)" == "zfs" ] && {
+       [ "$mds1_FSTYPE" == zfs ] && {
                local F="feature@userobj_accounting"
                local pool=$(zpool_name mds1)
                local feature=$(do_facet mds1 $ZPOOL get -H $F $pool)
@@ -1984,7 +2663,7 @@ test_18() {
 
        # check if watchdog is triggered
        do_facet ost1 dmesg > $TMP/lustre-log-${TESTNAME}.log
-       local watchdog=$(awk '/Service thread pid/ && /was inactive/ \
+       local watchdog=$(awk '/[Ss]ervice thread pid/ && /was inactive/ \
                        { print; }' $TMP/lustre-log-${TESTNAME}.log)
        [ -z "$watchdog" ] || error "$watchdog"
        rm -f $TMP/lustre-log-${TESTNAME}.log
@@ -2227,7 +2906,7 @@ test_23_sub() {
 }
 
 test_23() {
-       [ $(facet_fstype ost1) == "zfs" ] &&
+       [ "$ost1_FSTYPE" == zfs ] &&
                skip "Overwrite in place is not guaranteed to be " \
                "space neutral on ZFS"
 
@@ -2297,8 +2976,8 @@ test_27b() { # b20200
                $SHOW_QUOTA_PROJID ||
                        error "lfs quota failed with projid argument"
        fi
-       resetquota -u $TSTUSR
-       resetquota -g $TSTUSR
+       resetquota -u $TSTID
+       resetquota -g $TSTID
        resetquota -p $TSTPRJID
        return 0
 }
@@ -2668,7 +3347,7 @@ run_test 35 "Usage is still accessible across reboot"
 # chown/chgrp to the file created with MDS_OPEN_DELAY_CREATE
 # LU-5006
 test_37() {
-       [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.6.93) ] &&
+       [ "$MDS1_VERSION" -lt $(version_code 2.6.93) ] &&
                skip "Old server doesn't have LU-5006 fix."
 
        setup_quota_test || error "setup quota failed with $?"
@@ -2700,7 +3379,7 @@ run_test 37 "Quota accounted properly for file created by 'lfs setstripe'"
 
 # LU-8801
 test_38() {
-       [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.8.60) ] &&
+       [ "$MDS1_VERSION" -lt $(version_code 2.8.60) ] &&
                skip "Old server doesn't have LU-8801 fix."
 
        [ "$UID" != 0 ] && skip_env "must run as root" && return
@@ -2729,7 +3408,7 @@ test_38() {
        cancel_lru_locks osc
        sync; sync_all_data || true
 
-       local procf="osd-$(facet_fstype $SINGLEMDS).$FSNAME-MDT0000"
+       local procf="osd-$mds1_FSTYPE.$FSNAME-MDT0000"
        procf=${procf}.quota_slave.acct_user
        local accnt_cnt
 
@@ -2843,6 +3522,85 @@ test_40c() {
 }
 run_test 40c "Remote child Dir inherit project quota properly"
 
+test_40d() {
+       [ "$MDSCOUNT" -lt "2" ] && skip_env "needs >= 2 MDTs"
+       is_project_quota_supported || skip "Project quota is not supported"
+
+       setup_quota_test || error "setup quota failed with $?"
+       local dir="$DIR/$tdir/dir"
+
+       mkdir -p $dir
+       $LFS setdirstripe -D -c 2 -i -1 $dir || error "setdirstripe failed"
+       change_project -sp $TSTPRJID $dir ||
+               error "change project on $dir failed"
+       for i in $(seq 5); do
+               mkdir -p $dir/d$i/d$i ||
+                       error "mkdir $dir/d$i/d$i failed"
+               local projid=$($LFS project -d $dir/d$i/d$i |
+                              awk '{print $1}')
+               [ "$projid" == "$TSTPRJID" ] ||
+                       error "projid id expected $TSTPRJID not $projid"
+               touch $dir/d$i/d$i/file
+               #verify inherit works file for stripe dir.
+               local projid=$($LFS project -d $dir/d$i/d$i/file | awk '{print $1}')
+               [ "$projid" == "$TSTPRJID" ] ||
+                       error "file under remote dir expected 1 not $projid"
+       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
+}
+run_test 40d "Stripe Directory inherit project quota properly"
+
+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
+       local projid=$((testnum * 1000))
+
+       quota_init
+
+       # enable mdt/ost quota
+       set_mdt_qtype ugp || error "enable mdt quota failed"
+       set_ost_qtype ugp || error "enable ost quota failed"
+
+       test_mkdir -p $dir && change_project -sp $projid $dir
+       $LFS setquota -p $projid -b 0 -B ${blimit}K -i 0 -I $ilimit $dir ||
+               error "set project quota failed"
+
+       sync; sync_all_data
+       sleep_maxage
+
+       # check if df output works as expected
+       echo "== global statfs: $MOUNT =="
+       df -kP $MOUNT; df -iP $MOUNT; $LFS quota -p $projid $dir
+       echo
+       echo "== project statfs (prjid=$projid): $dir =="
+       df -kP $dir; df -iP $dir
+       local bused=$(getquota -p $projid global curspace)
+       local iused=$(getquota -p $projid global curinodes)
+       # note trailing space to match double printf from awk
+       local expected="$blimit $bused $ilimit $iused "
+
+       wait_update $HOSTNAME \
+               "{ df -kP $dir; df -iP $dir; } |
+                awk '/$FSNAME/ { printf \\\"%d %d \\\", \\\$2,\\\$3 }'" \
+               "$expected" ||
+               error "failed to get correct statfs for project quota"
+
+       cleanup_quota_test
+}
+run_test 41 "df should return projid-specific values"
+
 test_50() {
        ! is_project_quota_supported &&
                skip "Project quota is not supported"
@@ -2965,8 +3723,8 @@ test_54() {
        #clear project but with kept projid
        change_project -rCk $DIR/$tdir
        proj_count1=$(lfs project -rcp $TSTPRJID $DIR/$tdir | wc -l)
-       [ $proj_count1 -eq $proj_count ] ||
-                       error "c3: expected $proj_count got $proj_count1"
+       [ $proj_count1 -eq 1 ] ||
+                       error "c3: expected 1 got $proj_count1"
 
        #verify projid untouched.
        proj_count1=$(lfs project -r $DIR/$tdir | grep -c $TSTPRJID)
@@ -2993,7 +3751,7 @@ test_54() {
 run_test 54 "basic lfs project interface test"
 
 test_55() {
-       [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10.58) ] &&
+       [ "$MDS1_VERSION" -lt $(version_code 2.10.58) ] &&
                skip "Not supported before 2.10.58."
        setup_quota_test || error "setup quota failed with $?"
 
@@ -3063,7 +3821,7 @@ test_57() {
        #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 }'" \
-                       " failed to get xattr for '$dir/pipe'" || return 1
+                       " unable to get xattr for fifo '$dir/pipe'" || return 1
        #command can process further if it hit some errors
        touch $dir/aaa $dir/bbb
        mkdir $dir/subdir -p
@@ -3078,7 +3836,7 @@ test_57() {
 run_test 57 "lfs project could tolerate errors"
 
 test_59() {
-       [ "$(facet_fstype $SINGLEMDS)" != "ldiskfs" ] &&
+       [ "$mds1_FSTYPE" != ldiskfs ] &&
                skip "ldiskfs only test"
        disable_project_quota
        setup_quota_test || error "setup quota failed with $?"
@@ -3125,7 +3883,7 @@ run_test 60 "Test quota for root with setgid"
 
 # test default quota
 test_default_quota() {
-       [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.51) ] &&
+       [ "$MDS1_VERSION" -lt $(version_code 2.11.51) ] &&
                skip "Not supported before 2.11.51."
 
        local qtype=$1
@@ -3320,8 +4078,8 @@ test_62() {
 run_test 62 "Project inherit should be only changed by root"
 
 test_dom() {
-       [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.55) ] &&
-               skip "Not supported before 2.11.55" && return
+       [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ] &&
+               skip "Not supported before 2.11.55"
 
        local qtype=$1
        local qid=$TSTUSR
@@ -3431,6 +4189,623 @@ test_63() {
 }
 run_test 63 "quota on DoM tests"
 
+test_64() {
+       ! is_project_quota_supported &&
+               skip "Project quota is not supported"
+       setup_quota_test || error "setup quota failed with $?"
+       local dir1="$DIR/$tdir/"
+
+       touch $dir1/file
+       ln -s $dir1/file $dir1/file_link
+
+       $LFS project -sp $TSTPRJID $dir1/file_link >&/dev/null &&
+               error "set symlink file's project should fail"
+
+       $LFS project $TSTPRJID $dir1/file_link >&/dev/null &&
+               error "get symlink file's project should fail"
+
+       cleanup_quota_test
+}
+run_test 64 "lfs project on symlink files should fail"
+
+test_65() {
+       local SIZE=10 #10M
+       local TESTFILE="$DIR/$tdir/$tfile-0"
+
+       setup_quota_test || error "setup quota failed with $?"
+       set_ost_qtype $QTYPE || error "enable ost quota failed"
+       quota_init
+
+       echo "Write..."
+       $RUNAS $DD of=$TESTFILE count=$SIZE ||
+               error "failed to write"
+       # flush cache, ensure noquota flag is set on client
+       cancel_lru_locks osc
+       sync; sync_all_data || true
+
+       local quota_u=$($LFS quota -u $TSTUSR $DIR)
+       local quota_g=$($LFS quota -g $TSTUSR $DIR)
+       local quota_all=$($RUNAS $LFS quota $DIR)
+
+       [ "$(echo "$quota_all" | head -n3)" != "$quota_u" ] &&
+               error "usr quota not match"
+       [ "$(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"
+
+test_66() {
+       ! is_project_quota_supported &&
+               skip "Project quota is not supported"
+       [ "$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
+
+       test_mkdir -i 0 -c 1 $testdir || error "failed to mkdir"
+       chown -R $TSTID:$TSTID $testdir
+       change_project -sp $TSTPRJID $testdir
+       $RUNAS mkdir $testdir/foo || error "failed to mkdir foo"
+
+       $RUNAS lfs project -p 0 $testdir/foo &&
+               error "nonroot user should fail to set projid"
+
+       $RUNAS lfs project -C $testdir/foo &&
+               error "nonroot user should fail to clear projid"
+
+       change_project -C $testdir/foo || error "failed to clear project"
+
+       do_facet mds1 $LCTL set_param mdt.*.enable_chprojid_gid=-1
+       $RUNAS lfs project -p $TSTPRJID $testdir/foo || error \
+       "failed to set projid with normal user when enable_chprojid_gid=-1"
+
+       $RUNAS lfs project -rC $testdir/ || error \
+"failed to clear project state with normal user when enable_chprojid_gid=-1"
+
+       touch $testdir/bar || error "failed touch $testdir/bar"
+       $RUNAS lfs project -p $TSTPRJID $testdir/bar && error \
+       "normal user should not be able to set projid on root owned file"
+
+       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"
+
+test_67_write() {
+       local file="$1"
+       local qtype="$2"
+       local size=$3
+       local _runas=""
+       local short_qtype=${qtype:0:1}
+
+       echo "file "$file
+       echo "0 $0 1 $1 2 $2 3 $3 4 $4"
+       case "$4" in
+               quota_usr)  _runas=$RUNAS;;
+               quota_2usr) _runas=$RUNAS2;;
+               *)          error "unknown quota parameter $4";;
+       esac
+
+       log "Write..."
+       date
+       $_runas $DD of=$file count=$size ||
+               quota_error $short_qtype $TSTUSR \
+                       "$qtype write failure, but expect success"
+       date
+       cancel_lru_locks osc
+       date
+       sync; sync_all_data || true
+       date
+}
+
+getgranted() {
+       local pool=$1
+       local ptype=$2
+       local userid=$3
+       local qtype=$4
+       local param=qmt.$FSNAME-QMT0000.$ptype-$pool.glb-$qtype
+
+       do_facet mds1 $LCTL get_param $param |
+               grep -A2 $userid | awk -F'[, ]*' 'NR==2{print $9}'
+}
+
+test_67() {
+       local limit=20  # 20M
+       local testfile="$DIR/$tdir/$tfile-0"
+       local testfile2="$DIR/$tdir/$tfile-1"
+       local testfile3="$DIR/$tdir/$tfile-2"
+       local qpool="qpool1"
+       local used
+       local granted
+       local granted_mb
+
+       mds_supports_qp
+       [ "$ost1_FSTYPE" == zfs ] &&
+               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"
+
+       # test for user
+       log "User quota (block hardlimit:$limit MB)"
+       $LFS setquota -u $TSTUSR -b 0 -B ${limit}M -i 0 -I 0 $DIR ||
+               error "set user quota failed"
+
+       # make sure the system is clean
+       used=$(getquota -u $TSTUSR global curspace)
+       [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
+
+       granted=$(getgranted "0x0" "dt" $TSTID "usr")
+       echo "granted 0x0 before write $granted"
+
+       # trigger reintegration
+       local procf="osd-$(facet_fstype ost1).$FSNAME-OST*."
+       procf=${procf}quota_slave.force_reint
+       do_facet ost1 $LCTL set_param $procf=1 ||
+               error "force reintegration failed"
+       wait_ost_reint "u" || error "reintegration failed"
+       granted=$(getgranted "0x0" "dt" $TSTID "usr")
+       [ $granted -ne 0 ] &&
+               error "Granted($granted) for $TSTUSR in $qpool isn't 0."
+
+       $LFS setstripe $testfile -c 1 -i 0 || error "setstripe $testfile failed"
+       chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
+
+       # write 10 MB to testfile
+       test_67_write "$testfile" "user" 10 "quota_usr"
+
+       # create qpool and add OST1
+       pool_add $qpool || error "pool_add failed"
+       pool_add_targets $qpool 1 1 || error "pool_add_targets failed"
+       # as quota_usr hasn't limits, lqe may absent. But it should be
+       # created after the 1st direct qmt_get.
+       used=$(getquota -u $TSTUSR global bhardlimit $qpool)
+
+       # check granted - should be 0, as testfile is located only on OST0
+       granted=$(getgranted "0x0" "dt" $TSTID "usr")
+       echo "global granted $granted"
+       granted=$(getgranted $qpool "dt" $TSTID "usr")
+       echo "$qpool granted $granted"
+       [ $granted -ne 0 ] &&
+               error "Granted($granted) for $TSTUSR in $qpool isn't 0."
+
+       # add OST0 to qpool and check granted space
+       pool_add_targets $qpool 0 1 ||
+               error "pool_add_targets failed"
+       granted_mb=$(($(getgranted $qpool "dt" $TSTID "usr")/1024))
+       echo "Granted $granted_mb MB"
+       #should be 10M + qunit for each OST
+       [ $granted_mb -ge 10 -a $granted_mb -lt $limit ] ||
+               error "Granted($granted_mb) for $TSTUSR in $qpool is wrong."
+
+       $LFS setstripe $testfile2 -c 1 -i 1 ||
+               error "setstripe $testfile2 failed"
+       chown $TSTUSR2.$TSTUSR2 $testfile2 || error "chown $testfile2 failed"
+       # Write from another user and check that qpool1
+       # shows correct granted, despite quota_2usr hasn't limits in qpool1.
+       test_67_write "$testfile2" "user" 10 "quota_2usr"
+       used=$(getquota -u $TSTUSR2 global curspace $qpool)
+       granted=$(getgranted $qpool "dt" $TSTID2 "usr")
+       [ $granted -ne 0 ] &&
+               error "Granted($granted) for $TSTUSR2 in $qpool isn't 0."
+
+       # Granted space for quota_2usr in qpool1 should appear only
+       # when global lqe for this user becomes enforced.
+       $LFS setquota -u $TSTUSR2 -B ${limit}M $DIR ||
+               error "set user quota failed"
+       granted_mb=$(($(getgranted $qpool "dt" $TSTID2 "usr")/1024))
+       echo "granted_mb $granted_mb"
+       [ $granted_mb -ge 10 -a $granted_mb -lt $limit ] ||
+               error "Granted($granted) for $TSTUSR in $qpool is wrong."
+
+       $LFS setstripe $testfile3 -c 1 -i 0 ||
+               error "setstripe $testfile3 failed"
+       chown $TSTUSR2.$TSTUSR2 $testfile3 || error "chown $testfile3 failed"
+       test_67_write "$testfile3" "user" 10 "quota_2usr"
+       granted_mb=$(($(getgranted $qpool "dt" $TSTID2 "usr")/1024))
+       echo "$testfile3 granted_mb $granted_mb"
+       [ $granted_mb -eq $limit ] ||
+               error "Granted($granted_mb) for $TSTUSR2 is not equal to 20M"
+
+       # remove OST1 from the qpool1 and check granted space
+       # should be 0 for TSTUSR and 10M for TSTUSR2
+       pool_remove_target $qpool 0
+       granted_mb=$(($(getgranted $qpool "dt" $TSTID "usr")/1024))
+       [ $granted_mb -eq 0 ] ||
+               error "Granted($granted_mb) for $TSTUSR in $qpool != 0."
+       granted_mb=$(($(getgranted $qpool "dt" $TSTID2 "usr")/1024))
+       [ $granted_mb -eq 10 ] ||
+               error "Granted($granted_mb) for $TSTUSR2 is not equal to 10M"
+
+       rm -f $testfile
+       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 \
+               "user quota isn't released after deletion"
+       resetquota -u $TSTUSR
+
+       cleanup_quota_test
+}
+run_test 67 "quota pools recalculation"
+
+get_slave_nr() {
+       local pool=$1
+       local qtype=$2
+       local nr
+
+       do_facet mds1 $LCTL get_param -n qmt.$FSNAME-QMT0000.dt-$pool.info |
+               awk '/usr/ {getline; print $2}'
+}
+
+test_68()
+{
+       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"
+
+       # check slave number for glbal pool
+       local nr=$(get_slave_nr "0x0" "usr")
+       echo "nr result $nr"
+       [[ $nr != $((OSTCOUNT + MDSCOUNT)) ]] &&
+               error "Slave_nr $nr for global pool != ($OSTCOUNT + $MDSCOUNT)"
+
+       # create qpool and add OST1
+       pool_add $qpool || error "pool_add failed"
+       nr=$(get_slave_nr $qpool "usr")
+       [[ $nr != 0 ]] && error "Slave number $nr for $qpool != 0"
+
+       # add OST1 to qpool
+       pool_add_targets $qpool 1 1 || error "pool_add_targets failed"
+       nr=$(get_slave_nr $qpool "usr")
+       [[ $nr != 1 ]] && error "Slave number $nr for $qpool != 1"
+
+       # add OST0 to qpool
+       pool_add_targets $qpool 0 1 || error "pool_add_targets failed"
+       nr=$(get_slave_nr $qpool "usr")
+       [[ $nr != 2 ]] && error "Slave number $nr for $qpool != 2"
+
+       # remove OST0
+       pool_remove_target $qpool 0
+       nr=$(get_slave_nr $qpool "usr")
+       [[ $nr != 1 ]] && error "Slave number $nr for $qpool != 1"
+
+       # remove OST1
+       pool_remove_target $qpool 1
+       nr=$(get_slave_nr $qpool "usr")
+       [[ $nr != 0 ]] && error "Slave number $nr for $qpool != 0"
+
+       # Check again that all is fine with global pool
+       nr=$(get_slave_nr "0x0" "usr")
+       [[ $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 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"
+       set_mdt_qtype $QTYPE || error "enable mdt quota failed"
+
+       # Save DOM only at MDT0
+       $LFS setdirstripe -c 1 -i 0 $dom0 || error "cannot create $dom0"
+       $LFS setstripe -E 1M $dom0 -L mdt || error "setstripe to $dom0 failed"
+       chmod 0777 $dom0
+       $LFS setstripe -c 1 -i 0 "$DIR/$tdir/"
+
+       # create qpool and add OST0
+       pool_add $qpool || error "pool_add failed"
+       pool_add_targets $qpool 0 0 || error "pool_add_targets 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"
+
+       log "User quota (block hardlimit:$limit MB)"
+       $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR ||
+               error "set user quota failed"
+
+       $RUNAS dd if=/dev/zero of="$dom0/f1" bs=1K count=512 oflag=sync ||
+               quota_error u $TSTUSR "write failed"
+
+       $RUNAS dd if=/dev/zero of="$dom0/f1" bs=1K count=512 seek=512 \
+               oflag=sync || quota_error u $TSTUSR "write failed"
+
+       $RUNAS $DD of=$testfile count=$limit || true
+
+       # flush cache, ensure noquota flag is set on client
+       cancel_lru_locks osc
+       sync; sync_all_data || true
+
+       # MDT0 shouldn't get EDQUOT with glimpse.
+       $RUNAS $DD of=$testfile count=$limit seek=$limit &&
+               quota_error u $TSTUSR \
+                       "user write success, but expect EDQUOT"
+
+       # Now all members of qpool1 should get EDQUOT. Expect success
+       # when write to DOM on MDT0, as it belongs to global pool.
+       $RUNAS dd if=/dev/zero of="$dom0/f1" bs=1K count=512 \
+               oflag=sync || quota_error u $TSTUSR "write failed"
+
+       $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()
+{
+       local qpool="qpool1"
+       local limit=20
+       local err=0
+       local bhard
+
+       [[ CLIENT_VERSION -lt $(version_code $VERSION_WITH_QP) ]] &&
+               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
+
+       # create qpool and add OST0
+       pool_add $qpool || error "pool_add failed"
+       pool_add_targets $qpool 0 0 || error "pool_add_targets failed"
+
+       $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR
+       rc=$?
+       [ $rc -eq $err ] || error "setquota res $rc != $err"
+
+       # If MDS supports QP, check that limit was set properly.
+       if [[ $MDS1_VERSION -ge $(version_code $VERSION_WITH_QP) ]]; then
+               bhard=$(getquota -u $TSTUSR global bhardlimit $qpool)
+               echo "hard limit $bhard limit $limit"
+               [ $bhard -ne $((limit*1024)) ] &&
+                       error "bhard:$bhard for $qpool!=$((limit*1024))"
+       fi
+
+       $LFS quota -u $TSTUSR --pool $qpool $DIR
+       rc=$?
+       [ $rc -eq $err ] || error "quota res $rc != $err"
+
+       cleanup_quota_test
+}
+run_test 70 "check lfs setquota/quota with a pool option"
+
+test_71a()
+{
+       local limit=10  # 10M
+       local global_limit=100  # 100M
+       local testfile="$DIR/$tdir/$tfile-0"
+       local qpool="qpool1"
+       local qpool2="qpool2"
+
+       [ "$ost1_FSTYPE" == zfs ] &&
+               skip "ZFS grants some block space together with inode"
+       [[ $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"
+
+       # test for user
+       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 $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 ${limit}M --pool $qpool2 $DIR ||
+               error "set user quota failed"
+
+       # make sure the system is clean
+       local used=$(getquota -u $TSTUSR global curspace)
+
+       echo "used $used"
+       [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
+
+       # create 1st component 1-10M
+       $LFS setstripe -E 10M -S 1M -c 1 -i 0 $testfile
+       #create 2nd component 10-30M
+       $LFS setstripe --component-add -E 30M -c 1 -i 1 $testfile
+       chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
+
+       # сheck normal use and out of quota with PFL
+       # 1st element is in qppol1(OST0), 2nd in qpool2(OST2).
+       test_1_check_write $testfile "user" $((limit*2))
+       rm -f $testfile
+       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 \
+               "user quota isn't released after deletion"
+
+       # create 1st component 1-10M
+       $LFS setstripe -E 10M -S 1M -c 1 -i 0 $testfile
+       # create 2nd component 10-30M
+       $LFS setstripe --component-add -E 30M -c 1 -i 1 $testfile
+       chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
+
+       # write to the 2nd component
+       $RUNAS $DD of=$testfile count=$limit seek=10 ||
+               quota_error u $TSTUSR \
+                       "write failure, but expect success"
+       # this time maybe cache write,  ignore it's failure
+       $RUNAS $DD of=$testfile count=$((2*limit)) seek=10 || true
+       cancel_lru_locks osc
+       sync; sync_all_data || true
+       # write over limit in qpool2(2nd component 10-30M)
+       $RUNAS $DD of=$testfile count=1 seek=$((10 + 2*limit)) &&
+               quota_error u $TSTUSR "user write success, but expect EDQUOT"
+       # 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 testfile="$DIR/$tdir/$tfile-0"
+       local qpool="qpool1"
+       local qpool2="qpool2"
+
+       [ "$ost1_FSTYPE" == zfs ] &&
+               skip "ZFS grants some block space together with inode"
+       [[ $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"
+
+       # test for user
+       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 $qpool || error "pool_add failed"
+       pool_add_targets $qpool 0 1 ||
+               error "pool_add_targets failed"
+
+       $LFS setquota -u $TSTUSR -B ${limit1}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"
+
+       # make sure the system is clean
+       local used=$(getquota -u $TSTUSR global curspace)
+
+       echo "used $used"
+       [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
+
+       # First component is on OST0, 2nd on OST1
+       $LFS setstripe -E 128M -i 0 -z 64M -E -1 -i 1 -z 64M $testfile
+       chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
+
+       # fill the 1st component on OST0
+       $RUNAS $DD of=$testfile count=128 ||
+               quota_error u $TSTUSR "write failed"
+       # write to the 2nd cmpnt on OST1
+       $RUNAS $DD of=$testfile count=$((limit2/2)) seek=128 ||
+               quota_error u $TSTUSR "write failed"
+       # this time maybe cache write,  ignore it's failure
+       $RUNAS $DD of=$testfile count=$((limit2/2)) seek=$((128 + limit2/2)) ||
+               true
+       cancel_lru_locks osc
+       sync; sync_all_data || true
+       # 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
+}
+run_test 71b "Check SEL with quota pools"
+
+test_72()
+{
+       local limit=10  # 10M
+       local global_limit=50  # 50M
+       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"
+
+       # test for user
+       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 $qpool || error "pool_add failed"
+       pool_add_targets $qpool 1 1 || error "pool_add_targets failed"
+
+       $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR ||
+               error "set user quota failed"
+
+       # make sure the system is clean
+       local used=$(getquota -u $TSTUSR global curspace)
+       echo "used $used"
+       [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
+
+       used=$(getquota -u $TSTUSR global bhardlimit $qpool)
+
+       $LFS setstripe $testfile -c 1 -i 1 || error "setstripe $testfile failed"
+       chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
+       test_1_check_write $testfile "user" $limit
+       used=$(getquota -u $TSTUSR global bhardlimit $qpool)
+       echo "used $used"
+       [ $used -ge $limit ] || error "used($used) is less than limit($limit)"
+       # check that lfs quota -uv --pool prints only OST that
+       # 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
+}
+run_test 72 "lfs quota --pool prints only pool's OSTs"
+
 quota_fini()
 {
        do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=-quota"