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) ] &&
+ skip "Needs MDS version $VERSION_WITH_QP or later."
+}
require_dsh_mds || exit 0
require_dsh_ost || exit 0
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):"
# 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"
*) 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 "*"
wait_grace_time() {
local qtype=$1
local flavour=$2
- local extrasleep=${3:-5}
+ local pool=${3:-}
+ local extrasleep=${4:-5}
local qarg
+ local parg
case $qtype in
u|g) qarg=$TSTUSR ;;
*) error "get_grace_time: Invalid quota type: $qtype"
esac
+ if [ $pool ]; then
+ parg="--pool "$pool
+ echo "Quota info for $pool:"
+ $LFS quota -$qtype $qarg $parg $DIR
+ fi
+
case $flavour in
block)
- time=$(lfs quota -$qtype $qarg $DIR|
+ time=$(lfs quota -$qtype $qarg $parg $DIR|
awk 'NR == 3{ print $5 }'| sed 's/s$//')
;;
file)
;;
esac
+ # 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"
}
cleanup_quota_test() {
- trap 0
echo "Delete files..."
rm -rf $DIR/$tdir
echo "Wait for unlink objects finished..."
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
}
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
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
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 1 "Block hard limit (normal use and out of quota)"
+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 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"
run_test 2 "File hard limit (normal use and out of quota)"
test_block_soft() {
- local TESTFILE=$1
- local GRACE=$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
$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
- wait_grace_time $qtype "block"
+ wait_grace_time $qtype "block" $pool
$SHOW_QUOTA_USER
$SHOW_QUOTA_GROUP
$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
$SHOW_QUOTA_INFO_PROJID
echo "Unlink file to stop timer"
- rm -f $TESTFILE
+ rm -f $testfile
wait_delete_completed
sync_all_data || true
$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 GRACE=20 # 20s
+test_3a() {
+ local grace=20 # 20s
if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
- GRACE=60
+ grace=60
fi
- local TESTFILE=$DIR/$tdir/$tfile-0
+ local testfile=$DIR/$tdir/$tfile-0
# get minimum soft qunit size
- local LIMIT=$(( $(do_facet $SINGLEMDS $LCTL get_param -n \
+ 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 \
+ $MAX_IQ_TIME $DIR || error "set group grace time failed"
+ $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"
+
+ if is_project_quota_supported; then
+ 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."
+
+ $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 \
+ $DIR || error "set project quota failed"
+
+ 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 ||
+ error "restore 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 -g --block-grace $MAX_DQ_TIME --inode-grace \
+ $MAX_IQ_TIME $DIR || error "restore group grace time failed"
+}
+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."
- $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 ||
- error "set group quota failed"
+ pool_add $qpool || error "pool_add failed"
+ pool_add_targets $qpool 0 1 ||
+ error "pool_add_targets failed"
- test_block_soft $TESTFILE $GRACE $LIMIT "g"
+ pool_add $qpool2 || error "pool_add failed"
+ pool_add_targets $qpool2 0 1 ||
+ error "pool_add_targets failed"
- if is_project_quota_supported; then
- 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."
- $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 \
- $DIR || error "set project quota 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"
- 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 ||
- error "restore project grace time failed"
- fi
+ $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 -g --block-grace $MAX_DQ_TIME --inode-grace \
- $MAX_IQ_TIME $DIR || error "restore group 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 3 "Block soft limit (start timer, timer goes off, stop timer)"
+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 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
$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
$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
}
}
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"
}
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"