Whamcloud - gitweb
LU-16529 test: wait quota synced on quota slaves
[fs/lustre-release.git] / lustre / tests / sanity-quota.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 set -e
7
8 ONLY=${ONLY:-"$*"}
9
10 LUSTRE=${LUSTRE:-$(dirname $0)/..}
11 . $LUSTRE/tests/test-framework.sh
12 init_test_env $@
13 init_logging
14
15 ALWAYS_EXCEPT="$SANITY_QUOTA_EXCEPT "
16 # Bug number for skipped test:
17 ALWAYS_EXCEPT+=""
18 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
19
20 # Test duration:                   30 min
21 [ "$SLOW" = "no" ] && EXCEPT_SLOW="61"
22
23 if [ "$mds1_FSTYPE" = zfs ]; then
24         # bug number:                        LU-2887
25         # Test duration:                     21      9 min"
26         [ "$SLOW" = "no" ] && EXCEPT_SLOW+=" 12a     9"
27 fi
28
29 build_test_filter
30
31 DIRECTIO=${DIRECTIO:-$LUSTRE/tests/directio}
32 ORIG_PWD=${PWD}
33 TSTID=${TSTID:-"$(id -u $TSTUSR)"}
34 TSTID2=${TSTID2:-"$(id -u $TSTUSR2)"}
35 TSTPRJID=${TSTPRJID:-1000}
36 BLK_SZ=1024
37 MAX_DQ_TIME=604800
38 MAX_IQ_TIME=604800
39 QTYPE="ugp"
40 VERSION_WITH_QP="2.13.53"
41 mds_supports_qp() {
42         [ $MDS1_VERSION -lt $(version_code $VERSION_WITH_QP) ] &&
43                 skip "Needs MDS version $VERSION_WITH_QP or later."
44 }
45
46 require_dsh_mds || exit 0
47 require_dsh_ost || exit 0
48
49 # Does e2fsprogs support quota feature?
50 if [ "$mds1_FSTYPE" == ldiskfs ] &&
51         do_facet $SINGLEMDS "! $DEBUGFS -c -R supported_features |
52                 grep -q 'quota'"; then
53         skip_env "e2fsprogs doesn't support quota"
54 fi
55
56 QUOTALOG=${TESTSUITELOG:-$TMP/$(basename $0 .sh).log}
57
58 [ "$QUOTALOG" ] && rm -f $QUOTALOG || true
59
60 DIR=${DIR:-$MOUNT}
61 DIR2=${DIR2:-$MOUNT2}
62
63 QUOTA_AUTO_OLD=$QUOTA_AUTO
64 export QUOTA_AUTO=0
65
66 check_and_setup_lustre
67
68 ENABLE_PROJECT_QUOTAS=${ENABLE_PROJECT_QUOTAS:-true}
69 is_project_quota_supported || echo "project quota not supported/enabled"
70
71 SHOW_QUOTA_USER="$LFS quota -v -u $TSTUSR $DIR"
72 SHOW_QUOTA_USERID="$LFS quota -v -u $TSTID $DIR"
73 SHOW_QUOTA_GROUP="$LFS quota -v -g $TSTUSR $DIR"
74 SHOW_QUOTA_GROUPID="$LFS quota -v -g $TSTID $DIR"
75 SHOW_QUOTA_PROJID="eval is_project_quota_supported && $LFS quota -v -p $TSTPRJID $DIR"
76 SHOW_QUOTA_INFO_USER="$LFS quota -t -u $DIR"
77 SHOW_QUOTA_INFO_GROUP="$LFS quota -t -g $DIR"
78 SHOW_QUOTA_INFO_PROJID="eval is_project_quota_supported && $LFS quota -t -p $DIR"
79
80 lustre_fail() {
81         local fail_node=$1
82         local fail_loc=$2
83         local fail_val=${3:-0}
84         local NODES=
85
86         case $fail_node in
87         mds_ost|mdt_ost) NODES="$(comma_list $(mdts_nodes) $(osts_nodes))";;
88         mds|mdt) NODES="$(comma_list $(mdts_nodes))";;
89         ost) NODES="$(comma_list $(osts_nodes))";;
90         esac
91
92         do_nodes $NODES "lctl set_param fail_val=$fail_val fail_loc=$fail_loc"
93 }
94
95 change_project()
96 {
97         echo "lfs project $*"
98         lfs project $* || error "lfs project $* failed"
99 }
100
101 RUNAS="runas -u $TSTID -g $TSTID"
102 RUNAS2="runas -u $TSTID2 -g $TSTID2"
103 DD="dd if=/dev/zero bs=1M"
104
105 FAIL_ON_ERROR=false
106
107 # clear quota limits for a user or a group
108 # usage: resetquota -u username
109 #        resetquota -g groupname
110 #        resetquota -p projid
111
112 resetquota_one() {
113         $LFS setquota "$1" "$2" -b 0 -B 0 -i 0 -I 0 $MOUNT ||
114                 error "clear quota for [type:$1 name:$2] failed"
115 }
116
117 resetquota() {
118         (( "$#" == 2 )) || error "resetquota: wrong number of arguments: '$*'"
119         [[ "$1" == "-u" || "$1" == "-g" || "$1" == "-p" ]] ||
120                 error "resetquota: wrong quota type '$1' passed"
121
122         resetquota_one "$1" "$2"
123
124         # give a chance to slave to release space
125         sleep 1
126 }
127
128 quota_scan() {
129         local local_ugp=$1
130         local local_id=$2
131         local count
132
133         if [ "$local_ugp" == "a" -o "$local_ugp" == "u" ]; then
134                 $LFS quota -v -u $local_id $DIR
135                 count=$($LFS find --user $local_id $DIR | wc -l)
136                 log "Files for user ($local_id), count=$count:"
137                 ($LFS find --user $local_id $DIR | head -n 4 |
138                         xargs stat 2>/dev/null)
139         fi
140
141         if [ "$local_ugp" == "a" -o "$local_ugp" == "g" ]; then
142                 $LFS quota -v -g $local_id $DIR
143                 count=$($LFS find --group $local_id $DIR | wc -l)
144                 log "Files for group ($local_id), count=$count:"
145                 ($LFS find --group $local_id $DIR | head -n 4 |
146                         xargs stat 2>/dev/null)
147         fi
148
149         is_project_quota_supported || return 0
150         if [ "$local_ugp" == "a" -o "$local_ugp" == "p" ]; then
151                 $LFS quota -v -p $TSTPRJID $DIR
152                 count=$($LFS find --projid $TSTPRJID $DIR | wc -l)
153                 log "Files for project ($TSTPRJID), count=$count:"
154                 ($LFS find --projid $TSTPRJID $DIR | head -n 4 |
155                         xargs stat 2>/dev/null)
156         fi
157 }
158
159 quota_error() {
160         quota_scan $1 $2
161         shift 2
162         error "$*"
163 }
164
165 quota_log() {
166         quota_scan $1 $2
167         shift 2
168         log "$*"
169 }
170
171 # get quota for a user or a group
172 # usage: getquota -u|-g|-p <username>|<groupname>|<projid> global|<obd_uuid> \
173 #                 bhardlimit|bsoftlimit|bgrace|ihardlimit|isoftlimit|igrace \
174 #                 <pool_name>
175 getquota() {
176         local spec
177         local uuid
178         local pool_arg
179
180         sync_all_data > /dev/null 2>&1 || true
181
182         [ "$#" != 4 -a "$#" != 5 ] &&
183                 error "getquota: wrong number of arguments: $#"
184         [ "$1" != "-u" -a "$1" != "-g" -a "$1" != "-p" ] &&
185                 error "getquota: wrong u/g/p specifier $1 passed"
186
187         uuid="$3"
188
189         case "$4" in
190                 curspace)   spec=1;;
191                 bsoftlimit) spec=2;;
192                 bhardlimit) spec=3;;
193                 bgrace)     spec=4;;
194                 curinodes)  spec=5;;
195                 isoftlimit) spec=6;;
196                 ihardlimit) spec=7;;
197                 igrace)     spec=8;;
198                 *)          error "unknown quota parameter $4";;
199         esac
200
201         [ ! -z "$5" ] && pool_arg="--pool $5 "
202         [ "$uuid" = "global" ] && uuid=$DIR
203
204         $LFS quota -v "$1" "$2" $pool_arg $DIR |
205                 awk 'BEGIN { num='$spec' } { if ($1 == "'$uuid'") \
206                 { if (NF == 1) { getline } else { num++ } ; print $num;} }' \
207                 | tr -d "*"
208 }
209
210 # set mdt quota type
211 # usage: set_mdt_qtype ugp|u|g|p|none
212 set_mdt_qtype() {
213         local qtype=$1
214         local varsvc
215         local mdts=$(get_facets MDS)
216         local cmd
217         [[ "$qtype" =~ "p" ]] && ! is_project_quota_supported &&
218                 qtype=$(tr -d 'p' <<<$qtype)
219
220         if [[ $PERM_CMD == *"set_param -P"* ]]; then
221                 do_facet mgs $PERM_CMD \
222                         osd-*.$FSNAME-MDT*.quota_slave.enabled=$qtype
223         else
224                 do_facet mgs $PERM_CMD $FSNAME.quota.mdt=$qtype
225         fi
226         # we have to make sure each MDT received config changes
227         for mdt in ${mdts//,/ }; do
228                 varsvc=${mdt}_svc
229                 cmd="$LCTL get_param -n "
230                 cmd=${cmd}osd-$(facet_fstype $mdt).${!varsvc}
231                 cmd=${cmd}.quota_slave.enabled
232
233                 if $(facet_up $mdt); then
234                         wait_update_facet $mdt "$cmd" "$qtype" || return 1
235                 fi
236         done
237         return 0
238 }
239
240 # set ost quota type
241 # usage: set_ost_qtype ugp|u|g|p|none
242 set_ost_qtype() {
243         local qtype=$1
244         local varsvc
245         local osts=$(get_facets OST)
246         local cmd
247         [[ "$qtype" =~ "p" ]] && ! is_project_quota_supported &&
248                 qtype=$(tr -d 'p' <<<$qtype)
249
250         if [[ $PERM_CMD == *"set_param -P"* ]]; then
251                 do_facet mgs $PERM_CMD \
252                         osd-*.$FSNAME-OST*.quota_slave.enabled=$qtype
253         else
254                 do_facet mgs $PERM_CMD $FSNAME.quota.ost=$qtype
255         fi
256         # we have to make sure each OST received config changes
257         for ost in ${osts//,/ }; do
258                 varsvc=${ost}_svc
259                 cmd="$LCTL get_param -n "
260                 cmd=${cmd}osd-$(facet_fstype $ost).${!varsvc}
261                 cmd=${cmd}.quota_slave.enabled
262
263                 if $(facet_up $ost); then
264                         wait_update_facet $ost "$cmd" "$qtype" || return 1
265                 fi
266         done
267         return 0
268 }
269
270 wait_reintegration() {
271         local ntype=$1
272         local qtype=$2
273         local max=$3
274         local result="glb[1],slv[1],reint[0]"
275         local varsvc
276         local cmd
277         local tgts
278
279         if [ $ntype == "mdt" ]; then
280                 tgts=$(get_facets MDS)
281         else
282                 tgts=$(get_facets OST)
283         fi
284
285         for tgt in ${tgts//,/ }; do
286                 varsvc=${tgt}_svc
287                 cmd="$LCTL get_param -n "
288                 cmd=${cmd}osd-$(facet_fstype $tgt).${!varsvc}
289                 cmd=${cmd}.quota_slave.info
290
291                 if $(facet_up $tgt); then
292                         wait_update_facet $tgt "$cmd |
293                                 grep "$qtype" | awk '{ print \\\$3 }'" \
294                                         "$result" $max || return 1
295                 fi
296         done
297         return 0
298 }
299
300 wait_mdt_reint() {
301         local qtype=$1
302         local max=${2:-90}
303
304         if [[ "$qtype" =~ "u" ]]; then
305                 wait_reintegration "mdt" "user" $max || return 1
306         fi
307
308         if [[ "$qtype" =~ "g" ]]; then
309                 wait_reintegration "mdt" "group" $max || return 1
310         fi
311
312         if [[ "$qtype" =~ "p" ]]; then
313                 ! is_project_quota_supported && return 0
314                 wait_reintegration "mdt" "project" $max || return 1
315         fi
316         return 0
317 }
318
319 wait_ost_reint() {
320         local qtype=$1
321         local max=${2:-90}
322
323         if [[ "$qtype" =~ "u" ]]; then
324                 wait_reintegration "ost" "user" $max || return 1
325         fi
326
327         if [[ "$qtype" =~ "g" ]]; then
328                 wait_reintegration "ost" "group" $max || return 1
329         fi
330
331         if [[ "$qtype" =~ "p" ]]; then
332                 ! is_project_quota_supported && return 0
333                 wait_reintegration "ost" "project" $max || return 1
334         fi
335         return 0
336 }
337
338 wait_grace_time() {
339         local qtype=$1
340         local flavour=$2
341         local pool=${3:-}
342         local extrasleep=${4:-5}
343         local qarg
344         local parg
345
346         case $qtype in
347                 u|g) qarg=$TSTUSR ;;
348                 p) qarg=$TSTPRJID ;;
349                 *) error "get_grace_time: Invalid quota type: $qtype"
350         esac
351
352         if [ $pool ]; then
353                 parg="--pool "$pool
354                 echo "Quota info for $pool:"
355                 $LFS quota -$qtype $qarg $parg $DIR
356         fi
357
358         case $flavour in
359                 block)
360                         time=$(lfs quota -$qtype $qarg $parg $DIR|
361                                    awk 'NR == 3{ print $5 }')
362                         ;;
363                 file)
364                         time=$(lfs quota -$qtype $qarg $DIR|
365                                    awk 'NR == 3{ print $9 }')
366                         ;;
367                 *)
368                         error "Unknown quota type: $flavour"
369                         ;;
370         esac
371
372         local sleep_seconds=0
373         local orig_time=$time
374
375         echo "Grace time is $time"
376         # from lfs.c:__sec2str()
377         # const char spec[] = "smhdw";
378         # {1, 60, 60*60, 24*60*60, 7*24*60*60};
379         [[ $time == *w* ]] && w_time=${time%w*} &&
380                 let sleep_seconds+=$((w_time*7*24*60*60));
381         time=${time#*w}
382         [[ $time == *d* ]] && d_time=${time%d*} &&
383                 let sleep_seconds+=$((d_time*24*60*60));
384         time=${time#*d}
385         [[ $time == *h* ]] && h_time=${time%h*} &&
386                 let sleep_seconds+=$((h_time*60*60));
387         time=${time#*h}
388         [[ $time == *m* ]] && m_time=${time%m*} &&
389                 let sleep_seconds+=$((m_time*60));
390         time=${time#*m}
391         [[ $time == *s* ]] && s_time=${time%s*} &&
392                 let sleep_seconds+=$s_time
393
394         echo "Sleep through grace ..."
395         [ "$orig_time" == "-" ] &&
396             error "Grace timeout was not set or quota not exceeded"
397         if [ "$orig_time" == "expired" -o "$orig_time" == "none" ]; then
398             echo "...Grace timeout already expired"
399         else
400                 let sleep_seconds+=$extrasleep
401                 echo "...sleep $sleep_seconds seconds"
402                 sleep $sleep_seconds
403         fi
404 }
405
406 setup_quota_test() {
407         wait_delete_completed
408         echo "Creating test directory"
409         mkdir_on_mdt0 $DIR/$tdir || return 1
410         chmod 0777 $DIR/$tdir || return 2
411         # always clear fail_loc in case of fail_loc isn't cleared
412         # properly when previous test failed
413         lustre_fail mds_ost 0
414         stack_trap cleanup_quota_test EXIT
415 }
416
417 cleanup_quota_test() {
418         echo "Delete files..."
419         rm -rf $DIR/$tdir
420         [ -d $DIR/${tdir}_dom ] && rm -rf $DIR/${tdir}_dom
421         echo "Wait for unlink objects finished..."
422         wait_delete_completed
423         sync_all_data || true
424         reset_quota_settings
425 }
426
427 quota_show_check() {
428         local bf=$1
429         local ugp=$2
430         local qid=$3
431         local usage
432
433         $LFS quota -v -$ugp $qid $DIR
434
435         if [ "$bf" == "a" -o "$bf" == "b" ]; then
436                 usage=$(getquota -$ugp $qid global curspace)
437                 if [ -z $usage ]; then
438                         quota_error $ugp $qid \
439                                 "Query block quota failed ($ugp:$qid)."
440                 else
441                         [ $usage -ne 0 ] && quota_log $ugp $qid \
442                                 "Block quota isn't 0 ($ugp:$qid:$usage)."
443                 fi
444         fi
445
446         if [ "$bf" == "a" -o "$bf" == "f" ]; then
447                 usage=$(getquota -$ugp $qid global curinodes)
448                 if [ -z $usage ]; then
449                         quota_error $ugp $qid \
450                                 "Query file quota failed ($ugp:$qid)."
451                 else
452                         [ $usage -ne 0 ] && quota_log $ugp $qid \
453                                 "File quota isn't 0 ($ugp:$qid:$usage)."
454                 fi
455         fi
456 }
457
458 project_quota_enabled () {
459         local rc=0
460         local zfeat="feature@project_quota"
461
462         for facet in $(seq -f mds%g $MDSCOUNT) $(seq -f ost%g $OSTCOUNT); do
463                 local facet_fstype=${facet:0:3}1_FSTYPE
464                 local devname
465
466                 if [ "${!facet_fstype}" = "zfs" ]; then
467                         devname=$(zpool_name ${facet})
468                         do_facet ${facet} $ZPOOL get -H "$zfeat" $devname |
469                                 grep -wq active || rc=1
470                 else
471                         [ ${facet:0:3} == "mds" ] &&
472                                 devname=$(mdsdevname ${facet:3}) ||
473                                 devname=$(ostdevname ${facet:3})
474                         do_facet ${facet} $DEBUGFS -R features $devname |
475                                 grep -q project || rc=1
476                 fi
477         done
478         [ $rc -eq 0 ] && PQ_CLEANUP=false || PQ_CLEANUP=true
479         return $rc
480 }
481
482 project_quota_enabled || enable_project_quota
483
484 reset_quota_settings() {
485         resetquota_one -u $TSTUSR
486         [[ $(id -u $TSTUSR) == $TSTID ]] || resetquota_one -u $TSTID
487         resetquota_one -g $TSTUSR
488         [[ $(id -g $TSTUSR) == $TSTID ]] || resetquota_one -g $TSTID
489         resetquota_one -u $TSTUSR2
490         [[ $(id -u $TSTUSR2) == $TSTID2 ]] || resetquota_one -u $TSTID2
491         resetquota_one -g $TSTUSR2
492         [[ $(id -g $TSTUSR2) == $TSTID2 ]] || resetquota_one -g $TSTID2
493         is_project_quota_supported && resetquota_one -p $TSTPRJID
494
495         sleep 1
496 }
497
498 get_quota_on_qsd() {
499         local facet
500         local spec
501         local qid
502         local qtype
503         local output
504
505         facet=$1
506         case "$2" in
507                 usr) qtype="limit_user";;
508                 grp) qtype="limit_group";;
509                 *)         error "unknown quota parameter $2";;
510         esac
511
512         qid=$3
513         case "$4" in
514                 hardlimit) spec=4;;
515                 softlimit) spec=6;;
516                 *)         error "unknown quota parameter $4";;
517         esac
518
519         do_facet $facet $LCTL get_param osd-*.*-OST0000.quota_slave.$qtype |
520                 awk '($3 == '$qid') {getline; print $'$spec'; exit;}' | tr -d ,
521 }
522
523 wait_quota_setting_synced() {
524         local value
525         local qtype=$1
526         local qid=$2
527         local limit_type=$3
528         local limit_val=$4
529         local interval=0
530
531         value=$(get_quota_on_qsd ost1 $qtype $qid $limit_type)
532         while [[ $value != $limit_val ]]; do
533                 (( interval != 0 )) ||
534                         do_facet ost1 $LCTL set_param \
535                                 osd-*.*-OST0000.quota_slave.force_reint=1
536
537                 (( interval <= 20 )) ||
538                         error "quota ($value) don't update on QSD, $limit_val"
539
540                 interval=$((interval + 1))
541                 sleep 1
542
543                 value=$(get_quota_on_qsd ost1 $qtype $qid $limit_type)
544         done
545 }
546
547 # enable quota debug
548 quota_init() {
549         do_nodes $(comma_list $(nodes_list)) \
550                 "$LCTL set_param -n debug=+quota+trace"
551 }
552 quota_init
553 reset_quota_settings
554
555 check_runas_id_ret $TSTUSR $TSTUSR $RUNAS ||
556         error "Please create user $TSTUSR($TSTID) and group $TSTUSR($TSTID)"
557 check_runas_id_ret $TSTUSR2 $TSTUSR2 $RUNAS2 ||
558         error "Please create user $TSTUSR2($TSTID2) and group $TSTUSR2($TSTID2)"
559
560 test_quota_performance() {
561         local TESTFILE="$DIR/$tdir/$tfile-0"
562         local size=$1 # in MB
563         local stime=$(date +%s)
564         $RUNAS $DD of=$TESTFILE count=$size conv=fsync ||
565                 quota_error u $TSTUSR "write failure"
566         local etime=$(date +%s)
567         delta=$((etime - stime))
568         if [ $delta -gt 0 ]; then
569                 rate=$((size * 1024 / delta))
570                 if [ "$mds1_FSTYPE" = zfs ]; then
571                         # LU-2872 - see LU-2887 for fix
572                         [ $rate -gt 64 ] ||
573                                 error "SLOW IO for $TSTUSR (user): $rate KB/sec"
574                 else
575                         [ $rate -gt 1024 ] ||
576                                 error "SLOW IO for $TSTUSR (user): $rate KB/sec"
577                 fi
578         fi
579         rm -f $TESTFILE
580 }
581
582 # test basic quota performance b=21696
583 test_0() {
584         local MB=100 # MB
585         [ "$SLOW" = "no" ] && MB=10
586
587         local free_space=$(lfs_df | grep "summary" | awk '{print $4}')
588         [ $free_space -le $((MB * 1024)) ] &&
589                 skip "not enough space ${free_space} KB, " \
590                         "required $((MB * 1024)) KB"
591         setup_quota_test || error "setup quota failed with $?"
592
593         set_ost_qtype "none" || error "disable ost quota failed"
594         test_quota_performance $MB
595
596         set_ost_qtype $QTYPE || error "enable ost quota failed"
597         $LFS setquota -u $TSTUSR -b 0 -B 10G -i 0 -I 0 $DIR ||
598                 error "set quota failed"
599         test_quota_performance $MB
600 }
601 run_test 0 "Test basic quota performance"
602
603 # usage: test_1_check_write tfile user|group|project
604 test_1_check_write() {
605         local testfile="$1"
606         local qtype="$2"
607         local limit=$3
608         local short_qtype=${qtype:0:1}
609
610         log "Write..."
611         $RUNAS $DD of=$testfile count=$((limit/2)) ||
612                 quota_error $short_qtype $TSTUSR \
613                         "$qtype write failure, but expect success"
614         log "Write out of block quota ..."
615         # this time maybe cache write, ignore it's failure
616         $RUNAS $DD of=$testfile count=$((limit/2)) seek=$((limit/2)) || true
617         # flush cache, ensure noquota flag is set on client
618         cancel_lru_locks osc
619         sync; sync_all_data || true
620         # sync means client wrote all it's cache, but id doesn't
621         # guarantee that slave received new edquot through glimpse.
622         # so wait a little to be sure slave got it.
623         sleep 5
624         $RUNAS $DD of=$testfile count=1 seek=$limit &&
625                 quota_error $short_qtype $TSTUSR \
626                         "user write success, but expect EDQUOT"
627         return 0
628 }
629
630 check_write_fallocate() {
631         local testfile="$1"
632         local qtype="$2"
633         local limit=$3
634         local short_qtype=${qtype:0:1}
635
636         count=$((limit/2))
637         log "Write ${count}MiB Using Fallocate"
638         $RUNAS fallocate -l${count}MiB $testfile ||
639                 quota_error $short_qtype $TSTUSR "Write ${count}MiB fail"
640
641         cancel_lru_locks osc
642         sync; sync_all_data || true
643         sleep 2
644
645         count=$((limit + 1))
646         log "Write ${count}MiB Using Fallocate"
647         $RUNAS fallocate -l${count}MiB $testfile &&
648                 quota_error $short_qtype $TSTUSR \
649                 "Write success, expect EDQUOT" || true
650 }
651
652 # test block hardlimit
653 test_1a() {
654         local limit=10 # MB
655         local testfile="$DIR/$tdir/$tfile-0"
656
657         setup_quota_test || error "setup quota failed with $?"
658
659         # enable ost quota
660         set_ost_qtype $QTYPE || error "enable ost quota failed"
661
662         # test for user
663         log "User quota (block hardlimit:$limit MB)"
664         $LFS setquota -u $TSTUSR -b 0 -B ${limit}M -i 0 -I 0 $DIR ||
665                 error "set user quota failed"
666
667         # make sure the system is clean
668         local used=$(getquota -u $TSTUSR global curspace)
669         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
670
671         $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
672         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
673
674         test_1_check_write $testfile "user" $limit
675
676         rm -f $testfile
677         wait_delete_completed || error "wait_delete_completed failed"
678         sync_all_data || true
679         used=$(getquota -u $TSTUSR global curspace)
680         [ $used -ne 0 ] && quota_error u $TSTUSR \
681                 "user quota isn't released after deletion"
682         resetquota -u $TSTUSR
683
684         # test for group
685         log "--------------------------------------"
686         log "Group quota (block hardlimit:$limit MB)"
687         $LFS setquota -g $TSTUSR -b 0 -B ${limit}M -i 0 -I 0 $DIR ||
688                 error "set group quota failed"
689
690         testfile="$DIR/$tdir/$tfile-1"
691         # make sure the system is clean
692         used=$(getquota -g $TSTUSR global curspace)
693         [ $used -ne 0 ] && error "Used space ($used) for group $TSTUSR isn't 0"
694
695         $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
696         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
697
698         test_1_check_write $testfile "group" $limit
699         rm -f $testfile
700         wait_delete_completed || error "wait_delete_completed failed"
701         sync_all_data || true
702         used=$(getquota -g $TSTUSR global curspace)
703         [ $used -ne 0 ] && quota_error g $TSTUSR \
704                                 "Group quota isn't released after deletion"
705         resetquota -g $TSTUSR
706
707         if ! is_project_quota_supported; then
708                 echo "Project quota is not supported"
709                 return 0
710         fi
711
712         testfile="$DIR/$tdir/$tfile-2"
713         # make sure the system is clean
714         used=$(getquota -p $TSTPRJID global curspace)
715         [ $used -ne 0 ] &&
716                 error "used space($used) for project $TSTPRJID isn't 0"
717
718         # test for Project
719         log "--------------------------------------"
720         log "Project quota (block hardlimit:$limit mb)"
721         $LFS setquota -p $TSTPRJID -b 0 -B ${limit}M -i 0 -I 0 $DIR ||
722                 error "set project quota failed"
723
724         $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
725         chown $TSTUSR:$TSTUSR $testfile || error "chown $testfile failed"
726         change_project -p $TSTPRJID $testfile
727
728         test_1_check_write $testfile "project" $limit
729
730         # cleanup
731         cleanup_quota_test
732
733         used=$(getquota -p $TSTPRJID global curspace)
734         [ $used -ne 0 ] && quota_error p $TSTPRJID \
735                 "project quota isn't released after deletion"
736
737         resetquota -p $TSTPRJID
738 }
739 run_test 1a "Block hard limit (normal use and out of quota)"
740
741 test_1b() {
742         local limit=10 # MB
743         local global_limit=20 # MB
744         local testfile="$DIR/$tdir/$tfile-0"
745         local qpool="qpool1"
746
747         mds_supports_qp
748         setup_quota_test || error "setup quota failed with $?"
749
750         # enable ost quota
751         set_ost_qtype $QTYPE || error "enable ost quota failed"
752
753         # test for user
754         log "User quota (block hardlimit:$global_limit MB)"
755         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
756                 error "set user quota failed"
757
758         pool_add $qpool || error "pool_add failed"
759         pool_add_targets $qpool 0 $(($OSTCOUNT - 1)) ||
760                 error "pool_add_targets failed"
761
762         # check qmt_pool_add dmesg error
763         local msg_rgx="QMT0000: can't add to $FSNAME-OST0000.*pool.*$qpool"
764         local dmesg_err
765         dmesg_err=$(do_facet mds1 dmesg | grep "$msg_rgx" | tail -1)
766         [[ -z "$dmesg_err" ]] || error "found qmt_pool_add error: $dmesg_err"
767
768         $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR ||
769                 error "set user quota failed"
770
771         # make sure the system is clean
772         local used=$(getquota -u $TSTUSR global curspace)
773         echo "used $used"
774         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
775
776         used=$(getquota -u $TSTUSR global bhardlimit $qpool)
777
778         $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
779         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
780
781         test_1_check_write $testfile "user" $limit
782
783         rm -f $testfile
784         wait_delete_completed || error "wait_delete_completed failed"
785         sync_all_data || true
786         used=$(getquota -u $TSTUSR global curspace $qpool)
787         [ $used -ne 0 ] && quota_error u $TSTUSR \
788                 "user quota isn't released after deletion"
789         resetquota -u $TSTUSR
790
791         # test for group
792         log "--------------------------------------"
793         log "Group quota (block hardlimit:$global_limit MB)"
794         $LFS setquota -g $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
795                 error "set group quota failed"
796
797         $LFS setquota -g $TSTUSR -b 0 -B ${limit}M --pool $qpool $DIR ||
798                 error "set group quota failed"
799
800         testfile="$DIR/$tdir/$tfile-1"
801         # make sure the system is clean
802         used=$(getquota -g $TSTUSR global curspace $qpool)
803         [ $used -ne 0 ] && error "Used space ($used) for group $TSTUSR isn't 0"
804
805         $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
806         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
807
808         test_1_check_write $testfile "group" $limit
809
810         rm -f $testfile
811         wait_delete_completed || error "wait_delete_completed failed"
812         sync_all_data || true
813         used=$(getquota -g $TSTUSR global curspace $qpool)
814         [ $used -ne 0 ] && quota_error g $TSTUSR \
815                                 "Group quota isn't released after deletion"
816         resetquota -g $TSTUSR
817
818         if ! is_project_quota_supported; then
819                 echo "Project quota is not supported"
820                 return 0
821         fi
822
823         testfile="$DIR/$tdir/$tfile-2"
824         # make sure the system is clean
825         used=$(getquota -p $TSTPRJID global curspace $qpool)
826         [ $used -ne 0 ] &&
827                 error "used space($used) for project $TSTPRJID isn't 0"
828
829         # test for Project
830         log "--------------------------------------"
831         log "Project quota (block hardlimit:$global_limit mb)"
832         $LFS setquota -p $TSTPRJID -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
833                 error "set project quota failed"
834
835         $LFS setquota -p $TSTPRJID -b 0 -B ${limit}M --pool $qpool $DIR ||
836                 error "set project quota failed"
837
838
839         $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
840         chown $TSTUSR:$TSTUSR $testfile || error "chown $testfile failed"
841         change_project -p $TSTPRJID $testfile
842
843         test_1_check_write $testfile "project" $limit
844
845         # cleanup
846         cleanup_quota_test
847
848         used=$(getquota -p $TSTPRJID global curspace)
849         [ $used -eq 0 ] || quota_error p $TSTPRJID \
850                 "project quota isn't released after deletion"
851 }
852 run_test 1b "Quota pools: Block hard limit (normal use and out of quota)"
853
854 test_1c() {
855         local global_limit=20 # MB
856         local testfile="$DIR/$tdir/$tfile-0"
857         local qpool1="qpool1"
858         local qpool2="qpool2"
859
860         mds_supports_qp
861         setup_quota_test || error "setup quota failed with $?"
862
863         # enable ost quota
864         set_ost_qtype $QTYPE || error "enable ost quota failed"
865
866         # test for user
867         log "User quota (block hardlimit:$global_limit MB)"
868         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
869                 error "set user quota failed"
870
871         pool_add $qpool1 || error "pool_add failed"
872         pool_add_targets $qpool1 0 $(($OSTCOUNT - 1)) ||
873                 error "pool_add_targets failed"
874
875         pool_add $qpool2 || error "pool_add failed"
876         pool_add_targets $qpool2 0 $(($OSTCOUNT - 1)) ||
877                 error "pool_add_targets failed"
878
879         # create pools without hard limit
880         # initially such case raised several bugs
881         $LFS setquota -u $TSTUSR -B 0M --pool $qpool1 $DIR ||
882                 error "set user quota failed"
883
884         $LFS setquota -u $TSTUSR -B 0M --pool $qpool2 $DIR ||
885                 error "set user quota failed"
886
887         # make sure the system is clean
888         local used=$(getquota -u $TSTUSR global curspace)
889         echo "used $used"
890         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
891
892         used=$(getquota -u $TSTUSR global bhardlimit $qpool)
893
894         test_1_check_write $testfile "user" $global_limit
895
896         used=$(getquota -u $TSTUSR global curspace $qpool1)
897         echo "qpool1 used $used"
898         used=$(getquota -u $TSTUSR global curspace $qpool2)
899         echo "qpool2 used $used"
900
901         rm -f $testfile
902         wait_delete_completed || error "wait_delete_completed failed"
903         sync_all_data || true
904
905         used=$(getquota -u $TSTUSR global curspace $qpool1)
906         [ $used -eq 0 ] || quota_error u $TSTUSR \
907                 "user quota isn't released after deletion"
908 }
909 run_test 1c "Quota pools: check 3 pools with hardlimit only for global"
910
911 test_1d() {
912         local limit1=10 # MB
913         local limit2=12 # MB
914         local global_limit=20 # MB
915         local testfile="$DIR/$tdir/$tfile-0"
916         local qpool1="qpool1"
917         local qpool2="qpool2"
918
919         mds_supports_qp
920         setup_quota_test || error "setup quota failed with $?"
921
922         # enable ost quota
923         set_ost_qtype $QTYPE || error "enable ost quota failed"
924
925         # test for user
926         log "User quota (block hardlimit:$global_limit MB)"
927         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
928                 error "set user quota failed"
929
930         pool_add $qpool1 || error "pool_add failed"
931         pool_add_targets $qpool1 0 $(($OSTCOUNT - 1)) ||
932                 error "pool_add_targets failed"
933
934         pool_add $qpool2 || error "pool_add failed"
935         pool_add_targets $qpool2 0 $(($OSTCOUNT - 1)) ||
936                 error "pool_add_targets failed"
937
938         $LFS setquota -u $TSTUSR -B ${limit1}M --pool $qpool1 $DIR ||
939                 error "set user quota failed"
940
941         $LFS setquota -u $TSTUSR -B ${limit2}M --pool $qpool2 $DIR ||
942         error "set user quota failed"
943
944         # make sure the system is clean
945         local used=$(getquota -u $TSTUSR global curspace)
946         echo "used $used"
947         [ $used -ne 0 ] && error "used space($used) for user $TSTUSR isn't 0."
948
949         used=$(getquota -u $TSTUSR global bhardlimit $qpool)
950
951         test_1_check_write $testfile "user" $limit1
952
953         used=$(getquota -u $TSTUSR global curspace $qpool1)
954         echo "qpool1 used $used"
955         used=$(getquota -u $TSTUSR global curspace $qpool2)
956         echo "qpool2 used $used"
957
958         rm -f $testfile
959         wait_delete_completed || error "wait_delete_completed failed"
960         sync_all_data || true
961
962         used=$(getquota -u $TSTUSR global curspace $qpool1)
963         [ $used -eq 0 ] || quota_error u $TSTUSR \
964                 "user quota isn't released after deletion"
965 }
966 run_test 1d "Quota pools: check block hardlimit on different pools"
967
968 test_1e() {
969         local limit1=10 # MB
970         local global_limit=53000000 # MB
971         local testfile="$DIR/$tdir/$tfile-0"
972         local testfile2="$DIR/$tdir/$tfile-1"
973         local qpool1="qpool1"
974
975         mds_supports_qp
976         setup_quota_test || error "setup quota failed with $?"
977
978         # enable ost quota
979         set_ost_qtype $QTYPE || error "enable ost quota failed"
980
981         # global_limit is much greater than limit1 to get
982         # different qunit's on osts. Since 1st qunit shrinking
983         # on OST1(that belongs to qpool1), this qunit should
984         # be sent to OST1.
985         log "User quota (block hardlimit:$global_limit MB)"
986         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
987                 error "set user quota failed"
988
989         pool_add $qpool1 || error "pool_add failed"
990         pool_add_targets $qpool1 1 1 ||
991                 error "pool_add_targets failed"
992
993         $LFS setquota -u $TSTUSR -B ${limit1}M --pool $qpool1 $DIR ||
994                 error "set user quota failed"
995
996         # make sure the system is clean
997         local used=$(getquota -u $TSTUSR global curspace)
998         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
999
1000         $LFS setstripe $testfile -c 1 -i 1 || error "setstripe $testfile failed"
1001         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
1002
1003         test_1_check_write $testfile "user" $limit1
1004
1005         $LFS setstripe $testfile2 -c 1 -i 0 ||
1006                 error "setstripe $testfile2 failed"
1007         chown $TSTUSR.$TSTUSR $testfile2 || error "chown $testfile2 failed"
1008         # Now write to file with a stripe on OST0, that doesn't belong to qpool1
1009         log "Write..."
1010         $RUNAS $DD of=$testfile2 count=20 ||
1011                 quota_error u $TSTUSR \
1012                         "$qtype write failure, but expect success"
1013
1014         rm -f $testfile
1015         rm -f $testfile2
1016         wait_delete_completed || error "wait_delete_completed failed"
1017         sync_all_data || true
1018
1019         used=$(getquota -u $TSTUSR global curspace $qpool1)
1020         [ $used -eq 0 ] || quota_error u $TSTUSR \
1021                 "user quota isn't released after deletion"
1022 }
1023 run_test 1e "Quota pools: global pool high block limit vs quota pool with small"
1024
1025 test_1f() {
1026         local global_limit=200 # MB
1027         local limit1=10 # MB
1028         local TESTDIR="$DIR/$tdir/"
1029         local testfile="$TESTDIR/$tfile-0"
1030         local qpool1="qpool1"
1031
1032         mds_supports_qp
1033         setup_quota_test || error "setup quota failed with $?"
1034
1035         # enable ost quota
1036         set_ost_qtype $QTYPE || error "enable ost quota failed"
1037
1038         log "User quota (block hardlimit:$global_limit MB)"
1039         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
1040                 error "set user quota failed"
1041
1042         pool_add $qpool1 || error "pool_add failed"
1043         pool_add_targets $qpool1 0 0 ||
1044                 error "pool_add_targets failed"
1045
1046         $LFS setquota -u $TSTUSR -B ${limit1}M --pool $qpool1 $DIR ||
1047                 error "set user quota failed"
1048
1049         # make sure the system is clean
1050         local used=$(getquota -u $TSTUSR global curspace)
1051         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
1052
1053         $LFS setstripe $TESTDIR -c 1 -i 0 || error "setstripe $TESTDIR failed"
1054
1055         test_1_check_write $testfile "user" $limit1
1056
1057         pool_remove_target $qpool1 0
1058         rm -f $testfile
1059         wait_delete_completed || error "wait_delete_completed failed"
1060         sync_all_data || true
1061
1062         pool_add_targets $qpool1 0 0 || error "pool_add_targets failed"
1063         # qunit for appropriate element in lgd array should be set
1064         # correctly(4096). Earlier it was not changed continuing to be 1024.
1065         # This caused write to hung when it hit limit1 - qunit shrinking to 1024
1066         # for qpool1 lqe didn't cause changing qunit for OST0 in gld array
1067         # as it already was 1024. As flag "need_update" for this qunit was
1068         # not set, new qunit wasn't sent to OST0. Thus revoke was not set
1069         # for "qpool1" lqe and it couldn't set EDQUOT despite granted
1070         # became > 10M. QMT returned EINPROGRESS in a loop.
1071         # Check that it doesn't hung anymore.
1072         test_1_check_write $testfile "user" $limit1
1073 }
1074 run_test 1f "Quota pools: correct qunit after removing/adding OST"
1075
1076 test_1g() {
1077         local limit=20 # MB
1078         local global_limit=40 # MB
1079         local testfile="$DIR/$tdir/$tfile-0"
1080         local qpool="qpool1"
1081         local mdmb_param="osc.*.max_dirty_mb"
1082         local max_dirty_mb=$($LCTL get_param -n $mdmb_param | head -1)
1083
1084         mds_supports_qp
1085         setup_quota_test || error "setup quota failed with $?"
1086         $LCTL set_param $mdmb_param=1
1087         stack_trap "$LCTL set_param $mdmb_param=$max_dirty_mb" EXIT
1088
1089         # enable ost quota
1090         set_ost_qtype $QTYPE || error "enable ost quota failed"
1091
1092         # test for user
1093         log "User quota (block hardlimit:$global_limit MB)"
1094         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
1095                 error "set user quota failed"
1096
1097         pool_add $qpool || error "pool_add failed"
1098         pool_add_targets $qpool 0 $(($OSTCOUNT - 1)) ||
1099                 error "pool_add_targets failed"
1100
1101         $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR ||
1102                 error "set user quota failed"
1103
1104         # make sure the system is clean
1105         local used=$(getquota -u $TSTUSR global curspace)
1106         echo "used $used"
1107         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
1108
1109         $LFS setstripe $testfile -C 200 || error "setstripe $testfile failed"
1110         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
1111
1112         log "Write..."
1113         $RUNAS $DD of=$testfile count=$((limit/2)) ||
1114                 quota_error u $TSTUSR \
1115                         "$qtype write failure, but expect success"
1116         log "Write out of block quota ..."
1117         # this time maybe cache write,  ignore it's failure
1118         $RUNAS $DD of=$testfile count=$((limit/2)) seek=$((limit/2)) || true
1119         # flush cache, ensure noquota flag is set on client
1120         cancel_lru_locks osc
1121         sync; sync_all_data || true
1122         sleep 5
1123         $RUNAS $DD of=$testfile count=$OSTCOUNT seek=$limit &&
1124                 quota_error u $TSTUSR \
1125                         "user write success, but expect EDQUOT"
1126
1127         rm -f $testfile
1128         wait_delete_completed || error "wait_delete_completed failed"
1129         sync_all_data || true
1130
1131         used=$(getquota -u $TSTUSR global curspace $qpool)
1132         [ $used -ne 0 ] && quota_error u $TSTUSR \
1133                 "user quota isn't released after deletion"
1134         return 0
1135 }
1136 run_test 1g "Quota pools: Block hard limit with wide striping"
1137
1138 test_1h() {
1139         local limit=10 # MB
1140         local testfile="$DIR/$tdir/$tfile-0"
1141
1142         check_set_fallocate_or_skip
1143
1144         setup_quota_test || error "setup quota failed with $?"
1145
1146         # enable ost quota
1147         set_ost_qtype $QTYPE || error "enable ost quota failed"
1148
1149         # test for user
1150         log "User quota (block hardlimit:$limit MB)"
1151         $LFS setquota -u $TSTUSR -b 0 -B ${limit}M -i 0 -I 0 $DIR ||
1152                 error "set user quota failed"
1153
1154         # make sure the system is clean
1155         local used=$(getquota -u $TSTUSR global curspace)
1156         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
1157
1158         $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
1159         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
1160
1161         check_write_fallocate $testfile "user" $limit
1162
1163         rm -f $testfile
1164         wait_delete_completed || error "wait_delete_completed failed"
1165         sync_all_data || true
1166         used=$(getquota -u $TSTUSR global curspace)
1167         [ $used -eq 0 ] || quota_error u $TSTUSR \
1168                 "user quota isn't released after deletion"
1169 }
1170 run_test 1h "Block hard limit test using fallocate"
1171
1172 test_1i() {
1173         local global_limit=200  # 200M
1174         local limit1=10  # 10M
1175         local TESTDIR="$DIR/$tdir/"
1176         local testfile="$TESTDIR/$tfile-0"
1177         local testfile1="$TESTDIR/$tfile-1"
1178         local testfile2="$TESTDIR/$tfile-2"
1179         local qpool1="qpool1"
1180
1181         mds_supports_qp
1182         setup_quota_test || error "setup quota failed with $?"
1183
1184         # enable ost quota
1185         set_ost_qtype $QTYPE || error "enable ost quota failed"
1186
1187         log "User quota (block hardlimit:$global_limit MB)"
1188         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
1189                 error "set user quota failed"
1190
1191         pool_add $qpool1 || error "pool_add failed"
1192         pool_add_targets $qpool1 0 0 ||
1193                 error "pool_add_targets failed"
1194
1195         $LFS setquota -u $TSTUSR -B ${limit1}M --pool $qpool1 $DIR ||
1196                 error "set user quota failed"
1197
1198         # make sure the system is clean
1199         local used=$(getquota -u $TSTUSR global curspace)
1200         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
1201
1202         $LFS setstripe $TESTDIR -c 1 -i 0 || error "setstripe $TESTDIR failed"
1203
1204         # hit pool limit
1205         test_1_check_write $testfile "user" $limit1
1206         $LFS setquota -u $TSTUSR -B 0 --pool $qpool1 $DIR ||
1207                 error "set user quota failed"
1208
1209         $LFS quota -uv $TSTUSR --pool $qpool1 $DIR
1210         $RUNAS $DD of=$testfile1 count=$((limit1/2)) ||
1211                 quota_error u $TSTUSR "write failure, but expect success"
1212
1213         rm -f $testfile
1214         rm -f $testfile1
1215         wait_delete_completed || error "wait_delete_completed failed"
1216         sync_all_data || true
1217
1218         $LFS setquota -u $TSTUSR -B ${limit1}M --pool $qpool1 $DIR ||
1219                 error "set user quota failed"
1220         test_1_check_write $testfile "user" $limit1
1221         local tmp_limit=$(($limit1*2))
1222         # increase pool limit
1223         $LFS setquota -u $TSTUSR -B ${tmp_limit}M --pool $qpool1 $DIR ||
1224                 error "set user quota failed"
1225         # now write shouldn't fail
1226         $RUNAS $DD of=$testfile1 count=$((limit1/3)) ||
1227                 quota_error u $TSTUSR "write failure, but expect success"
1228         # decrease pool limit
1229         $LFS setquota -u $TSTUSR -B ${limit1}M --pool $qpool1 $DIR ||
1230                 error "set user quota failed"
1231         $RUNAS $DD of=$testfile2 count=$((limit1/3))
1232         # flush cache, ensure noquota flag is set on client
1233         cancel_lru_locks osc
1234         sync; sync_all_data || true
1235         $RUNAS $DD of=$testfile2 seek=$((limit1/3)) count=1 &&
1236                 quota_error u $TSTUSR "write success, but expect failure"
1237         return 0
1238 }
1239 run_test 1i "Quota pools: different limit and usage relations"
1240
1241 test_1j() {
1242         local limit=20 # MB
1243         local testfile="$DIR/$tdir/$tfile-0"
1244
1245         (( $OST1_VERSION >= $(version_code 2.15.52.206) )) ||
1246                 skip "need OST at least 2.15.52.206"
1247
1248         is_project_quota_supported ||
1249                 skip "skip project quota unsupported"
1250
1251         setup_quota_test || error "setup quota failed with $?"
1252
1253         # enable ost quota
1254         set_ost_qtype $QTYPE || error "enable ost quota failed"
1255
1256         # test for Project
1257         log "--------------------------------------"
1258         log "Project quota (block hardlimit:$limit mb)"
1259         $LFS setquota -p $TSTPRJID -b 0 -B ${limit}M -i 0 -I 0 $DIR ||
1260                 error "set project quota failed"
1261
1262         $LFS setstripe $testfile -c 1 -i 0 || error "setstripe $testfile failed"
1263         change_project -p $TSTPRJID $testfile
1264
1265         local procf=osd-$ost1_FSTYPE.$FSNAME-OST0000.quota_slave.root_prj_enable
1266         do_facet ost1 $LCTL set_param $procf=1 ||
1267                 error "enable root quotas for project failed"
1268         stack_trap "do_facet ost1 $LCTL set_param $procf=0"
1269
1270         runas -u 0 -g 0 $DD of=$testfile count=$limit oflag=direct || true
1271         runas -u 0 -g 0 $DD of=$testfile count=$((limit/2)) seek=$limit oflag=direct &&
1272                 quota_error "project" $TSTPRJID "root write to project success"
1273
1274         do_facet ost1 $LCTL set_param $procf=0 ||
1275                 error "disable root quotas for project failed"
1276
1277         runas -u 0 -g 0 $DD of=$testfile count=$limit seek=$limit oflag=direct ||
1278                 quota_error "project" $TSTPRJID "root write to project failed"
1279
1280         # cleanup
1281         cleanup_quota_test
1282
1283         used=$(getquota -p $TSTPRJID global curspace)
1284         (( $used == 0 )) || quota_error p $TSTPRJID \
1285                 "project quota isn't released after deletion"
1286 }
1287 run_test 1j "Enable project quota enforcement for root"
1288
1289 # test inode hardlimit
1290 test_2() {
1291         local testfile="$DIR/$tdir/$tfile-0"
1292         local least_qunit=$(do_facet mds1 $LCTL get_param -n \
1293                 qmt.$FSNAME-QMT0000.md-0x0.info |
1294                 sed -e 's/least qunit/least_qunit/' |
1295                 awk '/least_qunit/{ print $2 }')
1296         local limit
1297
1298         [ "$SLOW" = "no" ] && limit=$((least_qunit * 2)) ||
1299                 limit=$((least_qunit * 1024))
1300         echo "least_qunit: '$least_qunit', limit: '$limit'"
1301
1302         local free_inodes=$(mdt_free_inodes 0)
1303         echo "$free_inodes free inodes on master MDT"
1304         [ $free_inodes -lt $limit ] &&
1305                 skip "not enough free inodes $free_inodes required $limit"
1306
1307         setup_quota_test || error "setup quota failed with $?"
1308
1309         # enable mdt quota
1310         set_mdt_qtype $QTYPE || error "enable mdt quota failed"
1311
1312         # test for user
1313         log "User quota (inode hardlimit:$limit files)"
1314         $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I $limit $DIR ||
1315                 error "set user quota failed"
1316
1317         # make sure the system is clean
1318         local used=$(getquota -u $TSTUSR global curinodes)
1319         [ $used -ne 0 ] && error "Used inodes($used) for user $TSTUSR isn't 0."
1320
1321         log "Create $((limit - least_qunit)) files ..."
1322         $RUNAS createmany -m ${testfile} $((limit - least_qunit)) ||
1323                 quota_error u $TSTUSR "user create failure, but expect success"
1324         # it is ok, if it fails on the last qunit
1325         $RUNAS createmany -m ${testfile}_yyy $least_qunit || true
1326         log "Create out of file quota ..."
1327         $RUNAS touch ${testfile}_xxx &&
1328                 quota_error u $TSTUSR "user create success, but expect EDQUOT"
1329
1330         # cleanup
1331         unlinkmany ${testfile} $((limit - least_qunit)) ||
1332                 error "unlinkmany $testfile failed"
1333         # if 2nd createmany got EDQUOT, not all of nodes would be created
1334         unlinkmany ${testfile}_yyy $least_qunit || true
1335         rm -f ${testfile}_xxx
1336         wait_delete_completed
1337
1338         used=$(getquota -u $TSTUSR global curinodes)
1339         [ $used -ne 0 ] && quota_error u $TSTUSR \
1340                 "user quota isn't released after deletion"
1341         resetquota -u $TSTUSR
1342
1343         # test for group
1344         log "--------------------------------------"
1345         log "Group quota (inode hardlimit:$limit files)"
1346         $LFS setquota -g $TSTUSR -b 0 -B 0 -i 0 -I $limit $DIR ||
1347                 error "set group quota failed"
1348
1349         testfile=$DIR/$tdir/$tfile-1
1350         # make sure the system is clean
1351         used=$(getquota -g $TSTUSR global curinodes)
1352         [ $used -ne 0 ] && error "Used inodes($used) for group $TSTUSR isn't 0."
1353
1354         log "Create $limit files ..."
1355         $RUNAS createmany -m ${testfile} $((limit - least_qunit)) ||
1356                 quota_error g $TSTUSR "group create failure, but expect success"
1357         $RUNAS createmany -m ${testfile}_yyy $least_qunit ||
1358         log "Create out of file quota ..."
1359         $RUNAS touch ${testfile}_xxx &&
1360                 quota_error g $TSTUSR "group create success, but expect EDQUOT"
1361
1362         # cleanup
1363         unlinkmany ${testfile} $((limit - least_qunit)) ||
1364                 error "unlinkmany $testfile failed"
1365         unlinkmany ${testfile}_yyy $least_qunit || true
1366         rm -f ${testfile}_xxx
1367         wait_delete_completed
1368
1369         used=$(getquota -g $TSTUSR global curinodes)
1370         [ $used -ne 0 ] && quota_error g $TSTUSR \
1371                 "user quota isn't released after deletion"
1372
1373         resetquota -g $TSTUSR
1374         ! is_project_quota_supported &&
1375                 echo "Skip project quota is not supported" && return 0
1376
1377         # test for project
1378         log "--------------------------------------"
1379         log "Project quota (inode hardlimit:$limit files)"
1380         $LFS setquota -p $TSTPRJID -b 0 -B 0 -i 0 -I $limit $DIR ||
1381                 error "set project quota failed"
1382
1383         testfile=$DIR/$tdir/$tfile-1
1384         # make sure the system is clean
1385         used=$(getquota -p $TSTPRJID global curinodes)
1386         [ $used -ne 0 ] &&
1387                 error "Used inodes($used) for project $TSTPRJID isn't 0"
1388
1389         change_project -sp $TSTPRJID $DIR/$tdir
1390         log "Create $limit files ..."
1391         $RUNAS createmany -m ${testfile} $((limit-least_qunit)) ||
1392                 quota_error p $TSTPRJID \
1393                         "project create fail, but expect success"
1394         $RUNAS createmany -m ${testfile}_yyy $least_qunit || true
1395         log "Create out of file quota ..."
1396         $RUNAS touch ${testfile}_xxx && quota_error p $TSTPRJID \
1397                 "project create success, but expect EDQUOT"
1398         change_project -C $DIR/$tdir
1399
1400         cleanup_quota_test
1401         used=$(getquota -p $TSTPRJID global curinodes)
1402         [ $used -eq 0 ] || quota_error p $TSTPRJID \
1403                 "project quota isn't released after deletion"
1404
1405 }
1406 run_test 2 "File hard limit (normal use and out of quota)"
1407
1408 test_block_soft() {
1409         local testfile=$1
1410         local grace=$2
1411         local limit=$3
1412         local OFFSET=0
1413         local qtype=$4
1414         local pool=$5
1415         local soft_limit=$(do_facet $SINGLEMDS $LCTL get_param -n \
1416                 qmt.$FSNAME-QMT0000.dt-0x0.soft_least_qunit)
1417
1418         setup_quota_test
1419
1420         $LFS setstripe $testfile -c 1 -i 0
1421         chown $TSTUSR.$TSTUSR $testfile
1422         [ "$qtype" == "p" ] && is_project_quota_supported &&
1423                 change_project -p $TSTPRJID $testfile
1424
1425         echo "Write up to soft limit"
1426         $RUNAS $DD of=$testfile count=$limit ||
1427                 quota_error a $TSTUSR "write failure, but expect success"
1428         OFFSET=$((limit * 1024))
1429         cancel_lru_locks osc
1430
1431         echo "Write to exceed soft limit"
1432         $RUNAS dd if=/dev/zero of=$testfile bs=1K count=10 seek=$OFFSET ||
1433                 quota_error a $TSTUSR "write failure, but expect success"
1434         OFFSET=$((OFFSET + 1024)) # make sure we don't write to same block
1435         cancel_lru_locks osc
1436
1437         echo "mmap write when over soft limit"
1438         $RUNAS $MULTIOP $testfile.mmap OT40960SMW ||
1439                 quota_error a $TSTUSR "mmap write failure, but expect success"
1440         cancel_lru_locks osc
1441
1442         $SHOW_QUOTA_USER
1443         $SHOW_QUOTA_GROUP
1444         $SHOW_QUOTA_PROJID
1445         $SHOW_QUOTA_INFO_USER
1446         $SHOW_QUOTA_INFO_GROUP
1447         $SHOW_QUOTA_INFO_PROJID
1448
1449         echo "Write before timer goes off"
1450         $RUNAS dd if=/dev/zero of=$testfile bs=1K count=10 seek=$OFFSET ||
1451                 quota_error a $TSTUSR "write failure, but expect success"
1452         OFFSET=$((OFFSET + 1024))
1453         cancel_lru_locks osc
1454
1455         wait_grace_time $qtype "block" $pool
1456
1457         $SHOW_QUOTA_USER
1458         $SHOW_QUOTA_GROUP
1459         $SHOW_QUOTA_PROJID
1460         $SHOW_QUOTA_INFO_USER
1461         $SHOW_QUOTA_INFO_GROUP
1462         $SHOW_QUOTA_INFO_PROJID
1463
1464         log "Write after timer goes off"
1465         # maybe cache write, ignore.
1466         # write up to soft least quint to consume all
1467         # possible slave granted space.
1468         $RUNAS dd if=/dev/zero of=$testfile bs=1K \
1469                 count=$soft_limit seek=$OFFSET || true
1470         OFFSET=$((OFFSET + soft_limit))
1471         cancel_lru_locks osc
1472         log "Write after cancel lru locks"
1473         $RUNAS dd if=/dev/zero of=$testfile bs=1K count=10 seek=$OFFSET &&
1474                 quota_error a $TSTUSR "write success, but expect EDQUOT"
1475
1476         $SHOW_QUOTA_USER
1477         $SHOW_QUOTA_GROUP
1478         $SHOW_QUOTA_PROJID
1479         $SHOW_QUOTA_INFO_USER
1480         $SHOW_QUOTA_INFO_GROUP
1481         $SHOW_QUOTA_INFO_PROJID
1482
1483         echo "Unlink file to stop timer"
1484         rm -f $testfile
1485         wait_delete_completed
1486         sync_all_data || true
1487
1488         $SHOW_QUOTA_USER
1489         $SHOW_QUOTA_GROUP
1490         $SHOW_QUOTA_PROJID
1491         $SHOW_QUOTA_INFO_USER
1492         $SHOW_QUOTA_INFO_GROUP
1493         $SHOW_QUOTA_INFO_PROJID
1494
1495         $LFS setstripe $testfile -c 1 -i 0
1496         chown $TSTUSR.$TSTUSR $testfile
1497         [ "$qtype" == "p" ] && change_project -p $TSTPRJID $testfile
1498
1499         echo "Write ..."
1500         $RUNAS $DD of=$testfile count=$limit ||
1501                 quota_error a $TSTUSR "write failure, but expect success"
1502         # cleanup
1503         cleanup_quota_test
1504 }
1505
1506 # block soft limit
1507 test_3a() {
1508         local grace=20 # seconds
1509         if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
1510             grace=60
1511         fi
1512         local testfile=$DIR/$tdir/$tfile-0
1513
1514         # get minimum soft qunit size
1515         local limit=$(( $(do_facet $SINGLEMDS $LCTL get_param -n \
1516                 qmt.$FSNAME-QMT0000.dt-0x0.soft_least_qunit) / 1024 ))
1517
1518         set_ost_qtype $QTYPE || error "enable ost quota failed"
1519
1520         echo "User quota (soft limit:$limit MB  grace:$grace seconds)"
1521         # make sure the system is clean
1522         local used=$(getquota -u $TSTUSR global curspace)
1523         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
1524
1525         $LFS setquota -t -u --block-grace $grace --inode-grace \
1526                 $MAX_IQ_TIME $DIR || error "set user grace time failed"
1527         $LFS setquota -u $TSTUSR -b ${limit}M -B 0 -i 0 -I 0 $DIR ||
1528                 error "set user quota failed"
1529
1530         test_block_soft $testfile $grace $limit "u"
1531
1532         echo "Group quota (soft limit:$limit MB  grace:$grace seconds)"
1533         testfile=$DIR/$tdir/$tfile-1
1534         # make sure the system is clean
1535         used=$(getquota -g $TSTUSR global curspace)
1536         [ $used -ne 0 ] && error "Used space($used) for group $TSTUSR isn't 0."
1537
1538         $LFS setquota -t -g --block-grace $grace --inode-grace \
1539                 $MAX_IQ_TIME $DIR || error "set group grace time failed"
1540         $LFS setquota -g $TSTUSR -b ${limit}M -B 0 -i 0 -I 0 $DIR ||
1541                 error "set group quota failed"
1542
1543         test_block_soft $testfile $grace $limit "g"
1544
1545         if is_project_quota_supported; then
1546                 echo "Project quota (soft limit:$limit MB  grace:$grace sec)"
1547                 testfile=$DIR/$tdir/$tfile-2
1548                 # make sure the system is clean
1549                 used=$(getquota -p $TSTPRJID global curspace)
1550                 [ $used -ne 0 ] && error \
1551                         "Used space($used) for project $TSTPRJID isn't 0."
1552
1553                 $LFS setquota -t -p --block-grace $grace --inode-grace \
1554                         $MAX_IQ_TIME $DIR ||
1555                                 error "set project grace time failed"
1556                 $LFS setquota -p $TSTPRJID -b ${limit}M -B 0 -i 0 -I 0 \
1557                         $DIR || error "set project quota failed"
1558
1559                 test_block_soft $testfile $grace $limit "p"
1560                 resetquota -p $TSTPRJID
1561                 $LFS setquota -t -p --block-grace $MAX_DQ_TIME --inode-grace \
1562                         $MAX_IQ_TIME $DIR ||
1563                                 error "restore project grace time failed"
1564         fi
1565
1566         # cleanup
1567         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
1568                 $MAX_IQ_TIME $DIR || error "restore user grace time failed"
1569         $LFS setquota -t -g --block-grace $MAX_DQ_TIME --inode-grace \
1570                 $MAX_IQ_TIME $DIR || error "restore group grace time failed"
1571 }
1572 run_test 3a "Block soft limit (start timer, timer goes off, stop timer)"
1573
1574 test_3b() {
1575         local grace=20 # seconds
1576         local qpool="qpool1"
1577         if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
1578                 grace=60
1579         fi
1580         local testfile=$DIR/$tdir/$tfile-0
1581
1582         mds_supports_qp
1583         # get minimum soft qunit size
1584         local limit=$(( $(do_facet $SINGLEMDS $LCTL get_param -n \
1585                 qmt.$FSNAME-QMT0000.dt-0x0.soft_least_qunit) / 1024 ))
1586         local glbl_limit=$((2*limit))
1587         local glbl_grace=$((2*grace))
1588         echo "limit $limit glbl_limit $glbl_limit"
1589         echo "grace $grace glbl_grace $glbl_grace"
1590
1591         set_ost_qtype $QTYPE || error "enable ost quota failed"
1592
1593         echo "User quota in $qpool(soft limit:$limit MB  grace:$grace seconds)"
1594         # make sure the system is clean
1595         local used=$(getquota -u $TSTUSR global curspace)
1596         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
1597
1598         pool_add $qpool || error "pool_add failed"
1599         pool_add_targets $qpool 0 1 ||
1600                 error "pool_add_targets failed"
1601
1602         $LFS setquota -t -u --block-grace $glbl_grace --inode-grace \
1603                 $MAX_IQ_TIME $DIR || error "set user grace time failed"
1604         $LFS setquota -t -u --block-grace $grace \
1605                 --pool $qpool $DIR || error "set user grace time failed"
1606
1607         $LFS setquota -u $TSTUSR -b ${glbl_limit}M -B 0 -i 0 -I 0 $DIR ||
1608                 error "set user quota failed"
1609         $LFS setquota -u $TSTUSR -b ${limit}M -B 0 --pool $qpool $DIR ||
1610                 error "set user quota failed"
1611
1612         test_block_soft $testfile $grace $limit "u" $qpool
1613
1614         echo "Group quota in $qpool(soft limit:$limit MB  grace:$grace seconds)"
1615         testfile=$DIR/$tdir/$tfile-1
1616         # make sure the system is clean
1617         used=$(getquota -g $TSTUSR global curspace)
1618         [ $used -ne 0 ] && error "Used space($used) for group $TSTUSR isn't 0."
1619
1620         $LFS setquota -t -g --block-grace $glbl_grace --inode-grace \
1621                 $MAX_IQ_TIME $DIR || error "set group grace time failed"
1622         $LFS setquota -t -g --block-grace $grace \
1623                 --pool $qpool $DIR || error "set group grace time failed"
1624
1625         $LFS setquota -g $TSTUSR -b ${glbl_limit}M -B 0 -i 0 -I 0 $DIR ||
1626                 error "set group quota failed"
1627         $LFS setquota -g $TSTUSR -b ${limit}M -B 0 --pool $qpool $DIR ||
1628                 error "set group quota failed"
1629
1630         test_block_soft $testfile $grace $limit "g" $qpool
1631
1632         if is_project_quota_supported; then
1633                 echo "Project quota in $qpool(soft:$limit MB  grace:$grace sec)"
1634                 testfile=$DIR/$tdir/$tfile-2
1635                 # make sure the system is clean
1636                 used=$(getquota -p $TSTPRJID global curspace)
1637                 [ $used -ne 0 ] && error \
1638                         "Used space($used) for project $TSTPRJID isn't 0."
1639
1640                 $LFS setquota -t -p --block-grace $glbl_grace --inode-grace \
1641                         $MAX_IQ_TIME $DIR ||
1642                                 error "set project grace time failed"
1643                 $LFS setquota -t -p --block-grace $grace \
1644                         --pool $qpool $DIR ||
1645                                 error "set project grace time failed"
1646
1647                 $LFS setquota -p $TSTPRJID -b ${glbl_limit}M -B 0 -i 0 -I 0 \
1648                         $DIR || error "set project quota failed"
1649                 $LFS setquota -p $TSTPRJID -b ${limit}M -B 0 \
1650                         --pool $qpool $DIR || error "set project quota failed"
1651
1652                 test_block_soft $testfile $grace $limit "p" $qpool
1653                 resetquota -p $TSTPRJID
1654                 $LFS setquota -t -p --block-grace $MAX_DQ_TIME --inode-grace \
1655                         $MAX_IQ_TIME $DIR ||
1656                                 error "restore project grace time failed"
1657                 $LFS setquota -t -p --block-grace $MAX_DQ_TIME --pool $qpool \
1658                         $DIR || error "set project grace time failed"
1659         fi
1660
1661         # cleanup
1662         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
1663                 $MAX_IQ_TIME $DIR || error "restore user grace time failed"
1664         $LFS setquota -t -u --block-grace $MAX_DQ_TIME \
1665                 --pool $qpool $DIR || error "restore user grace time failed"
1666         $LFS setquota -t -g --block-grace $MAX_DQ_TIME --inode-grace \
1667                 $MAX_IQ_TIME $DIR || error "restore group grace time failed"
1668         $LFS setquota -t -g --block-grace $MAX_DQ_TIME \
1669                 --pool $qpool $DIR || error "restore group grace time failed"
1670 }
1671 run_test 3b "Quota pools: Block soft limit (start timer, expires, stop timer)"
1672
1673 test_3c() {
1674         local grace=20 # seconds
1675         local qpool="qpool1"
1676         local qpool2="qpool2"
1677         if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
1678                 grace=60
1679         fi
1680         local testfile=$DIR/$tdir/$tfile-0
1681
1682         mds_supports_qp
1683         # get minimum soft qunit size
1684         local limit=$(( $(do_facet $SINGLEMDS $LCTL get_param -n \
1685                 qmt.$FSNAME-QMT0000.dt-0x0.soft_least_qunit) / 1024 ))
1686         local limit2=$((limit+4))
1687         local glbl_limit=$((limit+8))
1688         local grace1=$((grace+10))
1689         local grace2=$grace
1690         local glbl_grace=$((grace+20))
1691         echo "limit $limit limit2 $limit2 glbl_limit $glbl_limit"
1692         echo "grace1 $grace1 grace2 $grace2 glbl_grace $glbl_grace"
1693
1694         set_ost_qtype $QTYPE || error "enable ost quota failed"
1695
1696         echo "User quota in qpool2(soft:$limit2 MB grace:$grace2 seconds)"
1697         # make sure the system is clean
1698         local used=$(getquota -u $TSTUSR global curspace)
1699         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
1700
1701         pool_add $qpool || error "pool_add failed"
1702         pool_add_targets $qpool 0 1 ||
1703                 error "pool_add_targets failed"
1704
1705         pool_add $qpool2 || error "pool_add failed"
1706         pool_add_targets $qpool2 0 1 ||
1707                 error "pool_add_targets failed"
1708
1709
1710         $LFS setquota -t -u --block-grace $glbl_grace --inode-grace \
1711                 $MAX_IQ_TIME $DIR || error "set user grace time failed"
1712         $LFS setquota -t -u --block-grace $grace1 \
1713                 --pool $qpool $DIR || error "set user grace time failed"
1714         $LFS setquota -t -u --block-grace $grace2 \
1715                 --pool $qpool2 $DIR || error "set user grace time failed"
1716
1717         $LFS setquota -u $TSTUSR -b ${glbl_limit}M -B 0 -i 0 -I 0 $DIR ||
1718                 error "set user quota failed"
1719         $LFS setquota -u $TSTUSR -b ${limit}M -B 0 --pool $qpool $DIR ||
1720                 error "set user quota failed"
1721         # qpool has minimum soft limit, but its grace is greater than
1722         # the grace period of qpool2. Thus write shouldn't fail when
1723         # hit qpool soft limit - only when reaches up qpool2 limit
1724         # after grace2 seconds.
1725         $LFS setquota -u $TSTUSR -b ${limit2}M -B 0 --pool $qpool2 $DIR ||
1726                 error "set user quota failed"
1727
1728         test_block_soft $testfile $grace2 $limit2 "u" $qpool2
1729
1730         # cleanup
1731         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
1732                 $MAX_IQ_TIME $DIR || error "restore user grace time failed"
1733         $LFS setquota -t -u --block-grace $MAX_DQ_TIME \
1734                 --pool $qpool $DIR || error "restore user grace time failed"
1735         $LFS setquota -t -u --block-grace $MAX_DQ_TIME \
1736                 --pool $qpool2 $DIR || error "restore user grace time failed"
1737 }
1738 run_test 3c "Quota pools: check block soft limit on different pools"
1739
1740 test_file_soft() {
1741         local TESTFILE=$1
1742         local LIMIT=$2
1743         local grace=$3
1744         local qtype=$4
1745         local SOFT_LIMIT=$(do_facet $SINGLEMDS $LCTL get_param -n \
1746                 qmt.$FSNAME-QMT0000.md-0x0.soft_least_qunit)
1747
1748         setup_quota_test
1749         is_project_quota_supported && change_project -sp $TSTPRJID $DIR/$tdir
1750
1751         echo "Create files to exceed soft limit"
1752         $RUNAS createmany -m ${TESTFILE}_ $((LIMIT + 1)) ||
1753                 quota_error a $TSTUSR "create failure, but expect success"
1754         local trigger_time=$(date +%s)
1755
1756         sync_all_data || true
1757
1758         local cur_time=$(date +%s)
1759         [ $(($cur_time - $trigger_time)) -ge $grace ] &&
1760                 error "Passed grace time $grace, $trigger_time, $cur_time"
1761
1762         echo "Create file before timer goes off"
1763         $RUNAS touch ${TESTFILE}_before ||
1764                 quota_error a $TSTUSR "failed create before timer expired," \
1765                         "but expect success. $trigger_time, $cur_time"
1766         sync_all_data || true
1767
1768         wait_grace_time $qtype "file"
1769
1770         $SHOW_QUOTA_USER
1771         $SHOW_QUOTA_GROUP
1772         $SHOW_QUOTA_PROJID
1773         $SHOW_QUOTA_INFO_USER
1774         $SHOW_QUOTA_INFO_GROUP
1775         $SHOW_QUOTA_INFO_PROJID
1776
1777         echo "Create file after timer goes off"
1778         # exceed least soft limit is possible
1779         $RUNAS createmany -m ${TESTFILE}_after_3 $((SOFT_LIMIT + 1)) &&
1780                 quota_error a $TSTUSR "create after timer expired," \
1781                         "but expect EDQUOT"
1782         sync_all_data || true
1783
1784         $SHOW_QUOTA_USER
1785         $SHOW_QUOTA_GROUP
1786         $SHOW_QUOTA_PROJID
1787         $SHOW_QUOTA_INFO_USER
1788         $SHOW_QUOTA_INFO_GROUP
1789         $SHOW_QUOTA_INFO_PROJID
1790
1791         echo "Unlink files to stop timer"
1792         find $(dirname $TESTFILE) -name "$(basename ${TESTFILE})*" | xargs rm -f
1793         wait_delete_completed
1794
1795         echo "Create file"
1796         $RUNAS touch ${TESTFILE}_xxx ||
1797                 quota_error a $TSTUSR "touch after timer stop failure," \
1798                         "but expect success"
1799         sync_all_data || true
1800
1801         # cleanup
1802         cleanup_quota_test
1803 }
1804
1805 # file soft limit
1806 test_4a() {
1807         local LIMIT=$(do_facet $SINGLEMDS $LCTL get_param -n \
1808                 qmt.$FSNAME-QMT0000.md-0x0.soft_least_qunit)
1809         local TESTFILE=$DIR/$tdir/$tfile-0
1810         local GRACE=12
1811
1812         [ "$mds1_FSTYPE" = zfs ] && GRACE=20
1813         set_mdt_qtype $QTYPE || error "enable mdt quota failed"
1814
1815         echo "User quota (soft limit:$LIMIT files  grace:$GRACE seconds)"
1816         # make sure the system is clean
1817         local USED=$(getquota -u $TSTUSR global curinodes)
1818         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
1819
1820         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
1821                 $GRACE $DIR || error "set user grace time failed"
1822         $LFS setquota -u $TSTUSR -b 0 -B 0 -i $LIMIT -I 0 $DIR ||
1823                 error "set user quota failed"
1824
1825         test_file_soft $TESTFILE $LIMIT $GRACE "u"
1826
1827         echo "Group quota (soft limit:$LIMIT files  grace:$GRACE seconds)"
1828         # make sure the system is clean
1829         USED=$(getquota -g $TSTUSR global curinodes)
1830         [ $USED -ne 0 ] && error "Used space($USED) for group $TSTUSR isn't 0."
1831
1832         $LFS setquota -t -g --block-grace $MAX_DQ_TIME --inode-grace \
1833                 $GRACE $DIR || error "set group grace time failed"
1834         $LFS setquota -g $TSTUSR -b 0 -B 0 -i $LIMIT -I 0 $DIR ||
1835                 error "set group quota failed"
1836         TESTFILE=$DIR/$tdir/$tfile-1
1837
1838         test_file_soft $TESTFILE $LIMIT $GRACE "g"
1839
1840         if is_project_quota_supported; then
1841                 echo "Project quota (soft limit:$LIMIT files grace:$GRACE sec)"
1842                 # make sure the system is clean
1843                 USED=$(getquota -p $TSTPRJID global curinodes)
1844                 [ $USED -ne 0 ] && error \
1845                         "Used space($USED) for project $TSTPRJID isn't 0."
1846
1847                 $LFS setquota -t -p --block-grace $MAX_DQ_TIME --inode-grace \
1848                         $GRACE $DIR || error "set project grace time failed"
1849                 $LFS setquota -p $TSTPRJID -b 0 -B 0 -i $LIMIT -I 0 $DIR ||
1850                         error "set project quota failed"
1851
1852                 TESTFILE=$DIR/$tdir/$tfile-1
1853                 # one less than limit, because of parent directory included.
1854                 test_file_soft $TESTFILE $((LIMIT-1)) $GRACE "p"
1855                 resetquota -p $TSTPRJID
1856                 $LFS setquota -t -p --block-grace $MAX_DQ_TIME --inode-grace \
1857                         $MAX_IQ_TIME $DIR ||
1858                                 error "restore project grace time failed"
1859         fi
1860
1861         # cleanup
1862         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
1863                 $MAX_IQ_TIME $DIR || error "restore user grace time failed"
1864         $LFS setquota -t -g --block-grace $MAX_DQ_TIME --inode-grace \
1865                 $MAX_IQ_TIME $DIR || error "restore group grace time failed"
1866 }
1867 run_test 4a "File soft limit (start timer, timer goes off, stop timer)"
1868
1869 test_4b() {
1870         local GR_STR1="1w3d"
1871         local GR_STR2="1000s"
1872         local GR_STR3="5s"
1873         local GR_STR4="1w2d3h4m5s"
1874         local GR_STR5="5c"
1875         local GR_STR6="18446744073709551615"
1876         local GR_STR7="-1"
1877
1878         wait_delete_completed
1879
1880         # test of valid grace strings handling
1881         echo "Valid grace strings test"
1882         $LFS setquota -t -u --block-grace $GR_STR1 --inode-grace \
1883                 $GR_STR2 $DIR || error "set user grace time failed"
1884         $LFS quota -u -t $DIR | grep "Block grace time: $GR_STR1"
1885         $LFS setquota -t -g --block-grace $GR_STR3 --inode-grace \
1886                 $GR_STR4 $DIR || error "set group grace time quota failed"
1887         $LFS quota -g -t $DIR | grep "Inode grace time: $GR_STR4"
1888
1889         # test of invalid grace strings handling
1890         echo "  Invalid grace strings test"
1891         ! $LFS setquota -t -u --block-grace $GR_STR4 --inode-grace $GR_STR5 $DIR
1892         ! $LFS setquota -t -g --block-grace $GR_STR4 --inode-grace $GR_STR6 $DIR
1893         ! $LFS setquota -t -g --block-grace $GR_STR4 --inode-grace \
1894                 $GR_STR7 $DIR
1895
1896         # cleanup
1897         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
1898                 $MAX_IQ_TIME $DIR || error "restore user grace time failed"
1899         $LFS setquota -t -g --block-grace $MAX_DQ_TIME --inode-grace \
1900                 $MAX_IQ_TIME $DIR || error "restore group grace time failed"
1901 }
1902 run_test 4b "Grace time strings handling"
1903
1904 # chown & chgrp (chown & chgrp successfully even out of block/file quota)
1905 test_5() {
1906         local BLIMIT=10 # MB
1907         local ILIMIT=10 # inodes
1908
1909         setup_quota_test || error "setup quota failed with $?"
1910
1911         set_mdt_qtype $QTYPE || error "enable mdt quota failed"
1912         set_ost_qtype $QTYPE || error "enable ost quota failed"
1913
1914         echo "Set quota limit (0 ${BLIMIT}M 0 $ILIMIT) for $TSTUSR.$TSTUSR"
1915         $LFS setquota -u $TSTUSR -b 0 -B ${BLIMIT}M -i 0 -I $ILIMIT $DIR ||
1916                 error "set user quota failed"
1917         $LFS setquota -g $TSTUSR -b 0 -B ${BLIMIT}M -i 0 -I $ILIMIT $DIR ||
1918         if is_project_quota_supported; then
1919                 error "set group quota failed"
1920                 $LFS setquota -p $TSTPRJID -b 0 -B ${BLIMIT}M -i 0 \
1921                         -I $ILIMIT $DIR || error "set project quota failed"
1922         fi
1923
1924         # make sure the system is clean
1925         local USED=$(getquota -u $TSTUSR global curinodes)
1926         [ $USED -ne 0 ] && error "Used inode($USED) for user $TSTUSR isn't 0."
1927         USED=$(getquota -g $TSTUSR global curinodes)
1928         [ $USED -ne 0 ] && error "Used inode($USED) for group $TSTUSR isn't 0."
1929         USED=$(getquota -u $TSTUSR global curspace)
1930         [ $USED -ne 0 ] && error "Used block($USED) for user $TSTUSR isn't 0."
1931         USED=$(getquota -g $TSTUSR global curspace)
1932         [ $USED -ne 0 ] && error "Used block($USED) for group $TSTUSR isn't 0."
1933         if is_project_quota_supported; then
1934                 USED=$(getquota -p $TSTPRJID global curinodes)
1935                 [ $USED -ne 0 ] &&
1936                         error "Used inode($USED) for project $TSTPRJID isn't 0."
1937                 USED=$(getquota -p $TSTPRJID global curspace)
1938                 [ $USED -ne 0 ] &&
1939                         error "Used block($USED) for project $TSTPRJID isn't 0."
1940         fi
1941
1942         echo "Create more than $ILIMIT files and more than $BLIMIT MB ..."
1943         createmany -m $DIR/$tdir/$tfile-0_ $((ILIMIT + 1)) ||
1944                 error "create failure, expect success"
1945         if is_project_quota_supported; then
1946                 touch $DIR/$tdir/$tfile-0_1
1947                 change_project -p $TSTPRJID $DIR/$tdir/$tfile-0_1
1948         fi
1949         $DD of=$DIR/$tdir/$tfile-0_1 count=$((BLIMIT+1)) ||
1950                 error "write failure, expect success"
1951
1952         echo "Chown files to $TSTUSR.$TSTUSR ..."
1953         for i in $(seq 0 $ILIMIT); do
1954                 chown $TSTUSR.$TSTUSR $DIR/$tdir/$tfile-0_$i ||
1955                         quota_error a $TSTUSR "chown failure, expect success"
1956         done
1957
1958         # cleanup
1959         unlinkmany $DIR/$tdir/$tfile-0_ $((ILIMIT + 1)) ||
1960                 error "unlinkmany $DIR/$tdir/$tfile-0_ failed"
1961 }
1962 run_test 5 "Chown & chgrp successfully even out of block/file quota"
1963
1964 # test dropping acquire request on master
1965 test_6() {
1966         local LIMIT=3 # MB
1967
1968         # Clear dmesg so watchdog is not triggered by previous
1969         # test output
1970         do_facet ost1 dmesg -c > /dev/null
1971
1972         setup_quota_test || error "setup quota failed with $?"
1973
1974         # make sure the system is clean
1975         local USED=$(getquota -u $TSTUSR global curspace)
1976         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
1977
1978         # make sure no granted quota on ost
1979         set_ost_qtype $QTYPE || error "enable ost quota failed"
1980         resetquota -u $TSTUSR
1981
1982         # create file for $TSTUSR
1983         local TESTFILE=$DIR/$tdir/$tfile-$TSTUSR
1984         $LFS setstripe $TESTFILE -c 1 -i 0 || error "setstripe $TESTFILE failed"
1985         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
1986
1987         # create file for $TSTUSR2
1988         local TESTFILE2=$DIR/$tdir/$tfile-$TSTUSR2
1989         $LFS setstripe $TESTFILE2 -c 1 -i 0 || error "setstripe $TESTFILE2 failed"
1990         chown $TSTUSR2.$TSTUSR2 $TESTFILE2 || error "chown $TESTFILE2 failed"
1991
1992         # cache per-ID lock for $TSTUSR on slave
1993         $LFS setquota -u $TSTUSR -b 0 -B ${LIMIT}M -i 0 -I 0 $DIR ||
1994                 error "set quota failed"
1995         $RUNAS $DD of=$TESTFILE count=1 ||
1996                 error "write $TESTFILE failure, expect success"
1997         $RUNAS2 $DD of=$TESTFILE2 count=1 ||
1998                 error "write $TESTFILE2 failure, expect success"
1999
2000         if at_is_enabled; then
2001                 at_max_saved=$(at_max_get ost1)
2002                 at_max_set $TIMEOUT ost1
2003
2004                 # write to enforced ID ($TSTUSR) to exceed limit to make sure
2005                 # DQACQ is sent, which makes at_max to take effect
2006                 $RUNAS $DD of=$TESTFILE count=$LIMIT seek=1 oflag=sync \
2007                                                                 conv=notrunc
2008                 rm -f $TESTFILE
2009                 wait_delete_completed
2010         fi
2011
2012         sync; sync
2013         sync_all_data || true
2014
2015         #define QUOTA_DQACQ 601
2016         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC 0x513
2017         lustre_fail mds 0x513 601
2018
2019         do_facet ost1 $LCTL set_param \
2020                         osd-*.$FSNAME-OST*.quota_slave.timeout=$((TIMEOUT / 2))
2021
2022         # write to un-enforced ID ($TSTUSR2) should succeed
2023         $RUNAS2 $DD of=$TESTFILE2 count=$LIMIT seek=1 oflag=sync conv=notrunc ||
2024                 error "write failure, expect success"
2025
2026         # write to enforced ID ($TSTUSR) in background, exceeding limit
2027         # to make sure DQACQ is sent
2028         $RUNAS $DD of=$TESTFILE count=$LIMIT seek=1 oflag=sync conv=notrunc &
2029         DDPID=$!
2030
2031         # watchdog timer uses a factor of 2
2032         echo "Sleep for $((TIMEOUT * 2 + 1)) seconds ..."
2033         sleep $((TIMEOUT * 2 + 1))
2034
2035         [ $at_max_saved -ne 0 ] && at_max_set $at_max_saved ost1
2036
2037         # write should be blocked and never finished
2038         if ! ps -p $DDPID  > /dev/null 2>&1; then
2039                 lustre_fail mds 0 0
2040                 error "write finished incorrectly!"
2041         fi
2042
2043         lustre_fail mds 0 0
2044
2045         # no watchdog is triggered
2046         do_facet ost1 dmesg > $TMP/lustre-log-${TESTNAME}.log
2047         watchdog=$(awk '/[Ss]ervice thread pid/ && /was inactive/ \
2048                         { print; }' $TMP/lustre-log-${TESTNAME}.log)
2049         [ -z "$watchdog" ] || error "$watchdog"
2050
2051         rm -f $TMP/lustre-log-${TESTNAME}.log
2052
2053         # write should continue then fail with EDQUOT
2054         local count=0
2055         local c_size
2056         while [ true ]; do
2057                 if ! ps -p ${DDPID} > /dev/null 2>&1; then break; fi
2058                 if [ $count -ge 240 ]; then
2059                         quota_error u $TSTUSR "dd not finished in $count secs"
2060                 fi
2061                 count=$((count + 1))
2062                 if [ $((count % 30)) -eq 0 ]; then
2063                         c_size=$(stat -c %s $TESTFILE)
2064                         echo "Waiting $count secs. $c_size"
2065                         $SHOW_QUOTA_USER
2066                 fi
2067                 sleep 1
2068         done
2069 }
2070 run_test 6 "Test dropping acquire request on master"
2071
2072 # quota reintegration (global index)
2073 test_7a() {
2074         local TESTFILE=$DIR/$tdir/$tfile
2075         local LIMIT=20 # MB
2076
2077         [ "$SLOW" = "no" ] && LIMIT=5
2078
2079         setup_quota_test || error "setup quota failed with $?"
2080
2081         # make sure the system is clean
2082         local USED=$(getquota -u $TSTUSR global curspace)
2083         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
2084
2085         # make sure no granted quota on ost1
2086         set_ost_qtype $QTYPE || error "enable ost quota failed"
2087         resetquota -u $TSTUSR
2088         set_ost_qtype "none" || error "disable ost quota failed"
2089
2090         local OSTUUID=$(ostuuid_from_index 0)
2091         USED=$(getquota -u $TSTUSR $OSTUUID bhardlimit)
2092         [ $USED -ne 0 ] &&
2093                 error "limit($USED) on $OSTUUID for user $TSTUSR isn't 0"
2094
2095         # create test file
2096         $LFS setstripe $TESTFILE -c 1 -i 0 || error "setstripe $TESTFILE failed"
2097         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
2098
2099         echo "Stop ost1..."
2100         stop ost1
2101
2102         echo "Enable quota & set quota limit for $TSTUSR"
2103         set_ost_qtype $QTYPE || error "enable ost quota failed"
2104         $LFS setquota -u $TSTUSR -b 0 -B ${LIMIT}M -i 0 -I 0 $DIR ||
2105                 error "set quota failed"
2106
2107         echo "Start ost1..."
2108         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "start ost1 failed"
2109         quota_init
2110
2111         wait_ost_reint $QTYPE || error "reintegration failed"
2112
2113         # hardlimit should have been fetched by slave during global
2114         # reintegration, write will exceed quota
2115         $RUNAS $DD of=$TESTFILE count=$((LIMIT + 1)) oflag=sync &&
2116                 quota_error u $TSTUSR "write success, but expect EDQUOT"
2117
2118         rm -f $TESTFILE
2119         wait_delete_completed
2120         sync_all_data || true
2121         sleep 3
2122
2123         echo "Stop ost1..."
2124         stop ost1
2125
2126         $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I 0 $DIR ||
2127                 error "clear quota failed"
2128
2129         echo "Start ost1..."
2130         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "start ost1 failed"
2131         quota_init
2132
2133         wait_ost_reint $QTYPE || error "reintegration failed"
2134
2135         # hardlimit should be cleared on slave during reintegration
2136         $RUNAS $DD of=$TESTFILE count=$((LIMIT + 1)) oflag=sync ||
2137                 quota_error u $TSTUSR "write error, but expect success"
2138 }
2139 run_test 7a "Quota reintegration (global index)"
2140
2141 # quota reintegration (slave index)
2142 test_7b() {
2143         local limit=100000 # MB
2144         local TESTFILE=$DIR/$tdir/$tfile
2145
2146         setup_quota_test || error "setup quota failed with $?"
2147
2148         # make sure the system is clean
2149         local USED=$(getquota -u $TSTUSR global curspace)
2150         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
2151
2152         # make sure no granted quota on ost1
2153         set_ost_qtype $QTYPE || error "enable ost quota failed"
2154         resetquota -u $TSTUSR
2155         set_ost_qtype "none" || error "disable ost quota failed"
2156
2157         local OSTUUID=$(ostuuid_from_index 0)
2158         USED=$(getquota -u $TSTUSR $OSTUUID bhardlimit)
2159         [ $USED -ne 0 ] &&
2160                 error "limit($USED) on $OSTUUID for user $TSTUSR isn't 0"
2161
2162         # create test file
2163         $LFS setstripe $TESTFILE -c 1 -i 0 || error "setstripe $TESTFILE failed"
2164         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
2165
2166         # consume some space to make sure the granted space will not
2167         # be released during reconciliation
2168         $RUNAS $DD of=$TESTFILE count=1 oflag=sync ||
2169                 error "consume space failure, expect success"
2170
2171         # define OBD_FAIL_QUOTA_EDQUOT 0xa02
2172         lustre_fail mds 0xa02
2173
2174         set_ost_qtype $QTYPE || error "enable ost quota failed"
2175         $LFS setquota -u $TSTUSR -b 0 -B ${limit}M -i 0 -I 0 $DIR ||
2176                 error "set quota failed"
2177
2178         # ignore the write error
2179         $RUNAS $DD of=$TESTFILE count=1 seek=1 oflag=sync conv=notrunc
2180
2181         local old_used=$(getquota -u $TSTUSR $OSTUUID bhardlimit)
2182
2183         lustre_fail mds 0
2184
2185         echo "Restart ost to trigger reintegration..."
2186         stop ost1
2187         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "start ost1 failed"
2188         quota_init
2189
2190         wait_ost_reint $QTYPE || error "reintegration failed"
2191
2192         USED=$(getquota -u $TSTUSR $OSTUUID bhardlimit)
2193         [ $USED -gt $old_used ] || error "limit on $OSTUUID $USED <= $old_used"
2194
2195         cleanup_quota_test
2196         $SHOW_QUOTA_USER
2197 }
2198 run_test 7b "Quota reintegration (slave index)"
2199
2200 # quota reintegration (restart mds during reintegration)
2201 test_7c() {
2202         local LIMIT=20 # MB
2203         local TESTFILE=$DIR/$tdir/$tfile
2204
2205         [ "$SLOW" = "no" ] && LIMIT=5
2206
2207         setup_quota_test || error "setup quota failed with $?"
2208
2209         # make sure the system is clean
2210         local USED=$(getquota -u $TSTUSR global curspace)
2211         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
2212
2213         set_ost_qtype "none" || error "disable ost quota failed"
2214         $LFS setquota -u $TSTUSR -b 0 -B ${LIMIT}M -i 0 -I 0 $DIR ||
2215                 error "set quota failed"
2216
2217         # define OBD_FAIL_QUOTA_DELAY_REINT 0xa03
2218         lustre_fail ost 0xa03
2219
2220         # enable ost quota
2221         set_ost_qtype $QTYPE || error "enable ost quota failed"
2222         # trigger reintegration
2223         local procf="osd-$ost1_FSTYPE.$FSNAME-OST*."
2224         procf=${procf}quota_slave.force_reint
2225         do_facet ost1 $LCTL set_param $procf=1 ||
2226                 error "force reintegration failed"
2227
2228         echo "Stop mds..."
2229         stop mds1
2230
2231         lustre_fail ost 0
2232
2233         echo "Start mds..."
2234         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
2235         quota_init
2236
2237         # wait longer than usual to make sure the reintegration
2238         # is triggered by quota wb thread.
2239         wait_ost_reint $QTYPE 200 || error "reintegration failed"
2240
2241         # hardlimit should have been fetched by slave during global
2242         # reintegration, write will exceed quota
2243         $RUNAS $DD of=$TESTFILE count=$((LIMIT + 1)) oflag=sync &&
2244                 quota_error u $TSTUSR "write success, but expect EDQUOT"
2245         return 0
2246 }
2247 run_test 7c "Quota reintegration (restart mds during reintegration)"
2248
2249 # Quota reintegration (Transfer index in multiple bulks)
2250 test_7d(){
2251         local TESTFILE=$DIR/$tdir/$tfile
2252         local TESTFILE1="$DIR/$tdir/$tfile"-1
2253         local limit=20 # MB
2254
2255         setup_quota_test || error "setup quota failed with $?"
2256
2257         set_ost_qtype "none" || error "disable ost quota failed"
2258         $LFS setquota -u $TSTUSR -B ${limit}M $DIR ||
2259                 error "set quota for $TSTUSR failed"
2260         $LFS setquota -u $TSTUSR2 -B ${limit}M $DIR ||
2261                 error "set quota for $TSTUSR2 failed"
2262
2263         #define OBD_FAIL_OBD_IDX_READ_BREAK 0x608
2264         lustre_fail mds 0x608 0
2265
2266         # enable quota to tirgger reintegration
2267         set_ost_qtype "u" || error "enable ost quota failed"
2268         wait_ost_reint "u" || error "reintegration failed"
2269
2270         lustre_fail mds 0
2271
2272         # hardlimit should have been fetched by slave during global
2273         # reintegration, write will exceed quota
2274         $RUNAS $DD of=$TESTFILE count=$((limit + 1)) oflag=sync &&
2275                 quota_error u $TSTUSR "$TSTUSR write success, expect EDQUOT"
2276
2277         $RUNAS2 $DD of=$TESTFILE1 count=$((limit + 1)) oflag=sync &&
2278                 quota_error u $TSTUSR2 "$TSTUSR2 write success, expect EDQUOT"
2279         return 0
2280 }
2281 run_test 7d "Quota reintegration (Transfer index in multiple bulks)"
2282
2283 # quota reintegration (inode limits)
2284 test_7e() {
2285         [ "$MDSCOUNT" -lt "2" ] && skip "needs >= 2 MDTs"
2286
2287         # LU-2435: skip this quota test if underlying zfs version has not
2288         # supported native dnode accounting
2289         [ "$mds1_FSTYPE" == zfs ] && {
2290                 local F="feature@userobj_accounting"
2291                 local pool=$(zpool_name mds1)
2292                 local feature=$(do_facet mds1 $ZPOOL get -H $F $pool)
2293
2294                 [[ "$feature" != *" active "* ]] &&
2295                         skip "requires zpool with active userobj_accounting"
2296         }
2297
2298         local ilimit=$((1024 * 2)) # inodes
2299         local TESTFILE=$DIR/${tdir}-1/$tfile
2300
2301         setup_quota_test || error "setup quota failed with $?"
2302
2303         # make sure the system is clean
2304         local USED=$(getquota -u $TSTUSR global curinodes)
2305         [ $USED -ne 0 ] && error "Used inode($USED) for user $TSTUSR isn't 0."
2306
2307         # make sure no granted quota on mdt1
2308         set_mdt_qtype $QTYPE || error "enable mdt quota failed"
2309         resetquota -u $TSTUSR
2310         set_mdt_qtype "none" || error "disable mdt quota failed"
2311
2312         local MDTUUID=$(mdtuuid_from_index $((MDSCOUNT - 1)))
2313         USED=$(getquota -u $TSTUSR $MDTUUID ihardlimit)
2314         [ $USED -ne 0 ] && error "limit($USED) on $MDTUUID for user" \
2315                 "$TSTUSR isn't 0."
2316
2317         echo "Stop mds${MDSCOUNT}..."
2318         stop mds${MDSCOUNT}
2319
2320         echo "Enable quota & set quota limit for $TSTUSR"
2321         set_mdt_qtype $QTYPE || error "enable mdt quota failed"
2322         $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I $ilimit $DIR ||
2323                 error "set quota failed"
2324
2325         echo "Start mds${MDSCOUNT}..."
2326         start mds${MDSCOUNT} $(mdsdevname $MDSCOUNT) $MDS_MOUNT_OPTS
2327         quota_init
2328
2329         wait_mdt_reint $QTYPE || error "reintegration failed"
2330
2331         echo "create remote dir"
2332         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/${tdir}-1 ||
2333                 error "create remote dir failed"
2334         chmod 0777 $DIR/${tdir}-1
2335
2336         # hardlimit should have been fetched by slave during global
2337         # reintegration, create will exceed quota
2338         $RUNAS createmany -m $TESTFILE $((ilimit + 1)) &&
2339                 quota_error u $TSTUSR "create succeeded, expect EDQUOT"
2340
2341         $RUNAS unlinkmany $TESTFILE $ilimit || error "unlink files failed"
2342         wait_delete_completed
2343         sync_all_data || true
2344
2345         echo "Stop mds${MDSCOUNT}..."
2346         stop mds${MDSCOUNT}
2347
2348         $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I 0 $DIR ||
2349                 error "clear quota failed"
2350
2351         echo "Start mds${MDSCOUNT}..."
2352         start mds${MDSCOUNT} $(mdsdevname $MDSCOUNT) $MDS_MOUNT_OPTS
2353         quota_init
2354
2355         wait_mdt_reint $QTYPE || error "reintegration failed"
2356
2357         # hardlimit should be cleared on slave during reintegration
2358         $RUNAS createmany -m $TESTFILE $((ilimit + 1)) ||
2359                 quota_error u $TSTUSR "create failed, expect success"
2360
2361         $RUNAS unlinkmany $TESTFILE $((ilimit + 1)) || error "unlink failed"
2362         rmdir $DIR/${tdir}-1 || error "unlink remote dir failed"
2363 }
2364 run_test 7e "Quota reintegration (inode limits)"
2365
2366 # run dbench with quota enabled
2367 test_8() {
2368         local BLK_LIMIT="100g" #100G
2369         local FILE_LIMIT=1000000
2370
2371         setup_quota_test || error "setup quota failed with $?"
2372
2373         set_mdt_qtype $QTYPE || error "enable mdt quota failed"
2374         set_ost_qtype $QTYPE || error "enable ost quota failed"
2375
2376         echo "Set enough high limit for user: $TSTUSR"
2377         $LFS setquota -u $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $DIR ||
2378                 error "set user quota failed"
2379         echo "Set enough high limit for group: $TSTUSR"
2380         $LFS setquota -g $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $DIR ||
2381                 error "set group quota failed"
2382         if is_project_quota_supported; then
2383                 change_project -sp $TSTPRJID $DIR/$tdir
2384                 echo "Set enough high limit for project: $TSTPRJID"
2385                 $LFS setquota -p $TSTPRJID -b 0 \
2386                         -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $DIR ||
2387                         error "set project quota failed"
2388         fi
2389
2390         local duration=""
2391         [ "$SLOW" = "no" ] && duration=" -t 120"
2392         $RUNAS bash rundbench -D $DIR/$tdir 3 $duration ||
2393                 quota_error a $TSTUSR "dbench failed!"
2394
2395         is_project_quota_supported && change_project -C $DIR/$tdir
2396         return 0
2397 }
2398 run_test 8 "Run dbench with quota enabled"
2399
2400 # this check is just for test_9
2401 OST0_MIN=4900000 #4.67G
2402
2403 check_whether_skip () {
2404         local OST0_SIZE=$($LFS df $DIR | awk '/\[OST:0\]/ {print $4}')
2405         log "OST0_SIZE: $OST0_SIZE  required: $OST0_MIN"
2406         if [ $OST0_SIZE -lt $OST0_MIN ]; then
2407                 echo "WARN: OST0 has less than $OST0_MIN free, skip this test."
2408                 return 0
2409         else
2410                 return 1
2411         fi
2412 }
2413
2414 # run for fixing bug10707, it needs a big room. test for 64bit
2415 test_9() {
2416         local filesize=$((1024 * 9 / 2)) # 4.5G
2417
2418         check_whether_skip && return 0
2419
2420         setup_quota_test || error "setup quota failed with $?"
2421
2422         set_ost_qtype "ug" || error "enable ost quota failed"
2423
2424         local TESTFILE="$DIR/$tdir/$tfile-0"
2425         local BLK_LIMIT=100G #100G
2426         local FILE_LIMIT=1000000
2427
2428         echo "Set block limit $BLK_LIMIT bytes to $TSTUSR.$TSTUSR"
2429
2430         log "Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT)" \
2431                 "for user: $TSTUSR"
2432         $LFS setquota -u $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $DIR ||
2433                 error "set user quota failed"
2434
2435         log "Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT)" \
2436                 "for group: $TSTUSR"
2437         $LFS setquota -g $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $DIR ||
2438                 error "set group quota failed"
2439
2440         quota_show_check a u $TSTUSR
2441         quota_show_check a g $TSTUSR
2442
2443         echo "Create test file"
2444         $LFS setstripe $TESTFILE -c 1 -i 0 || error "setstripe $TESTFILE failed"
2445         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
2446
2447         log "Write the big file of 4.5G ..."
2448         $RUNAS $DD of=$TESTFILE count=$filesize ||
2449                 quota_error a $TSTUSR "write 4.5G file failure, expect success"
2450
2451         $SHOW_QUOTA_USER
2452         $SHOW_QUOTA_GROUP
2453
2454         cleanup_quota_test
2455
2456         $SHOW_QUOTA_USER
2457         $SHOW_QUOTA_GROUP
2458 }
2459 run_test 9 "Block limit larger than 4GB (b10707)"
2460
2461 test_10() {
2462         local TESTFILE=$DIR/$tdir/$tfile
2463
2464         setup_quota_test || error "setup quota failed with $?"
2465
2466         # set limit to root user should fail
2467         $LFS setquota -u root -b 100G -B 500G -i 1K -I 1M $DIR &&
2468                 error "set limit for root user successfully, expect failure"
2469         $LFS setquota -g root -b 1T -B 10T -i 5K -I 100M $DIR &&
2470                 error "set limit for root group successfully, expect failure"
2471         $LFS setquota -p 0 -b 1T -B 10T -i 5K -I 100M $DIR &&
2472                 error "set limit for project 0 successfully, expect failure"
2473
2474         # root user can overrun quota
2475         set_ost_qtype "ug" || error "enable ost quota failed"
2476
2477         $LFS setquota -u $TSTUSR -b 0 -B 2M -i 0 -I 0 $DIR ||
2478                 error "set quota failed"
2479         quota_show_check b u $TSTUSR
2480
2481         $LFS setstripe $TESTFILE -c 1 || error "setstripe $TESTFILE failed"
2482         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
2483
2484         runas -u 0 -g 0 $DD of=$TESTFILE count=3 oflag=sync ||
2485                 error "write failure, expect success"
2486 }
2487 run_test 10 "Test quota for root user"
2488
2489 test_11() {
2490         local TESTFILE=$DIR/$tdir/$tfile
2491         setup_quota_test || error "setup quota failed with $?"
2492
2493         set_mdt_qtype "ug" || error "enable mdt quota failed"
2494         $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I 1 $DIR ||
2495                 error "set quota failed"
2496
2497         touch "$TESTFILE"-0 || error "touch $TESTFILE-0 failed"
2498         touch "$TESTFILE"-1 || error "touch $TESTFILE-0 failed"
2499
2500         chown $TSTUSR.$TSTUSR "$TESTFILE"-0 || error "chown $TESTFILE-0 failed"
2501         chown $TSTUSR.$TSTUSR "$TESTFILE"-1 || error "chown $TESTFILE-1 failed"
2502
2503         $SHOW_QUOTA_USER
2504         local USED=$(getquota -u $TSTUSR global curinodes)
2505         [ $USED -ge 2 ] || error "Used inodes($USED) is less than 2"
2506 }
2507 run_test 11 "Chown/chgrp ignores quota"
2508
2509 test_12a() {
2510         [ "$OSTCOUNT" -lt "2" ] && skip "needs >= 2 OSTs"
2511
2512         local blimit=22 # MB
2513         local blk_cnt=$((blimit - 5))
2514         local TESTFILE0="$DIR/$tdir/$tfile"-0
2515         local TESTFILE1="$DIR/$tdir/$tfile"-1
2516
2517         setup_quota_test || error "setup quota failed with $?"
2518
2519         set_ost_qtype "u" || error "enable ost quota failed"
2520         quota_show_check b u $TSTUSR
2521
2522         $LFS setquota -u $TSTUSR -b 0 -B ${blimit}M -i 0 -I 0 $DIR ||
2523                 error "set quota failed"
2524
2525         $LFS setstripe $TESTFILE0 -c 1 -i 0 || error "setstripe $TESTFILE0 failed"
2526         $LFS setstripe $TESTFILE1 -c 1 -i 1 || error "setstripe $TESTFILE1 failed"
2527         chown $TSTUSR.$TSTUSR $TESTFILE0 || error "chown $TESTFILE0 failed"
2528         chown $TSTUSR.$TSTUSR $TESTFILE1 || error "chown $TESTFILE1 failed"
2529
2530         echo "Write to ost0..."
2531         $RUNAS $DD of=$TESTFILE0 count=$blk_cnt oflag=sync ||
2532                 quota_error a $TSTUSR "dd failed"
2533
2534         echo "Write to ost1..."
2535         $RUNAS $DD of=$TESTFILE1 count=$blk_cnt oflag=sync &&
2536                 quota_error a $TSTUSR "dd succeed, expect EDQUOT"
2537
2538         echo "Free space from ost0..."
2539         rm -f $TESTFILE0
2540         wait_delete_completed
2541         sync_all_data || true
2542
2543         echo "Write to ost1 after space freed from ost0..."
2544         $RUNAS $DD of=$TESTFILE1 count=$blk_cnt oflag=sync ||
2545                 quota_error a $TSTUSR "rebalancing failed"
2546 }
2547 run_test 12a "Block quota rebalancing"
2548
2549 test_12b() {
2550         [ "$MDSCOUNT" -lt "2" ] && skip "needs >= 2 MDTs"
2551
2552         local ilimit=$((1024 * 2)) # inodes
2553         local TESTFILE0=$DIR/$tdir/$tfile
2554         local TESTFILE1=$DIR/${tdir}-1/$tfile
2555
2556         setup_quota_test || error "setup quota failed with $?"
2557
2558         $LFS mkdir -i 1 $DIR/${tdir}-1 || error "create remote dir failed"
2559         chmod 0777 $DIR/${tdir}-1
2560
2561         set_mdt_qtype "u" || error "enable mdt quota failed"
2562         quota_show_check f u $TSTUSR
2563
2564         $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I $ilimit $DIR ||
2565                 error "set quota failed"
2566
2567         echo "Create $ilimit files on mdt0..."
2568         $RUNAS createmany -m $TESTFILE0 $ilimit ||
2569                 quota_error u $TSTUSR "create failed, but expect success"
2570
2571         echo "Create files on mdt1..."
2572         $RUNAS createmany -m $TESTFILE1 1 &&
2573                 quota_error a $TSTUSR "create succeeded, expect EDQUOT"
2574
2575         echo "Free space from mdt0..."
2576         $RUNAS unlinkmany $TESTFILE0 $ilimit || error "unlink mdt0 files failed"
2577         wait_delete_completed
2578         sync_all_data || true
2579
2580         echo "Create files on mdt1 after space freed from mdt0..."
2581         $RUNAS createmany -m $TESTFILE1 $((ilimit / 2)) ||
2582                 quota_error a $TSTUSR "rebalancing failed"
2583
2584         $RUNAS unlinkmany $TESTFILE1 $((ilimit / 2)) ||
2585                 error "unlink mdt1 files failed"
2586         rmdir $DIR/${tdir}-1 || error "unlink remote dir failed"
2587 }
2588 run_test 12b "Inode quota rebalancing"
2589
2590 test_13(){
2591         local TESTFILE=$DIR/$tdir/$tfile
2592         # the name of lwp on ost1 name is MDT0000-lwp-OST0000
2593         local procf="ldlm.namespaces.*MDT0000-lwp-OST0000.lru_size"
2594
2595         setup_quota_test || error "setup quota failed with $?"
2596
2597         set_ost_qtype "u" || error "enable ost quota failed"
2598         quota_show_check b u $TSTUSR
2599
2600         $LFS setquota -u $TSTUSR -b 0 -B 10M -i 0 -I 0 $DIR ||
2601                 error "set quota failed"
2602         $LFS setstripe $TESTFILE -c 1 -i 0 || error "setstripe $TESTFILE failed"
2603         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
2604
2605         # clear the locks in cache first
2606         do_facet ost1 $LCTL set_param -n $procf=clear
2607         local nlock=$(do_facet ost1 $LCTL get_param -n $procf)
2608         [ $nlock -eq 0 ] || error "$nlock cached locks"
2609
2610         # write to acquire the per-ID lock
2611         $RUNAS $DD of=$TESTFILE count=1 oflag=sync ||
2612                 quota_error a $TSTUSR "dd failed"
2613
2614         nlock=$(do_facet ost1 $LCTL get_param -n $procf)
2615         [ $nlock -eq 1 ] || error "lock count($nlock) isn't 1"
2616
2617         # clear quota doesn't trigger per-ID lock cancellation
2618         resetquota -u $TSTUSR
2619         nlock=$(do_facet ost1 $LCTL get_param -n $procf)
2620         [ $nlock -eq 1 ] || error "per-ID lock is lost on quota clear"
2621
2622         # clear the per-ID lock
2623         do_facet ost1 $LCTL set_param -n $procf=clear
2624         nlock=$(do_facet ost1 $LCTL get_param -n $procf)
2625         [ $nlock -eq 0 ] || error "per-ID lock isn't cleared"
2626
2627         # spare quota should be released
2628         local OSTUUID=$(ostuuid_from_index 0)
2629         local limit=$(getquota -u $TSTUSR $OSTUUID bhardlimit)
2630         local space=$(getquota -u $TSTUSR $OSTUUID curspace)
2631         [ $limit -le $space ] ||
2632                 error "spare quota isn't released, limit:$limit, space:$space"
2633 }
2634 run_test 13 "Cancel per-ID lock in the LRU list"
2635
2636 test_14()
2637 {
2638         local qpool="qpool1"
2639         local tfile1="$DIR/$tdir/$tfile-0"
2640
2641         mds_supports_qp
2642         setup_quota_test || error "setup quota failed with $?"
2643         # enable ost quota
2644         set_ost_qtype $QTYPE || error "enable ost quota failed"
2645
2646         $LFS setquota -u $TSTUSR -b 0 -B 100M -i 0 -I 0 $DIR ||
2647                 error "set user quota failed"
2648         pool_add $qpool || error "pool_add failed"
2649         pool_add_targets $qpool 0 ||
2650                 error "pool_add_targets failed"
2651         $LFS setstripe -p $qpool $DIR/$tdir || error "cannot set stripe"
2652         $LFS setquota -u $TSTUSR -B 30M --pool $qpool $DIR ||
2653                 error "set user quota failed"
2654
2655         # don't care about returned value
2656         $RUNAS $DD of=$tfile1 count=10 oflag=direct
2657
2658         echo "Stop ost1..."
2659         stop ost1
2660         $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I 0 $DIR ||
2661                 error "set user quota failed"
2662
2663         # no panic after removing OST0000 from the pool
2664         pool_remove_target $qpool 0
2665         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "start ost1 failed"
2666 }
2667 run_test 14 "check panic in qmt_site_recalc_cb"
2668
2669 test_15(){
2670         local LIMIT=$((24 * 1024 * 1024 * 1024 * 1024)) # 24 TB
2671
2672         wait_delete_completed
2673         sync_all_data || true
2674
2675         # test for user
2676         $LFS setquota -u $TSTUSR -b 0 -B $LIMIT -i 0 -I 0 $DIR ||
2677                 error "set user quota failed"
2678         local TOTAL_LIMIT=$(getquota -u $TSTUSR global bhardlimit)
2679         [ $TOTAL_LIMIT -eq $LIMIT ] ||
2680                 error "(user) limit:$TOTAL_LIMIT, expect:$LIMIT, failed!"
2681         resetquota -u $TSTUSR
2682
2683         # test for group
2684         $LFS setquota -g $TSTUSR -b 0 -B $LIMIT -i 0 -I 0 $DIR ||
2685                 error "set group quota failed"
2686         TOTAL_LIMIT=$(getquota -g $TSTUSR global bhardlimit)
2687         [ $TOTAL_LIMIT -eq $LIMIT ] ||
2688                 error "(group) limits:$TOTAL_LIMIT, expect:$LIMIT, failed!"
2689         resetquota -g $TSTUSR
2690 }
2691 run_test 15 "Set over 4T block quota"
2692
2693 test_16a()
2694 {
2695         (( $CLIENT_VERSION < $(version_code 2.14.55) )) &&
2696                 skip "Not supported Lustre client before 2.14.55"
2697
2698         setup_quota_test || error "setup quota failed with $?"
2699
2700         $LFS setquota -u $TSTUSR -B 500M -I 10K $MOUNT ||
2701                 error "failed to set quota for user $TSTUSR"
2702         $LFS setquota -g $TSTUSR -B 500M -I 10K $MOUNT ||
2703                 error "failed to set quota for group $TSTUSR"
2704
2705         $RUNAS $DD of=$DIR/$tdir/$tfile bs=1M count=50 ||
2706                 quota_error u $TSTUSR "write failure"
2707
2708         $LFS quota -u $TSTUSR $MOUNT ||
2709                 quota_error u $TSTUSR "failed to get quota"
2710
2711         local OSC=$($LCTL dl | grep OST0000-osc-[^M] | awk '{print $4}')
2712
2713         $LCTL --device %$OSC deactivate
2714         stack_trap "$LCTL --device %$OSC activate"
2715
2716         $LFS quota -v -u $TSTUSR $MOUNT ||
2717                 quota_error u $TSTUSR "failed to get quota after deactivate OSC"
2718         $LFS quota -v -g $TSTUSR $MOUNT ||
2719                 quota_error g $TSTUSR "failed to get quota after deactivate OSC"
2720
2721         (( $MDSCOUNT > 1 )) || return 0
2722
2723         local MDC=$($LCTL dl | grep MDT0001-mdc-[^M] | awk '{print $4}')
2724
2725         $LCTL --device %$MDC deactivate
2726         stack_trap "$LCTL --device %$MDC activate"
2727
2728         $LFS quota -v -u $TSTUSR $MOUNT ||
2729                 quota_error u $TSTUSR "failed to get quota after deactivate MDC"
2730         $LFS quota -v -g $TSTUSR $MOUNT ||
2731                 quota_error g $TSTUSR "failed to get quota after deactivate OSC"
2732 }
2733 run_test 16a "lfs quota should skip the inactive MDT/OST"
2734
2735 cleanup_16b()
2736 {
2737         stopall
2738         formatall
2739         setupall
2740 }
2741
2742 test_16b()
2743 {
2744         (( $CLIENT_VERSION < $(version_code 2.14.55) )) &&
2745                 skip "Not supported Lustre client before 2.14.55"
2746
2747         (( $MDSCOUNT >= 3 )) || skip "needs >= 3 MDTs"
2748
2749         stopall
2750         if ! combined_mgs_mds ; then
2751                 format_mgs
2752                 start_mgs
2753         fi
2754
2755         add mds1 $(mkfs_opts mds1 $(mdsdevname 1)) --index=0 --reformat \
2756                 $(mdsdevname 1) $(mdsvdevname 1)
2757         add mds2 $(mkfs_opts mds2 $(mdsdevname 2)) --index=1 --reformat \
2758                 $(mdsdevname 2) $(mdsvdevname 2)
2759         add mds3 $(mkfs_opts mds3 $(mdsdevname 3)) --index=100 --reformat \
2760                 $(mdsdevname 3) $(mdsvdevname 3)
2761
2762         add ost1 $(mkfs_opts ost1 $(ostdevname 1)) --index=0 --reformat \
2763                 $(ostdevname 1) $(ostvdevname 1)
2764         add ost2 $(mkfs_opts ost2 $(ostdevname 2)) --index=100 --reformat \
2765                 $(ostdevname 2) $(ostvdevname 2)
2766
2767         stack_trap cleanup_16b
2768
2769         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS || error "MDT1 start failed"
2770         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS || error "MDT2 start failed"
2771         start mds3 $(mdsdevname 3) $MDS_MOUNT_OPTS || error "MDT3 start failed"
2772         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "OST1 start failed"
2773         start ost2 $(ostdevname 2) $OST_MOUNT_OPTS || error "OST2 start failed"
2774
2775         mount_client $MOUNT || error "Unable to mount client"
2776
2777         setup_quota_test || error "setup quota failed with $?"
2778
2779         $LFS setquota -u $TSTUSR -B 100M -I 10K $MOUNT ||
2780                 error "failed to set quota for user $TSTUSR"
2781         $LFS setquota -g $TSTUSR -B 100M -I 10K $MOUNT ||
2782                 error "failed to set quota for group $TSTUSR"
2783
2784         $RUNAS $DD of=$DIR/$tdir/$tfile bs=1M count=10 ||
2785                 quota_error u $TSTUSR "write failure"
2786
2787         cnt=$($LFS quota -v -u $TSTUSR $MOUNT | grep -ce "^$FSNAME-[MD|OS]T*")
2788         [ $cnt -le 5 ] || quota_error u $TSTUSR "failed to get user quota"
2789         cnt=$($LFS quota -v -g $TSTUSR $MOUNT | grep -ce "^$FSNAME-[MD|OS]T*")
2790         [ $cnt -le 5 ] || quota_error g $TSTUSR "failed to get group quota"
2791 }
2792 run_test 16b "lfs quota should skip the nonexistent MDT/OST"
2793
2794 test_17sub() {
2795         local err_code=$1
2796         local BLKS=1    # 1M less than limit
2797         local TESTFILE=$DIR/$tdir/$tfile
2798
2799         setup_quota_test || error "setup quota failed with $?"
2800
2801         # make sure the system is clean
2802         local USED=$(getquota -u $TSTUSR global curspace)
2803         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
2804
2805         set_ost_qtype "ug" || error "enable ost quota failed"
2806         # make sure no granted quota on ost
2807         resetquota -u $TSTUSR
2808         $LFS setquota -u $TSTUSR -b 0 -B 10M -i 0 -I 0 $DIR ||
2809                 error "set quota failed"
2810
2811         quota_show_check b u $TSTUSR
2812
2813         #define OBD_FAIL_QUOTA_RECOVERABLE_ERR 0xa04
2814         lustre_fail mds 0xa04 $err_code
2815
2816         # write in background
2817         $RUNAS $DD of=$TESTFILE count=$BLKS oflag=direct &
2818         local DDPID=$!
2819
2820         sleep 2
2821         # write should be blocked and never finished
2822         if ! ps -p $DDPID  > /dev/null 2>&1; then
2823                 lustre_fail mds 0 0
2824                 quota_error u $TSTUSR "write finished incorrectly!"
2825         fi
2826
2827         lustre_fail mds 0 0
2828
2829         local count=0
2830         local timeout=30
2831         while [ true ]; do
2832                 if ! ps -p ${DDPID} > /dev/null 2>&1; then break; fi
2833                 count=$((count+1))
2834                 if [ $count -gt $timeout ]; then
2835                         quota_error u $TSTUSR "dd is not finished!"
2836                 fi
2837                 sleep 1
2838         done
2839
2840         sync; sync_all_data || true
2841
2842         USED=$(getquota -u $TSTUSR global curspace)
2843         [ $USED -ge $((BLKS * 1024)) ] || quota_error u $TSTUSR \
2844                 "Used space(${USED}K) is less than ${BLKS}M"
2845
2846         cleanup_quota_test
2847 }
2848
2849 # DQACQ return recoverable error
2850 test_17() {
2851         echo "DQACQ return -ENOLCK"
2852         #define ENOLCK  37
2853         test_17sub 37 || error "Handle -ENOLCK failed"
2854
2855         echo "DQACQ return -EAGAIN"
2856         #define EAGAIN  11
2857         test_17sub 11 || error "Handle -EAGAIN failed"
2858
2859         echo "DQACQ return -ETIMEDOUT"
2860         #define ETIMEDOUT 110
2861         test_17sub 110 || error "Handle -ETIMEDOUT failed"
2862
2863         echo "DQACQ return -ENOTCONN"
2864         #define ENOTCONN 107
2865         test_17sub 107 || error "Handle -ENOTCONN failed"
2866 }
2867
2868 run_test 17 "DQACQ return recoverable error"
2869
2870 test_18_sub () {
2871         local io_type=$1
2872         local blimit=200 # MB
2873         local TESTFILE="$DIR/$tdir/$tfile"
2874
2875         setup_quota_test || error "setup quota failed with $?"
2876
2877         set_ost_qtype "u" || error "enable ost quota failed"
2878         log "User quota (limit: $blimit)"
2879         $LFS setquota -u $TSTUSR -b 0 -B ${blimit}M -i 0 -I 0 $MOUNT ||
2880                 error "set quota failed"
2881         quota_show_check b u $TSTUSR
2882
2883         $LFS setstripe $TESTFILE -i 0 -c 1 || error "setstripe $TESTFILE failed"
2884         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
2885
2886         local timeout=$(sysctl -n lustre.timeout)
2887
2888         if [ $io_type = "directio" ]; then
2889                 log "Write 100M (directio) ..."
2890                 $RUNAS $DD of=$TESTFILE count=100 oflag=direct &
2891         else
2892                 log "Write 100M (buffered) ..."
2893                 $RUNAS $DD of=$TESTFILE count=100 &
2894         fi
2895         local DDPID=$!
2896
2897         replay_barrier $SINGLEMDS
2898         log "Fail mds for $((2 * timeout)) seconds"
2899         fail $SINGLEMDS $((2 * timeout))
2900
2901         local count=0
2902         if at_is_enabled; then
2903                 timeout=$(at_max_get mds)
2904         else
2905                 timeout=$(lctl get_param -n timeout)
2906         fi
2907
2908         while [ true ]; do
2909                 if ! ps -p ${DDPID} > /dev/null 2>&1; then break; fi
2910                 if [ $((++count % (2 * timeout) )) -eq 0 ]; then
2911                         log "it took $count second"
2912                 fi
2913                 sleep 1
2914         done
2915
2916         log "(dd_pid=$DDPID, time=$count, timeout=$timeout)"
2917         sync
2918         cancel_lru_locks mdc
2919         cancel_lru_locks osc
2920         $SHOW_QUOTA_USER
2921
2922         local testfile_size=$(stat -c %s $TESTFILE)
2923         if [ $testfile_size -ne $((BLK_SZ * 1024 * 100)) ] ; then
2924                 quota_error u $TSTUSR "expect $((BLK_SZ * 1024 * 100))," \
2925                         "got ${testfile_size}. Verifying file failed!"
2926         fi
2927         cleanup_quota_test
2928 }
2929
2930 # test when mds does failover, the ost still could work well
2931 # this test shouldn't trigger watchdog b=14840
2932 test_18() {
2933         # Clear dmesg so watchdog is not triggered by previous
2934         # test output
2935         do_facet ost1 dmesg -c > /dev/null
2936
2937         test_18_sub normal
2938         test_18_sub directio
2939
2940         # check if watchdog is triggered
2941         do_facet ost1 dmesg > $TMP/lustre-log-${TESTNAME}.log
2942         local watchdog=$(awk '/[Ss]ervice thread pid/ && /was inactive/ \
2943                         { print; }' $TMP/lustre-log-${TESTNAME}.log)
2944         [ -z "$watchdog" ] || error "$watchdog"
2945         rm -f $TMP/lustre-log-${TESTNAME}.log
2946 }
2947 run_test 18 "MDS failover while writing, no watchdog triggered (b14840)"
2948
2949 test_19() {
2950         local blimit=5 # MB
2951         local TESTFILE=$DIR/$tdir/$tfile
2952
2953         setup_quota_test || error "setup quota failed with $?"
2954
2955         set_ost_qtype $QTYPE || error "enable ost quota failed"
2956
2957         # bind file to a single OST
2958         $LFS setstripe -c 1 $TESTFILE || error "setstripe $TESTFILE failed"
2959         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
2960
2961         echo "Set user quota (limit: ${blimit}M)"
2962         $LFS setquota -u $TSTUSR -b 0 -B ${blimit}M -i 0 -I 0 $MOUNT ||
2963                 error "set user quota failed"
2964         quota_show_check b u $TSTUSR
2965         echo "Update quota limits"
2966         $LFS setquota -u $TSTUSR -b 0 -B ${blimit}M -i 0 -I 0 $MOUNT ||
2967                 error "set group quota failed"
2968         quota_show_check b u $TSTUSR
2969
2970         # first wirte might be cached
2971         $RUNAS $DD of=$TESTFILE count=$((blimit + 1))
2972         cancel_lru_locks osc
2973         $SHOW_QUOTA_USER
2974         $RUNAS $DD of=$TESTFILE count=$((blimit + 1)) seek=$((blimit + 1)) &&
2975                 quota_error u $TSTUSR "Write success, expect failure"
2976         $SHOW_QUOTA_USER
2977 }
2978 run_test 19 "Updating admin limits doesn't zero operational limits(b14790)"
2979
2980 test_20() { # b15754
2981         local LSTR=(2g 1t 4k 3m) # limits strings
2982         # limits values
2983         local LVAL=($((2*1024*1024)) $((1*1024*1024*1024)) $((4*1024)) \
2984                     $((3*1024*1024)))
2985
2986         resetquota -u $TSTUSR
2987
2988         $LFS setquota -u $TSTUSR --block-softlimit ${LSTR[0]} \
2989                 $MOUNT || error "could not set quota limits"
2990         $LFS setquota -u $TSTUSR --block-hardlimit ${LSTR[1]} \
2991                                 --inode-softlimit ${LSTR[2]} \
2992                                 --inode-hardlimit ${LSTR[3]} \
2993                                 $MOUNT || error "could not set quota limits"
2994
2995         [ "$(getquota -u $TSTUSR global bsoftlimit)" = "${LVAL[0]}" ] ||
2996                 error "bsoftlimit was not set properly"
2997         [ "$(getquota -u $TSTUSR global bhardlimit)" = "${LVAL[1]}" ] ||
2998                 error "bhardlimit was not set properly"
2999         [ "$(getquota -u $TSTUSR global isoftlimit)" = "${LVAL[2]}" ] ||
3000                 error "isoftlimit was not set properly"
3001         [ "$(getquota -u $TSTUSR global ihardlimit)" = "${LVAL[3]}" ] ||
3002                 error "ihardlimit was not set properly"
3003
3004         resetquota -u $TSTUSR
3005 }
3006 run_test 20 "Test if setquota specifiers work properly (b15754)"
3007
3008 test_21_sub() {
3009         local testfile=$1
3010         local blk_number=$2
3011         local seconds=$3
3012
3013         local time=$(($(date +%s) + seconds))
3014         while [ $(date +%s) -lt $time ]; do
3015                 $RUNAS $DD of=$testfile count=$blk_number > /dev/null 2>&1
3016         done
3017 }
3018
3019 # run for fixing bug16053, setquota shouldn't fail when writing and
3020 # deleting are happening
3021 test_21() {
3022         local TESTFILE="$DIR/$tdir/$tfile"
3023         local BLIMIT=10 # 10G
3024         local ILIMIT=1000000
3025
3026         setup_quota_test || error "setup quota failed with $?"
3027
3028         set_ost_qtype $QTYPE || error "Enable ost quota failed"
3029
3030         log "Set limit(block:${BLIMIT}G; file:$ILIMIT) for user: $TSTUSR"
3031         $LFS setquota -u $TSTUSR -b 0 -B ${BLIMIT}G -i 0 -I $ILIMIT $MOUNT ||
3032                 error "set user quota failed"
3033         log "Set limit(block:${BLIMIT}G; file:$ILIMIT) for group: $TSTUSR"
3034         $LFS setquota -g $TSTUSR -b 0 -B $BLIMIT -i 0 -I $ILIMIT $MOUNT ||
3035                 error "set group quota failed"
3036         if is_project_quota_supported; then
3037                 log "Set limit(block:${BLIMIT}G; file:$LIMIT) for " \
3038                         "project: $TSTPRJID"
3039                 $LFS setquota -p $TSTPRJID -b 0 -B $BLIMIT -i 0 -I $ILIMIT \
3040                          $MOUNT || error "set project quota failed"
3041         fi
3042
3043         # repeat writing on a 1M file
3044         test_21_sub ${TESTFILE}_1 1 30 &
3045         local DDPID1=$!
3046         # repeat writing on a 128M file
3047         test_21_sub ${TESTFILE}_2 128 30 &
3048         local DDPID2=$!
3049
3050         local time=$(($(date +%s) + 30))
3051         local i=1
3052         while [ $(date +%s) -lt $time ]; do
3053                 log "Set quota for $i times"
3054                 $LFS setquota -u $TSTUSR -b 0 -B "$((BLIMIT + i))G" -i 0 \
3055                         -I $((ILIMIT + i)) $MOUNT ||
3056                                 error "Set user quota failed"
3057                 $LFS setquota -g $TSTUSR -b 0 -B "$((BLIMIT + i))G" -i 0 \
3058                         -I $((ILIMIT + i)) $MOUNT ||
3059                                 error "Set group quota failed"
3060                 if is_project_quota_supported; then
3061                         $LFS setquota -p $TSTPRJID -b 0 -B \
3062                         "$((BLIMIT + i))G"  -i 0 -I $((ILIMIT + i)) $MOUNT ||
3063                                 error "Set project quota failed"
3064                 fi
3065                 i=$((i+1))
3066                 sleep 1
3067         done
3068
3069         local count=0
3070         while [ true ]; do
3071                 if ! ps -p ${DDPID1} > /dev/null 2>&1; then break; fi
3072                 count=$((count+1))
3073                 if [ $count -gt 60 ]; then
3074                         quota_error a $TSTUSR "dd should be finished!"
3075                 fi
3076                 sleep 1
3077         done
3078         echo "(dd_pid=$DDPID1, time=$count)successful"
3079
3080         count=0
3081         while [ true ]; do
3082                 if ! ps -p ${DDPID2} > /dev/null 2>&1; then break; fi
3083                 count=$((count+1))
3084                 if [ $count -gt 60 ]; then
3085                         quota_error a $TSTUSR "dd should be finished!"
3086                 fi
3087                 sleep 1
3088         done
3089         echo "(dd_pid=$DDPID2, time=$count)successful"
3090 }
3091 run_test 21 "Setquota while writing & deleting (b16053)"
3092
3093 # enable/disable quota enforcement permanently
3094 test_22() {
3095         echo "Set both mdt & ost quota type as ug"
3096         local qtype="ug"
3097         is_project_quota_supported && qtype=$QTYPE
3098         set_mdt_qtype $qtype || error "enable mdt quota failed"
3099         set_ost_qtype $qtype || error "enable ost quota failed"
3100
3101         echo "Restart..."
3102         stopall || error "failed to stopall (1)"
3103         mount
3104         setupall
3105
3106         echo "Verify if quota is enabled"
3107         local qtype1=$(mdt_quota_type)
3108         [ $qtype1 != $qtype ] && error "mdt quota setting is lost"
3109         qtype=$(ost_quota_type)
3110         [ $qtype1 != $qtype ] && error "ost quota setting is lost"
3111
3112         echo "Set both mdt & ost quota type as none"
3113         set_mdt_qtype "none" || error "disable mdt quota failed"
3114         set_ost_qtype "none" || error "disable ost quota failed"
3115
3116         echo "Restart..."
3117         stopall || error "failed to stopall (2)"
3118         mount
3119         setupall
3120         quota_init
3121
3122         echo "Verify if quota is disabled"
3123         qtype=$(mdt_quota_type)
3124         [ $qtype != "none" ] && error "mdt quota setting is lost"
3125         qtype=$(ost_quota_type)
3126         [ $qtype != "none" ] && error "ost quota setting is lost"
3127
3128         return 0
3129 }
3130 run_test 22 "enable/disable quota by 'lctl conf_param/set_param -P'"
3131
3132 test_23_sub() {
3133         local TESTFILE="$DIR/$tdir/$tfile"
3134         local LIMIT=$1
3135
3136         setup_quota_test || error "setup quota failed with $?"
3137
3138         set_ost_qtype $QTYPE || error "Enable ost quota failed"
3139
3140         # test for user
3141         log "User quota (limit: $LIMIT MB)"
3142         $LFS setquota -u $TSTUSR -b 0 -B "$LIMIT"M -i 0 -I 0 $DIR ||
3143                 error "set quota failed"
3144         quota_show_check b u $TSTUSR
3145
3146         $LFS setstripe $TESTFILE -c 1 -i 0 || error "setstripe $TESTFILE failed"
3147         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
3148
3149         log "Step1: trigger EDQUOT with O_DIRECT"
3150         log "Write half of file"
3151         $RUNAS $DD of=$TESTFILE count=$((LIMIT/2)) oflag=direct ||
3152                 quota_error u $TSTUSR "(1) Write failure, expect success." \
3153                         "limit=$LIMIT"
3154         log "Write out of block quota ..."
3155         $RUNAS $DD of=$TESTFILE count=$((LIMIT/2 + 1)) seek=$((LIMIT/2)) \
3156                 oflag=direct conv=notrunc &&
3157                 quota_error u $TSTUSR "(2) Write success, expect EDQUOT." \
3158                         "limit=$LIMIT"
3159         log "Step1: done"
3160
3161         log "Step2: rewrite should succeed"
3162         $RUNAS $DD of=$TESTFILE count=1 oflag=direct conv=notrunc||
3163                 quota_error u $TSTUSR "(3) Write failure, expect success." \
3164                         "limit=$LIMIT"
3165         log "Step2: done"
3166
3167         cleanup_quota_test
3168
3169         local OST0_UUID=$(ostuuid_from_index 0)
3170         local OST0_QUOTA_USED=$(getquota -u $TSTUSR $OST0_UUID curspace)
3171         [ $OST0_QUOTA_USED -ne 0 ] &&
3172                 ($SHOW_QUOTA_USER; \
3173                 quota_error u $TSTUSR "quota isn't released")
3174         $SHOW_QUOTA_USER
3175 }
3176
3177 test_23() {
3178         [ "$ost1_FSTYPE" == zfs ] &&
3179                 skip "Overwrite in place is not guaranteed to be " \
3180                 "space neutral on ZFS"
3181
3182         local OST0_MIN=$((6 * 1024)) # 6MB, extra space for meta blocks.
3183         check_whether_skip && return 0
3184         log "run for 4MB test file"
3185         test_23_sub 4
3186
3187         OST0_MIN=$((60 * 1024)) # 60MB, extra space for meta blocks.
3188         check_whether_skip && return 0
3189         log "run for 40MB test file"
3190         test_23_sub 40
3191 }
3192 run_test 23 "Quota should be honored with directIO (b16125)"
3193
3194 test_24() {
3195         local blimit=5 # MB
3196         local TESTFILE="$DIR/$tdir/$tfile"
3197
3198         setup_quota_test || error "setup quota failed with $?"
3199
3200         set_ost_qtype $QTYPE || error "enable ost quota failed"
3201
3202         # bind file to a single OST
3203         $LFS setstripe -c 1 $TESTFILE || error "setstripe $TESTFILE failed"
3204         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
3205
3206         echo "Set user quota (limit: ${blimit}M)"
3207         $LFS setquota -u $TSTUSR -b 0 -B "$blimit"M -i 0 -I 0 $MOUNT ||
3208                 error "set quota failed"
3209
3210         # overrun quota by root user
3211         runas -u 0 -g 0 $DD of=$TESTFILE count=$((blimit + 1)) ||
3212                 error "write failure, expect success"
3213         cancel_lru_locks osc
3214         sync_all_data || true
3215
3216         $SHOW_QUOTA_USER | grep '*' || error "no matching *"
3217 }
3218 run_test 24 "lfs draws an asterix when limit is reached (b16646)"
3219
3220 test_27a() { # b19612
3221         $LFS quota $TSTUSR $DIR &&
3222                 error "lfs succeeded with no type, but should have failed"
3223         $LFS setquota $TSTUSR $DIR &&
3224                 error "lfs succeeded with no type, but should have failed"
3225         return 0
3226 }
3227 run_test 27a "lfs quota/setquota should handle wrong arguments (b19612)"
3228
3229 test_27b() { # b20200
3230         $LFS setquota -u $TSTID -b 1000 -B 1000 -i 1000 -I 1000 $DIR ||
3231                 error "lfs setquota failed with uid argument"
3232         $LFS setquota -g $TSTID -b 1000 -B 1000 -i 1000 -I 1000 $DIR ||
3233                 error "lfs stequota failed with gid argument"
3234         if is_project_quota_supported; then
3235                 $LFS setquota -p $TSTPRJID -b 1000 -B 1000 -i 1000 -I \
3236                         1000 $DIR || error \
3237                                 "lfs stequota failed with projid argument"
3238         fi
3239         $SHOW_QUOTA_USERID || error "lfs quota failed with uid argument"
3240         $SHOW_QUOTA_GROUPID || error "lfs quota failed with gid argument"
3241         if is_project_quota_supported; then
3242                 $SHOW_QUOTA_PROJID ||
3243                         error "lfs quota failed with projid argument"
3244                 resetquota_one -p $TSTPRJID
3245         fi
3246         resetquota -u $TSTID
3247         resetquota -g $TSTID
3248         return 0
3249 }
3250 run_test 27b "lfs quota/setquota should handle user/group/project ID (b20200)"
3251
3252 test_27c() {
3253         local limit
3254
3255         $LFS setquota -u $TSTID -b 30M -B 3T $DIR ||
3256                 error "lfs setquota failed"
3257
3258         limit=$($LFS quota -u $TSTID -v -h $DIR | grep $DIR | awk '{print $3}')
3259         [ $limit != "30M" ] && error "softlimit $limit isn't human-readable"
3260         limit=$($LFS quota -u $TSTID -v -h $DIR | grep $DIR | awk '{print $4}')
3261         [ $limit != "3T" ] && error "hardlimit $limit isn't human-readable"
3262
3263         $LFS setquota -u $TSTID -b 1500M -B 18500G $DIR ||
3264                 error "lfs setquota for $TSTID failed"
3265
3266         limit=$($LFS quota -u $TSTID -v -h $DIR | grep $DIR | awk '{print $3}')
3267         [ $limit != "1.465G" ] && error "wrong softlimit $limit"
3268         limit=$($LFS quota -u $TSTID -v -h $DIR | grep $DIR | awk '{print $4}')
3269         [ $limit != "18.07T" ] && error "wrong hardlimit $limit"
3270
3271         $LFS quota -u $TSTID -v -h $DIR | grep -q "Total allocated" ||
3272                 error "total allocated inode/block limit not printed"
3273
3274         resetquota -u $TSTUSR
3275 }
3276 run_test 27c "lfs quota should support human-readable output"
3277
3278 test_27d() {
3279         local softlimit=1.5
3280         local hardlimit=2.3
3281         local limit
3282
3283         $LFS setquota -u $TSTID -b ${softlimit}p -B ${hardlimit}P $DIR ||
3284                 error "set fraction block limit failed"
3285         limit=$($LFS quota -u $TSTID -h $DIR | grep $DIR | awk '{print $3}')
3286         [ $limit == ${softlimit}P ] || error "get fraction softlimit failed"
3287         limit=$($LFS quota -u $TSTID -h $DIR | grep $DIR | awk '{print $4}')
3288         [ $limit == ${hardlimit}P ] || error "get fraction hardlimit failed"
3289
3290         resetquota -u $TSTUSR
3291 }
3292 run_test 27d "lfs setquota should support fraction block limit"
3293
3294 test_30() {
3295         local LIMIT=4 # MB
3296         local TESTFILE="$DIR/$tdir/$tfile"
3297         local GRACE=10
3298
3299         setup_quota_test || error "setup quota failed with $?"
3300
3301         set_ost_qtype "u" || error "enable ost quota failed"
3302
3303         $LFS setstripe $TESTFILE -i 0 -c 1 || error "setstripe $TESTFILE failed"
3304         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
3305
3306         $LFS setquota -t -u --block-grace $GRACE --inode-grace \
3307                 $MAX_IQ_TIME $DIR || error "set grace time failed"
3308         $LFS setquota -u $TSTUSR -b ${LIMIT}M -B 0 -i 0 -I 0 $DIR ||
3309                 error "set quota failed"
3310         $RUNAS $DD of=$TESTFILE count=$((LIMIT * 2)) || true
3311         cancel_lru_locks osc
3312         sleep $GRACE
3313         $LFS setquota -u $TSTUSR -B 0 $DIR || error "clear quota failed"
3314         # over-quota flag has not yet settled since we do not trigger async
3315         # events based on grace time period expiration
3316         $SHOW_QUOTA_USER
3317         $RUNAS $DD of=$TESTFILE conv=notrunc oflag=append count=4 || true
3318         cancel_lru_locks osc
3319         # now over-quota flag should be settled and further writes should fail
3320         $SHOW_QUOTA_USER
3321         $RUNAS $DD of=$TESTFILE conv=notrunc oflag=append count=4 &&
3322                 error "grace times were reset"
3323         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
3324                 $MAX_IQ_TIME $DIR || error "restore grace time failed"
3325 }
3326 run_test 30 "Hard limit updates should not reset grace times"
3327
3328 # basic usage tracking for user & group
3329 test_33() {
3330         local INODES=10 # files
3331         local BLK_CNT=2 # MB each
3332         local TOTAL_BLKS=$((INODES * BLK_CNT * 1024))
3333
3334         setup_quota_test || error "setup quota failed with $?"
3335
3336         # make sure the system is clean
3337         local USED=$(getquota -u $TSTID global curspace)
3338         [ $USED -ne 0 ] &&
3339                 error "Used space ($USED) for user $TSTID isn't 0."
3340         USED=$(getquota -g $TSTID global curspace)
3341         [ $USED -ne 0 ] &&
3342                 error "Used space ($USED) for group $TSTID isn't 0."
3343         if is_project_quota_supported; then
3344                 USED=$(getquota -p $TSTPRJID global curspace)
3345                 [ $USED -ne 0 ] && error \
3346                         "Used space ($USED) for project $TSTPRJID isn't 0."
3347         fi
3348
3349         echo "Write files..."
3350         for i in $(seq 0 $INODES); do
3351                 $RUNAS $DD of=$DIR/$tdir/$tfile-$i count=$BLK_CNT 2>/dev/null ||
3352                         error "write failed"
3353                         is_project_quota_supported &&
3354                                 change_project -p $TSTPRJID $DIR/$tdir/$tfile-$i
3355                 echo "Iteration $i/$INODES completed"
3356         done
3357         cancel_lru_locks osc
3358
3359         echo "Wait for setattr on objects finished..."
3360         wait_delete_completed
3361
3362         sync; sync_all_data || true
3363
3364         echo "Verify disk usage after write"
3365         USED=$(getquota -u $TSTID global curspace)
3366         [ $USED -lt $TOTAL_BLKS ] &&
3367                 error "Used space for user $TSTID:$USED, expected:$TOTAL_BLKS"
3368         USED=$(getquota -g $TSTID global curspace)
3369         [ $USED -lt $TOTAL_BLKS ] &&
3370                 error "Used space for group $TSTID:$USED, expected:$TOTAL_BLKS"
3371         if is_project_quota_supported; then
3372                 USED=$(getquota -p $TSTPRJID global curspace)
3373                 [ $USED -lt $TOTAL_BLKS ] && error \
3374                         "Used space for project $TSTPRJID:$USED, expected:$TOTAL_BLKS"
3375         fi
3376
3377         echo "Verify inode usage after write"
3378         USED=$(getquota -u $TSTID global curinodes)
3379         [ $USED -lt $INODES ] &&
3380                 error "Used inode for user $TSTID is $USED, expected $INODES"
3381         USED=$(getquota -g $TSTID global curinodes)
3382         [ $USED -lt $INODES ] &&
3383                 error "Used inode for group $TSTID is $USED, expected $INODES"
3384         if is_project_quota_supported; then
3385                 USED=$(getquota -p $TSTPRJID global curinodes)
3386                 [ $USED -lt $INODES ] && error \
3387                         "Used inode for project $TSTPRJID is $USED, expected $INODES"
3388         fi
3389
3390         cleanup_quota_test
3391
3392         echo "Verify disk usage after delete"
3393         USED=$(getquota -u $TSTID global curspace)
3394         [ $USED -eq 0 ] || error "Used space for user $TSTID isn't 0. $USED"
3395         USED=$(getquota -u $TSTID global curinodes)
3396         [ $USED -eq 0 ] || error "Used inodes for user $TSTID isn't 0. $USED"
3397         USED=$(getquota -g $TSTID global curspace)
3398         [ $USED -eq 0 ] || error "Used space for group $TSTID isn't 0. $USED"
3399         USED=$(getquota -g $TSTID global curinodes)
3400         [ $USED -eq 0 ] || error "Used inodes for group $TSTID isn't 0. $USED"
3401         if is_project_quota_supported; then
3402                 USED=$(getquota -p $TSTPRJID global curspace)
3403                 [ $USED -eq 0 ] ||
3404                         error "Used space for project $TSTPRJID isn't 0. $USED"
3405                 USED=$(getquota -p $TSTPRJID global curinodes)
3406                 [ $USED -eq 0 ] ||
3407                         error "Used inodes for project $TSTPRJID isn't 0. $USED"
3408         fi
3409 }
3410 run_test 33 "Basic usage tracking for user & group & project"
3411
3412 # usage transfer test for user & group & project
3413 test_34() {
3414         local BLK_CNT=2 # MB
3415         local project_supported="no"
3416
3417         is_project_quota_supported && project_supported="yes"
3418         setup_quota_test || error "setup quota failed with $?"
3419
3420         # make sure the system is clean
3421         local USED=$(getquota -u $TSTID global curspace)
3422         [ $USED -ne 0 ] && error "Used space ($USED) for user $TSTID isn't 0."
3423         USED=$(getquota -g $TSTID global curspace)
3424         [ $USED -ne 0 ] && error "Used space ($USED) for group $TSTID isn't 0."
3425
3426         local USED=$(getquota -u $TSTID2 global curspace)
3427         [ $USED -ne 0 ] && error "Used space ($USED) for user $TSTID2 isn't 0."
3428         if [ $project_supported == "yes" ]; then
3429                 USED=$(getquota -p $TSTPRJID global curspace)
3430                 [ $USED -ne 0 ] && error \
3431                         "Used space ($USED) for Project $TSTPRJID isn't 0."
3432         fi
3433
3434         echo "Write file..."
3435         $DD of=$DIR/$tdir/$tfile count=$BLK_CNT 2>/dev/null ||
3436                 error "write failed"
3437         cancel_lru_locks osc
3438         sync; sync_all_data || true
3439
3440         echo "chown the file to user $TSTID"
3441         chown $TSTID $DIR/$tdir/$tfile || error "chown failed"
3442
3443         echo "Wait for setattr on objects finished..."
3444         wait_delete_completed
3445
3446         BLK_CNT=$((BLK_CNT * 1024))
3447
3448         echo "Verify disk usage for user $TSTID"
3449         USED=$(getquota -u $TSTID global curspace)
3450         [ $USED -lt $BLK_CNT ] &&
3451                 error "Used space for user $TSTID is ${USED}, expected $BLK_CNT"
3452         USED=$(getquota -u $TSTID global curinodes)
3453         [ $USED -ne 1 ] &&
3454                 error "Used inodes for user $TSTID is $USED, expected 1"
3455
3456         echo "chgrp the file to group $TSTID"
3457         chgrp $TSTID $DIR/$tdir/$tfile || error "chgrp failed"
3458
3459         echo "Wait for setattr on objects finished..."
3460         wait_delete_completed
3461
3462         echo "Verify disk usage for group $TSTID"
3463         USED=$(getquota -g $TSTID global curspace)
3464         [ $USED -ge $BLK_CNT ] ||
3465                 error "Used space for group $TSTID is $USED, expected $BLK_CNT"
3466         USED=$(getquota -g $TSTID global curinodes)
3467         [ $USED -eq 1 ] ||
3468                 error "Used inodes for group $TSTID is $USED, expected 1"
3469
3470         # chown won't change the ost object group. LU-4345 */
3471         echo "chown the file to user $TSTID2"
3472         chown $TSTID2 $DIR/$tdir/$tfile || error "chown to $TSTID2 failed"
3473
3474         echo "Wait for setattr on objects finished..."
3475         wait_delete_completed
3476
3477         echo "change_project project id to $TSTPRJID"
3478         [ $project_supported == "yes" ] &&
3479                 change_project -p $TSTPRJID $DIR/$tdir/$tfile
3480         echo "Wait for setattr on objects finished..."
3481         wait_delete_completed
3482
3483         echo "Verify disk usage for user $TSTID2/$TSTID and group $TSTID"
3484         USED=$(getquota -u $TSTID2 global curspace)
3485         [ $USED -lt $BLK_CNT ] &&
3486                 error "Used space for user $TSTID2 is $USED, expected $BLK_CNT"
3487         USED=$(getquota -u $TSTID global curspace)
3488         [ $USED -ne 0 ] &&
3489                 error "Used space for user $TSTID is $USED, expected 0"
3490         USED=$(getquota -g $TSTID global curspace)
3491         [ $USED -lt $BLK_CNT ] &&
3492                 error "Used space for group $TSTID is $USED, expected $BLK_CNT"
3493         if [ $project_supported == "yes" ]; then
3494                 USED=$(getquota -p $TSTPRJID global curspace)
3495                 [ $USED -lt $BLK_CNT ] && error \
3496                         "Used space for group $TSTPRJID is $USED, expected $BLK_CNT"
3497         fi
3498         return 0
3499 }
3500 run_test 34 "Usage transfer for user & group & project"
3501
3502 # usage is still accessible across restart
3503 test_35() {
3504         local BLK_CNT=2 # MB
3505
3506         setup_quota_test || error "setup quota failed with $?"
3507
3508         echo "Write file..."
3509         $RUNAS $DD of=$DIR/$tdir/$tfile count=$BLK_CNT 2>/dev/null ||
3510                 error "write failed"
3511         is_project_quota_supported &&
3512                 change_project -p $TSTPRJID $DIR/$tdir/$tfile
3513         cancel_lru_locks osc
3514
3515         echo "Wait for setattr on objects finished..."
3516         wait_delete_completed
3517
3518         sync; sync_all_data || true
3519
3520         echo "Save disk usage before restart"
3521         local ORIG_USR_SPACE=$(getquota -u $TSTID global curspace)
3522         [ $ORIG_USR_SPACE -eq 0 ] &&
3523                 error "Used space for user $TSTID is 0, expected ${BLK_CNT}M"
3524         local ORIG_USR_INODES=$(getquota -u $TSTID global curinodes)
3525         [ $ORIG_USR_INODES -eq 0 ] &&
3526                 error "Used inodes for user $TSTID is 0, expected 1"
3527         echo "User $TSTID: ${ORIG_USR_SPACE}KB $ORIG_USR_INODES inodes"
3528         local ORIG_GRP_SPACE=$(getquota -g $TSTID global curspace)
3529         [ $ORIG_GRP_SPACE -eq 0 ] &&
3530                 error "Used space for group $TSTID is 0, expected ${BLK_CNT}M"
3531         local ORIG_GRP_INODES=$(getquota -g $TSTID global curinodes)
3532         [ $ORIG_GRP_INODES -eq 0 ] &&
3533                 error "Used inodes for group $TSTID is 0, expected 1"
3534         echo "Group $TSTID: ${ORIG_GRP_SPACE}KB $ORIG_GRP_INODES inodes"
3535
3536         if is_project_quota_supported; then
3537                 local ORIG_PRJ_SPACE=$(getquota -p $TSTPRJID global curspace)
3538                 [ $ORIG_PRJ_SPACE -eq 0 ] && error \
3539                         "Used space for project $TSTPRJID is 0, expected ${BLK_CNT}M"
3540                 local ORIG_PRJ_INODES=$(getquota -p $TSTPRJID global curinodes)
3541                 [ $ORIG_PRJ_INODES -eq 0 ] && error \
3542                         "Used inodes for project $TSTPRJID is 0, expected 1"
3543                 echo "Project $TSTPRJID: ${ORIG_PRJ_SPACE}KB $ORIG_PRJ_INODES inodes"
3544         fi
3545
3546         log "Restart..."
3547         stopall
3548         setupall
3549         quota_init
3550
3551         echo "Verify disk usage after restart"
3552         local USED=$(getquota -u $TSTID global curspace)
3553         [ $USED -eq $ORIG_USR_SPACE ] ||
3554                 error "Used space for user $TSTID changed from " \
3555                         "$ORIG_USR_SPACE to $USED"
3556         USED=$(getquota -u $TSTID global curinodes)
3557         [ $USED -eq $ORIG_USR_INODES ] ||
3558                 error "Used inodes for user $TSTID changed from " \
3559                         "$ORIG_USR_INODES to $USED"
3560         USED=$(getquota -g $TSTID global curspace)
3561         [ $USED -eq $ORIG_GRP_SPACE ] ||
3562                 error "Used space for group $TSTID changed from " \
3563                         "$ORIG_GRP_SPACE to $USED"
3564         USED=$(getquota -g $TSTID global curinodes)
3565         [ $USED -eq $ORIG_GRP_INODES ] ||
3566                 error "Used inodes for group $TSTID changed from " \
3567                         "$ORIG_GRP_INODES to $USED"
3568         if [ $project_supported == "yes" ]; then
3569                 USED=$(getquota -p $TSTPRJID global curinodes)
3570                 [ $USED -eq $ORIG_PRJ_INODES ] ||
3571                         error "Used inodes for project $TSTPRJID " \
3572                                 "changed from $ORIG_PRJ_INODES to $USED"
3573                 USED=$(getquota -p $TSTPRJID global curspace)
3574                 [ $USED -eq $ORIG_PRJ_SPACE ] ||
3575                         error "Used space for project $TSTPRJID "\
3576                                 "changed from $ORIG_PRJ_SPACE to $USED"
3577         fi
3578
3579         # check if the vfs_dq_init() is called before writing
3580         echo "Append to the same file..."
3581         $RUNAS $DD of=$DIR/$tdir/$tfile count=$BLK_CNT seek=1 2>/dev/null ||
3582                 error "write failed"
3583         cancel_lru_locks osc
3584         sync; sync_all_data || true
3585
3586         echo "Verify space usage is increased"
3587         USED=$(getquota -u $TSTID global curspace)
3588         [ $USED -gt $ORIG_USR_SPACE ] ||
3589                 error "Used space for user $TSTID isn't increased" \
3590                         "orig:$ORIG_USR_SPACE, now:$USED"
3591         USED=$(getquota -g $TSTID global curspace)
3592         [ $USED -gt $ORIG_GRP_SPACE ] ||
3593                 error "Used space for group $TSTID isn't increased" \
3594                         "orig:$ORIG_GRP_SPACE, now:$USED"
3595         if [ $project_supported == "yes" ]; then
3596                 USED=$(getquota -p $TSTPRJID global curspace)
3597                 [ $USED -gt $ORIG_PRJ_SPACE ] ||
3598                         error "Used space for project $TSTPRJID isn't " \
3599                                 "increased orig:$ORIG_PRJ_SPACE, now:$USED"
3600         fi
3601 }
3602 run_test 35 "Usage is still accessible across reboot"
3603
3604 # chown/chgrp to the file created with MDS_OPEN_DELAY_CREATE
3605 # LU-5006
3606 test_37() {
3607         [ "$MDS1_VERSION" -lt $(version_code 2.6.93) ] &&
3608                 skip "Old server doesn't have LU-5006 fix."
3609
3610         setup_quota_test || error "setup quota failed with $?"
3611
3612         # make sure the system is clean
3613         local USED=$(getquota -u $TSTID global curspace)
3614         [ $USED -ne 0 ] &&
3615                 error "Used space ($USED) for user $TSTID isn't 0."
3616
3617         # create file with MDS_OPEN_DELAY_CREATE flag
3618         $LFS setstripe -c 1 -i 0 $DIR/$tdir/$tfile ||
3619                 error "Create file failed"
3620         # write to file
3621         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 conv=notrunc \
3622                 oflag=sync || error "Write file failed"
3623         # chown to the file
3624         chown $TSTID $DIR/$tdir/$tfile || error "Chown to file failed"
3625
3626         # wait for setattr on objects finished..."
3627         wait_delete_completed
3628
3629         USED=$(getquota -u $TSTID global curspace)
3630         [ $USED -ne 0 ] || quota_error u $TSTUSR "Used space is 0"
3631 }
3632 run_test 37 "Quota accounted properly for file created by 'lfs setstripe'"
3633
3634 # LU-8801
3635 test_38() {
3636         [ "$MDS1_VERSION" -lt $(version_code 2.8.60) ] &&
3637                 skip "Old server doesn't have LU-8801 fix."
3638
3639         [ "$UID" != 0 ] && skip_env "must run as root" && return
3640
3641         setup_quota_test || error "setup quota failed with $?"
3642
3643         # make sure the system is clean
3644         local USED=$(getquota -u $TSTID global curspace)
3645         [ $USED -ne 0 ] &&
3646                 error "Used space ($USED) for user $TSTID isn't 0."
3647         USED=$(getquota -u $TSTID2 global curspace)
3648         [ $USED -ne 0 ] &&
3649                 error "Used space ($USED) for user $TSTID2 isn't 0."
3650
3651         local TESTFILE="$DIR/$tdir/$tfile"
3652         local file_cnt=10000
3653
3654         # Generate id entries in accounting file
3655         echo "Create $file_cnt files..."
3656         for i in `seq $file_cnt`; do
3657                 touch $TESTFILE-$i
3658                 chown $((file_cnt - i)):$((file_cnt - i)) $TESTFILE-$i ||
3659                         error "failed to chown $TESTFILE-$i"
3660         done
3661         cancel_lru_locks osc
3662         sync; sync_all_data || true
3663
3664         local procf="osd-$mds1_FSTYPE.$FSNAME-MDT0000"
3665         procf=${procf}.quota_slave.acct_user
3666         local acct_cnt
3667
3668         acct_cnt=$(do_facet mds1 $LCTL get_param $procf | grep "id:" | \
3669                    awk '{if ($3 < 10000) {print $3}}' | wc -l)
3670         echo "Found $acct_cnt id entries"
3671
3672         [ $file_cnt -eq $acct_cnt ] || {
3673                 do_facet mds1 $LCTL get_param $procf
3674                 error "skipped id entries"
3675         }
3676 }
3677 run_test 38 "Quota accounting iterator doesn't skip id entries"
3678
3679 test_39() {
3680         local TESTFILE="$DIR/$tdir/project"
3681         ! is_project_quota_supported &&
3682                 skip "Project quota is not supported"
3683
3684         setup_quota_test || error "setup quota failed with $?"
3685
3686         touch $TESTFILE
3687         projectid=$(lfs project $TESTFILE | awk '{print $1}')
3688         [ $projectid -ne 0 ] &&
3689                 error "Project id should be 0 not $projectid"
3690         change_project -p 1024 $TESTFILE
3691         projectid=$(lfs project $TESTFILE | awk '{print $1}')
3692         [ $projectid -ne 1024 ] &&
3693                 error "Project id should be 1024 not $projectid"
3694
3695         stopall || error "failed to stopall (1)"
3696         mount
3697         setupall
3698         projectid=$(lfs project $TESTFILE | awk '{print $1}')
3699         [ $projectid -eq 1024 ] ||
3700                 error "Project id should be 1024 not $projectid"
3701 }
3702 run_test 39 "Project ID interface works correctly"
3703
3704 test_40a() {
3705         ! is_project_quota_supported &&
3706                 skip "Project quota is not supported"
3707         local dir1="$DIR/$tdir/dir1"
3708         local dir2="$DIR/$tdir/dir2"
3709
3710         setup_quota_test || error "setup quota failed with $?"
3711
3712         mkdir -p $dir1 $dir2
3713         change_project -sp 1 $dir1 && touch $dir1/1
3714         change_project -sp 2 $dir2
3715
3716         ln $dir1/1 $dir2/1_link &&
3717                 error "Hard link across different project quota should fail"
3718         return 0
3719 }
3720 run_test 40a "Hard link across different project ID"
3721
3722 test_40b() {
3723         ! is_project_quota_supported &&
3724                 skip "Project quota is not supported"
3725         local dir1="$DIR/$tdir/dir1"
3726         local dir2="$DIR/$tdir/dir2"
3727
3728         setup_quota_test || error "setup quota failed with $?"
3729         mkdir -p $dir1 $dir2
3730         change_project -sp 1 $dir1 && touch $dir1/1
3731         change_project -sp 2 $dir2
3732
3733         mv $dir1/1 $dir2/2 || error "mv failed $?"
3734         local projid=$(lfs project $dir2/2 | awk '{print $1}')
3735         [ "$projid" -eq 2 ] || error "project id expected 2 not $projid"
3736 }
3737 run_test 40b "Mv across different project ID"
3738
3739 test_40c() {
3740         [ "$MDSCOUNT" -lt "2" ] && skip "needs >= 2 MDTs"
3741                 ! is_project_quota_supported &&
3742                         skip "Project quota is not supported"
3743
3744         setup_quota_test || error "setup quota failed with $?"
3745         local dir="$DIR/$tdir/dir"
3746
3747         mkdir -p $dir && change_project -sp 1 $dir
3748         $LFS mkdir -i 1 $dir/remote_dir || error "create remote dir failed"
3749         local projid=$(lfs project -d $dir/remote_dir | awk '{print $1}')
3750         [ "$projid" != "1" ] && error "projid id expected 1 not $projid"
3751         touch $dir/remote_dir/file
3752         #verify inherit works file for remote dir.
3753         local projid=$(lfs project -d $dir/remote_dir/file | awk '{print $1}')
3754         [ "$projid" != "1" ] &&
3755                 error "file under remote dir expected 1 not $projid"
3756
3757         #Agent inode should be ignored for project quota
3758         local used=$(getquota -p 1 global curinodes)
3759         [ $used -eq 3 ] ||
3760                 error "file count expected 3 got $used"
3761 }
3762 run_test 40c "Remote child Dir inherit project quota properly"
3763
3764 test_40d() {
3765         [ "$MDSCOUNT" -lt "2" ] && skip_env "needs >= 2 MDTs"
3766         is_project_quota_supported || skip "Project quota is not supported"
3767
3768         setup_quota_test || error "setup quota failed with $?"
3769         local dir="$DIR/$tdir/dir"
3770
3771         mkdir -p $dir
3772         $LFS setdirstripe -D -c 2 -i -1 $dir || error "setdirstripe failed"
3773         change_project -sp $TSTPRJID $dir ||
3774                 error "change project on $dir failed"
3775         for i in $(seq 5); do
3776                 mkdir -p $dir/d$i/d$i ||
3777                         error "mkdir $dir/d$i/d$i failed"
3778                 local projid=$($LFS project -d $dir/d$i/d$i |
3779                                awk '{print $1}')
3780                 [ "$projid" == "$TSTPRJID" ] ||
3781                         error "projid id expected $TSTPRJID not $projid"
3782                 touch $dir/d$i/d$i/file
3783                 #verify inherit works file for stripe dir.
3784                 local projid=$($LFS project -d $dir/d$i/d$i/file | awk '{print $1}')
3785                 [ "$projid" == "$TSTPRJID" ] ||
3786                         error "file under remote dir expected 1 not $projid"
3787         done
3788
3789         # account should be 1 + (2 + 1) *10 + 1 * 5
3790         local used=$(getquota -p $TSTPRJID global curinodes)
3791         [ $used -eq 36 ] ||
3792                 error "file count expected 36 got $used"
3793 }
3794 run_test 40d "Stripe Directory inherit project quota properly"
3795
3796 test_41() {
3797         is_project_quota_supported ||
3798                 skip "Project quota is not supported"
3799         setup_quota_test || error "setup quota failed with $?"
3800         local dir="$DIR/$tdir/dir"
3801         local blimit=102400
3802         local ilimit=4096
3803         local projid=$((testnum * 1000))
3804
3805         quota_init
3806
3807         # enable mdt/ost quota
3808         set_mdt_qtype ugp || error "enable mdt quota failed"
3809         set_ost_qtype ugp || error "enable ost quota failed"
3810
3811         test_mkdir -p $dir && change_project -sp $projid $dir
3812         $LFS setquota -p $projid -b 0 -B ${blimit}K -i 0 -I $ilimit $dir ||
3813                 error "set project quota failed"
3814
3815         sync; sync_all_data
3816         sleep_maxage
3817
3818         # check if df output works as expected
3819         echo "== global statfs: $MOUNT =="
3820         df -kP $MOUNT; df -iP $MOUNT; $LFS quota -p $projid $dir
3821         echo
3822         echo "== project statfs (prjid=$projid): $dir =="
3823         df -kP $dir; df -iP $dir
3824         local bused=$(getquota -p $projid global curspace)
3825         local iused=$(getquota -p $projid global curinodes)
3826         # note trailing space to match double printf from awk
3827         local expected="$blimit $bused $ilimit $iused "
3828
3829         wait_update $HOSTNAME \
3830                 "{ df -kP $dir; df -iP $dir; } |
3831                  awk '/$FSNAME/ { printf \\\"%d %d \\\", \\\$2,\\\$3 }'" \
3832                 "$expected" ||
3833                 error "failed to get correct statfs for project quota"
3834 }
3835 run_test 41 "df should return projid-specific values"
3836
3837 test_delete_qid()
3838 {
3839         local qslv_file=$1
3840         local qtype_file=$2
3841         local qtype=$3
3842         local qid=$4
3843         local osd="osd-ldiskfs"
3844
3845         [ "$ost1_FSTYPE" = zfs ] && osd="osd-zfs"
3846
3847         rm -f $DIR/$tdir/$tfile
3848         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile
3849         chmod a+rw $DIR/$tdir/$tfile
3850
3851         $LFS setquota $qtype $qid -B 300M $MOUNT
3852         $RUNAS dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 ||
3853                 error "failed to dd"
3854
3855         do_facet $SINGLEMDS \
3856                 "cat /proc/fs/lustre/qmt/$FSNAME-QMT0000/dt-0x0/$qtype_file |
3857                  grep -E 'id: *$qid'" || error "QMT: no qid $qid is found"
3858         echo $osd
3859         do_facet ost1 \
3860                 "cat /proc/fs/lustre/$osd/$FSNAME-OST0000/$qslv_file |
3861                  grep -E 'id: *$qid'" || error "QSD: no qid $qid is found"
3862
3863         $LFS setquota $qtype $qid --delete $MOUNT
3864         do_facet $SINGLEMDS \
3865                 "cat /proc/fs/lustre/qmt/$FSNAME-QMT0000/dt-0x0/$qtype_file |
3866                  grep -E 'id: *$qid'" && error "QMT: qid $qid is not deleted"
3867         sleep 5
3868         do_facet ost1 \
3869                 "cat /proc/fs/lustre/$osd/$FSNAME-OST0000/$qslv_file |
3870                  grep -E 'id: *$qid'" && error "QSD: qid $qid is not deleted"
3871
3872         $LFS setquota $qtype $qid -B 500M $MOUNT
3873         $RUNAS dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 ||
3874                 error "failed to dd"
3875         do_facet $SINGLEMDS \
3876                 "cat /proc/fs/lustre/qmt/$FSNAME-QMT0000/dt-0x0/$qtype_file |
3877                  grep -E 'id: *$qid'" || error "QMT: qid $pid is not recreated"
3878         cat /proc/fs/lustre/$osd/$FSNAME-OST0000/$qslv_file
3879         do_facet ost1 \
3880                 "cat /proc/fs/lustre/$osd/$FSNAME-OST0000/$qslv_file |
3881                  grep -E 'id: *$qid'" || error "QSD: qid $qid is not recreated"
3882 }
3883
3884 test_48()
3885 {
3886         setup_quota_test || error "setup quota failed with $?"
3887         set_ost_qtype $QTYPE || error "enable ost quota failed"
3888         quota_init
3889
3890         test_delete_qid "quota_slave/limit_user" "glb-usr" "-u" $TSTID
3891         test_delete_qid "quota_slave/limit_group" "glb-grp" "-g" $TSTID
3892         is_project_quota_supported &&
3893             test_delete_qid "quota_slave/limit_project" "glb-prj" "-p" "10000"
3894
3895         cleanup_quota_test
3896 }
3897 run_test 48 "lfs quota --delete should delete quota project ID"
3898
3899 test_50() {
3900         ! is_project_quota_supported &&
3901                 skip "Project quota is not supported"
3902
3903         setup_quota_test || error "setup quota failed with $?"
3904         local dir1="$DIR/$tdir/dir1"
3905         local dir2="$DIR/$tdir/dir2"
3906
3907         mkdir -p $dir1 && change_project -sp 1 $dir1
3908         mkdir -p $dir2 && change_project -sp 2 $dir2
3909         for num in $(seq 1 10); do
3910                 touch $dir1/file_$num $dir2/file_$num
3911                 ln -s $dir1/file_$num $dir1/file_$num"_link"
3912                 ln -s $dir2/file_$num $dir2/file_$num"_link"
3913         done
3914
3915         count=$($LFS find --projid 1 $DIR | wc -l)
3916         [ "$count" != 21 ] && error "expected 21 but got $count"
3917
3918         # 1(projid 0 dir) + 1(projid 2 dir) + 20(projid 2 files)
3919         count=$($LFS find ! --projid 1 $DIR/$tdir | wc -l)
3920         [ $count -eq 22 ] || error "expected 22 but got $count"
3921 }
3922 run_test 50 "Test if lfs find --projid works"
3923
3924 test_51() {
3925         ! is_project_quota_supported &&
3926                 skip "Project quota is not supported"
3927         setup_quota_test || error "setup quota failed with $?"
3928         local dir="$DIR/$tdir/dir"
3929
3930         mkdir $dir && change_project -sp 1 $dir
3931         local used=$(getquota -p 1 global curinodes)
3932         [ $used != "1" ] && error "expected 1 got $used"
3933
3934         touch $dir/1
3935         touch $dir/2
3936         cp $dir/2 $dir/3
3937         used=$(getquota -p 1 global curinodes)
3938         [ $used != "4" ] && error "expected 4 got $used"
3939
3940         $DD if=/dev/zero of=$DIR/$tdir/6 bs=1M count=1
3941         #try cp to dir
3942         cp $DIR/$tdir/6 $dir/6
3943         used=$(getquota -p 1 global curinodes)
3944         [ $used != "5" ] && error "expected 5 got $used"
3945
3946         #try mv to dir
3947         mv $DIR/$tdir/6 $dir/7
3948         used=$(getquota -p 1 global curinodes)
3949         [ $used -eq 6 ] || error "expected 6 got $used"
3950 }
3951 run_test 51 "Test project accounting with mv/cp"
3952
3953 test_52() {
3954         ! is_project_quota_supported &&
3955                 skip "Project quota is not supported"
3956
3957         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
3958                 skip "Need MDS version at least 2.14.55"
3959
3960         setup_quota_test || error "setup quota failed with $?"
3961
3962         local dir1=$DIR/$tdir/t52_dir1
3963         local dir2=$DIR/$tdir/t52_dir2
3964
3965         mkdir $dir1 || error "failed to mkdir $dir1"
3966         mkdir $dir2 || error "failed to mkdir $dir2"
3967
3968         $LFS project -sp 1000 $dir1 || error "fail to set project on $dir1"
3969         $LFS project -sp 1001 $dir2 || error "fail to set project on $dir2"
3970
3971         $DD if=/dev/zero of=/$dir1/$tfile bs=1M count=100 ||
3972                 error "failed to create and write $tdir1/$tfile"
3973
3974         cancel_lru_locks osc
3975         sync; sync_all_data || true
3976
3977         local attrs=($(lsattr -p $dir1/$tfile))
3978         (( ${attrs[0]} == 1000 )) ||
3979                 error "project ID on $dir1/$tfile is not inherited"
3980
3981         $LFS quota -p 1000 $DIR
3982         $LFS quota -p 1001 $DIR
3983
3984         local prev_used=$(getquota -p 1000 global curspace)
3985         local prev_used2=$(getquota -p 1001 global curspace)
3986
3987         mrename $dir1 $dir2/tdir || log "rename directory return $?"
3988
3989         local inum_before=$(ls -i $dir1/$tfile | awk '{print $1}')
3990         mrename $dir1/$tfile $dir2/$tfile || error "failed to rename file"
3991         local inum_after=$(ls -i $dir2/$tfile | awk '{print $1}')
3992
3993         attrs=($(lsattr -p $dir2/$tfile))
3994         (( ${attrs[0]} == 1001 )) ||
3995                 error "project ID is not updated after rename"
3996
3997         (( $inum_before == $inum_after )) ||
3998                 error "inode is changed after rename: $inum_before, $inum_after"
3999
4000         sync_all_data || true
4001
4002         $LFS quota -p 1000 $DIR
4003         $LFS quota -p 1001 $DIR
4004
4005         local new_used=$(getquota -p 1000 global curspace)
4006         local new_used2=$(getquota -p 1001 global curspace)
4007
4008         (( $prev_used >= $new_used + 102400 )) ||
4009                 error "quota is not deducted from old project ID"
4010         (( $prev_used2 <= $new_used2 - 102400 )) ||
4011                 error "quota is not added for the new project ID"
4012 }
4013 run_test 52 "Rename normal file across project ID"
4014
4015 test_53() {
4016         ! is_project_quota_supported &&
4017                 skip "Project quota is not supported"
4018         setup_quota_test || error "setup quota failed with $?"
4019         local dir="$DIR/$tdir/dir"
4020         mkdir $dir && change_project -s $dir
4021         [[ $($LFS project -d $dir) =~ " P " ]] ||
4022                 error "inherit attribute should be set"
4023
4024         change_project -C $dir
4025         [[ $($LFS project -d $dir) =~ " - " ]] ||
4026                 error "inherit attribute should be cleared"
4027 }
4028 run_test 53 "Project inherit attribute could be cleared"
4029
4030 test_54() {
4031         ! is_project_quota_supported &&
4032                 skip "Project quota is not supported"
4033         setup_quota_test || error "setup quota failed with $?"
4034         local testfile="$DIR/$tdir/$tfile-0"
4035
4036         #set project ID/inherit attribute
4037         change_project -sp $TSTPRJID $DIR/$tdir
4038         $RUNAS createmany -m ${testfile} 100 ||
4039                 error "create many files failed"
4040
4041         local proj_count=$(lfs project -r $DIR/$tdir | wc -l)
4042         # one more count for directory itself */
4043         ((proj_count++))
4044
4045         #check project
4046         local proj_count1=$(lfs project -rcp $TSTPRJID $DIR/$tdir | wc -l)
4047         [ $proj_count1 -eq 0 ] || error "c1: expected 0 got $proj_count1"
4048
4049         proj_count1=$(lfs project -rcp $((TSTPRJID+1)) $DIR/$tdir | wc -l)
4050         [ $proj_count1 -eq $proj_count ] ||
4051                         error "c2: expected $proj_count got $proj_count1"
4052
4053         #clear project but with kept projid
4054         change_project -rCk $DIR/$tdir
4055         proj_count1=$(lfs project -rcp $TSTPRJID $DIR/$tdir | wc -l)
4056         [ $proj_count1 -eq 1 ] ||
4057                         error "c3: expected 1 got $proj_count1"
4058
4059         #verify projid untouched.
4060         proj_count1=$(lfs project -r $DIR/$tdir | grep -c $TSTPRJID)
4061         ((proj_count1++))
4062         [ $proj_count1 -eq $proj_count ] ||
4063                         error "c4: expected $proj_count got $proj_count1"
4064
4065         # test -0 option
4066         lfs project $DIR/$tdir -cr -0 | xargs -0 lfs project -s
4067         proj_count1=$(lfs project -rcp $TSTPRJID $DIR/$tdir | wc -l)
4068         [ $proj_count1 -eq 0 ] || error "c5: expected 0 got $proj_count1"
4069
4070         #this time clear all
4071         change_project -rC $DIR/$tdir
4072         proj_count1=$(lfs project -r $DIR/$tdir | grep -c $TSTPRJID)
4073         [ $proj_count1 -eq 0 ] ||
4074                         error "c6: expected 0 got $proj_count1"
4075         #cleanup
4076         unlinkmany ${testfile} 100 ||
4077                 error "unlink many files failed"
4078 }
4079 run_test 54 "basic lfs project interface test"
4080
4081 test_55() {
4082         [ "$MDS1_VERSION" -lt $(version_code 2.10.58) ] &&
4083                 skip "Not supported before 2.10.58."
4084         setup_quota_test || error "setup quota failed with $?"
4085
4086         set_ost_qtype $QTYPE || error "enable ost quota failed"
4087         quota_init
4088
4089         #add second group to TSTUSR
4090         usermod -G $TSTUSR,$TSTUSR2 $TSTUSR
4091
4092         #prepare test file
4093         $RUNAS dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1024 count=100000 ||
4094         error "failed to dd"
4095
4096         cancel_lru_locks osc
4097         sync; sync_all_data || true
4098
4099         $LFS setquota -g $TSTUSR2 -b 0 -B 50M $DIR ||
4100         error "failed to setquota on group $TSTUSR2"
4101
4102         $LFS quota -v -g $TSTUSR2 $DIR
4103
4104         runas -u $TSTUSR -g $TSTUSR2 chgrp $TSTUSR2 $DIR/$tdir/$tfile &&
4105         error "chgrp should failed with -EDQUOT"
4106
4107         USED=$(getquota -g $TSTUSR2 global curspace)
4108         echo "$USED"
4109
4110         $LFS setquota -g $TSTUSR2 -b 0 -B 300M $DIR ||
4111         error "failed to setquota on group $TSTUSR2"
4112
4113         $LFS quota -v -g $TSTUSR2 $DIR
4114
4115         runas -u $TSTUSR -g $TSTUSR2 chgrp $TSTUSR2 $DIR/$tdir/$tfile ||
4116         error "chgrp should succeed"
4117
4118         $LFS quota -v -g $TSTUSR2 $DIR
4119 }
4120 run_test 55 "Chgrp should be affected by group quota"
4121
4122 test_56() {
4123         setup_quota_test || error "setup quota failed with $?"
4124
4125         set_ost_qtype $QTYPE || error "enable ost quota failed"
4126         quota_init
4127
4128         $LFS setquota -t -u -b 10 -i 10 $DIR ||
4129                 erro "failed to set grace time for usr quota"
4130         grace_time=$($LFS quota -t -u $DIR | grep "Block grace time:" |
4131                      awk '{print $4 $8}')
4132         if [ "x$grace_time" != "x10s;10s" ]; then
4133                 $LFS quota -t -u $DIR
4134                 error "expected grace time: 10s;10s, got:$grace_time"
4135         fi
4136 }
4137 run_test 56 "lfs quota -t should work well"
4138
4139 test_57() {
4140         setup_quota_test || error "setup quota failed with $?"
4141
4142         local dir="$DIR/$tdir/dir"
4143         mkdir -p $dir
4144         mkfifo $dir/pipe
4145         #command can process further if it hit some errors
4146         $LFS project -sp 1 $dir/pipe
4147         touch $dir/aaa $dir/bbb
4148         mkdir $dir/subdir -p
4149         touch $dir/subdir/aaa $dir/subdir/bbb
4150         #create one invalid link file
4151         ln -s $dir/not_exist_file $dir/ccc
4152         local cnt=$(lfs project -r $dir 2>/dev/null | wc -l)
4153         [ $cnt -eq 7 ] || error "expected 7 got $cnt"
4154 }
4155 run_test 57 "lfs project could tolerate errors"
4156
4157 test_59() {
4158         [ "$mds1_FSTYPE" != ldiskfs ] &&
4159                 skip "ldiskfs only test"
4160         disable_project_quota
4161         setup_quota_test || error "setup quota failed with $?"
4162         quota_init
4163
4164         local testfile="$DIR/$tdir/$tfile-0"
4165         #make sure it did not crash kernel
4166         touch $testfile && lfs project -sp 1 $testfile
4167
4168         enable_project_quota
4169 }
4170 run_test 59 "lfs project dosen't crash kernel with project disabled"
4171
4172 test_60() {
4173         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
4174                 skip "Needs MDS version 2.11.53 or later."
4175         setup_quota_test || error "setup quota failed with $?"
4176
4177         local testfile=$DIR/$tdir/$tfile
4178         local limit=100
4179
4180         set_mdt_qtype "ug" || error "enable mdt quota failed"
4181
4182         $LFS setquota -g $TSTUSR -b 0 -B 0 -i 0 -I $limit $DIR ||
4183                 error "set quota failed"
4184         quota_show_check a g $TSTUSR
4185
4186         chown $TSTUSR.$TSTUSR $DIR/$tdir || error "chown $DIR/$tdir failed"
4187         chmod g+s $DIR/$tdir || error "chmod g+s failed"
4188         $RUNAS createmany -m ${testfile} $((limit-1)) ||
4189                 error "create many files failed"
4190
4191         $RUNAS touch $DIR/$tdir/foo && error "regular user should fail"
4192
4193         # root user can overrun quota
4194         runas -u 0 -g 0 touch $DIR/$tdir/foo ||
4195                 error "root user should succeed"
4196 }
4197 run_test 60 "Test quota for root with setgid"
4198
4199 # test default quota
4200 test_default_quota() {
4201         [ "$MDS1_VERSION" -lt $(version_code 2.11.51) ] &&
4202                 skip "Not supported before 2.11.51."
4203
4204         local qtype=$1
4205         local qres_type=$2
4206         local qid=$TSTUSR
4207         local qprjid=$TSTPRJID
4208         local qdtype="-U"
4209         local qs="-b"
4210         local qh="-B"
4211         local LIMIT=20480 #20M disk space
4212         local TESTFILE="$DIR/$tdir/$tfile-0"
4213         local $qpool_cmd
4214
4215         [ $qtype == "-p" ] && ! is_project_quota_supported &&
4216                 echo "Project quota is not supported" && return 0
4217
4218         [ $qtype == "-u" ] && qdtype="-U"
4219         [ $qtype == "-g" ] && qdtype="-G"
4220         [ $qtype == "-p" ] && {
4221                 qdtype="-P"
4222                 qid=$qprjid
4223         }
4224
4225         [ $qres_type == "meta" ] && {
4226                 LIMIT=10240 #10K inodes
4227                 qs="-i"
4228                 qh="-I"
4229         }
4230         [ ! -z "$3" ] && {
4231                 qpool_cmd="--pool $3"
4232                 # pool quotas don't work properly without global limit
4233                 $LFS setquota $qtype $qid -B1T -b1T $DIR ||
4234                         error "set global limit failed"
4235         }
4236
4237         setup_quota_test || error "setup quota failed with $?"
4238
4239         quota_init
4240
4241         # enable mdt/ost quota
4242         set_mdt_qtype $QTYPE || error "enable mdt quota failed"
4243         set_ost_qtype $QTYPE || error "enable ost quota failed"
4244
4245         log "set to use default quota"
4246         $LFS setquota $qtype $qid -d $qpool_cmd $DIR ||
4247                 error "set $qid to use default quota failed"
4248
4249         log "set default quota"
4250         $LFS setquota $qdtype $qpool_cmd $qs ${LIMIT} $qh ${LIMIT} $DIR ||
4251                 error "set $qid default quota failed"
4252
4253         log "get default quota"
4254         $LFS quota $qdtype $DIR || error "get default quota failed"
4255
4256         if [ $qres_type == "data" ]; then
4257                 local SLIMIT=$($LFS quota $qpool_cmd $qdtype $DIR | \
4258                                 grep "$MOUNT" | awk '{print $2}')
4259                 [ $SLIMIT -eq $LIMIT ] ||
4260                         error "the returned default quota is wrong"
4261         else
4262                 local SLIMIT=$($LFS quota $qdtype $DIR | grep "$MOUNT" | \
4263                                                         awk '{print $5}')
4264                 [ $SLIMIT -eq $LIMIT ] ||
4265                         error "the returned default quota is wrong"
4266         fi
4267
4268         # make sure the system is clean
4269         local USED=$(getquota $qtype $qid global curspace)
4270         [ $USED -ne 0 ] && error "Used space for $qid isn't 0."
4271
4272         $LFS setstripe $TESTFILE -c 1 $qpool_cmd ||
4273                         error "setstripe $TESTFILE failed"
4274         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
4275
4276         [ $qtype == "-p" ] && change_project -sp $TSTPRJID $DIR/$tdir
4277
4278         log "Test not out of quota"
4279         if [ $qres_type == "data" ]; then
4280                 $RUNAS $DD of=$TESTFILE count=$((LIMIT/2 >> 10)) oflag=sync ||
4281                         quota_error $qtype $qid "write failed, expect succeed"
4282         else
4283                 $RUNAS createmany -m $TESTFILE $((LIMIT/2)) ||
4284                         quota_error $qtype $qid "create failed, expect succeed"
4285
4286                 unlinkmany $TESTFILE $((LIMIT/2))
4287         fi
4288
4289         log "Test out of quota"
4290         # flush cache, ensure noquota flag is set on client
4291         cancel_lru_locks osc
4292         cancel_lru_locks mdc
4293         sync; sync_all_data || true
4294         if [ $qres_type == "data" ]; then
4295                 $RUNAS $DD of=$TESTFILE count=$((LIMIT*2 >> 10)) oflag=sync &&
4296                         quota_error $qtype $qid "write succeed, expect EDQUOT"
4297         else
4298                 $RUNAS createmany -m $TESTFILE $((LIMIT*2)) &&
4299                         quota_error $qtype $qid "create succeed, expect EDQUOT"
4300
4301                 unlinkmany $TESTFILE $((LIMIT*2))
4302         fi
4303
4304         rm -f $TESTFILE
4305         $LFS setstripe $TESTFILE -c 1 $qpool_cmd ||
4306                         error "setstripe $TESTFILE failed"
4307         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
4308
4309         log "Increase default quota"
4310
4311         # LU-4505: sleep 5 seconds to enable quota acquire
4312         sleep 5
4313
4314         # increase default quota
4315         $LFS setquota $qdtype $qpool_cmd $qs $((LIMIT*3)) \
4316                 $qh $((LIMIT*3)) $DIR || error "set default quota failed"
4317
4318         cancel_lru_locks osc
4319         cancel_lru_locks mdc
4320         sync; sync_all_data || true
4321         if [ $qres_type == "data" ]; then
4322                 $RUNAS $DD of=$TESTFILE count=$((LIMIT*2 >> 10)) oflag=sync ||
4323                         quota_error $qtype $qid "write failed, expect succeed"
4324         else
4325                 $RUNAS createmany -m $TESTFILE $((LIMIT*2)) ||
4326                         quota_error $qtype $qid "create failed, expect succeed"
4327
4328                 unlinkmany $TESTFILE $((LIMIT*2))
4329         fi
4330
4331         log "Set quota to override default quota"
4332         $LFS setquota $qtype $qid $qpool_cmd $qs ${LIMIT} $qh ${LIMIT} $DIR ||
4333                 error "set $qid quota failed"
4334
4335         cancel_lru_locks osc
4336         cancel_lru_locks mdc
4337         sync; sync_all_data || true
4338         if [ $qres_type == "data" ]; then
4339                 $RUNAS $DD of=$TESTFILE count=$((LIMIT*2 >> 10)) oflag=sync &&
4340                         quota_error $qtype $qid "write succeed, expect EQUOT"
4341         else
4342                 $RUNAS createmany -m $TESTFILE $((LIMIT*2)) &&
4343                         quota_error $qtype $qid "create succeed, expect EQUOT"
4344
4345                 unlinkmany $TESTFILE $((LIMIT*2))
4346         fi
4347
4348         log "Set to use default quota again"
4349
4350         # LU-4505: sleep 5 seconds to enable quota acquire
4351         sleep 5
4352
4353         $LFS setquota $qtype $qid -d $qpool_cmd $DIR ||
4354                 error "set $qid to use default quota failed"
4355
4356         cancel_lru_locks osc
4357         cancel_lru_locks mdc
4358         sync; sync_all_data || true
4359         if [ $qres_type == "data" ]; then
4360                 $RUNAS $DD of=$TESTFILE count=$((LIMIT*2 >> 10)) oflag=sync ||
4361                         quota_error $qtype $qid "write failed, expect succeed"
4362         else
4363                 $RUNAS createmany -m $TESTFILE $((LIMIT*2)) ||
4364                         quota_error $qtype $qid "create failed, expect succeed"
4365
4366                 unlinkmany $TESTFILE $((LIMIT*2))
4367         fi
4368
4369         log "Cleanup"
4370         rm -f $TESTFILE
4371         wait_delete_completed || error "wait_delete_completed failed"
4372         sync_all_data || true
4373
4374         $LFS setquota $qdtype $qpool_cmd $qs 0 $qh 0 $DIR ||
4375                 error "reset default quota failed"
4376         $LFS setquota $qtype $qid $qpool_cmd $qs 0 $qh 0 $DIR ||
4377                 error "reset quota failed"
4378         cleanup_quota_test
4379 }
4380
4381 test_61() {
4382         test_default_quota "-u" "data"
4383         test_default_quota "-u" "meta"
4384         test_default_quota "-g" "data"
4385         test_default_quota "-g" "meta"
4386         test_default_quota "-p" "data"
4387         test_default_quota "-p" "meta"
4388 }
4389 run_test 61 "default quota tests"
4390
4391 test_62() {
4392         ! is_project_quota_supported &&
4393                 skip "Project quota is not supported"
4394         [[ "$(chattr -h 2>&1)" =~ "project" ||
4395            "$(chattr -h 2>&1)" =~ "pRVf" ]] ||
4396                 skip "chattr did not support project quota"
4397         setup_quota_test || error "setup quota failed with $?"
4398         local testdir=$DIR/$tdir/
4399
4400         $RUNAS mkdir -p $testdir || error "failed to mkdir"
4401         change_project -s $testdir
4402         [[ $($LFS project -d $testdir) =~ "P" ]] ||
4403                 error "inherit attribute should be set"
4404         # chattr used FS_IOC_SETFLAGS ioctl
4405         $RUNAS chattr -P $testdir &&
4406                 error "regular user clear inherit should fail"
4407         [[ $($LFS project -d $testdir) =~ "P" ]] ||
4408                 error "inherit attribute should still be set"
4409         chattr -P $testdir || error "root failed to clear inherit"
4410         [[ $($LFS project -d $testdir) =~ "P" ]] &&
4411                 error "inherit attribute should be cleared"
4412         return 0
4413 }
4414 run_test 62 "Project inherit should be only changed by root"
4415
4416 test_dom() {
4417         [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ] &&
4418                 skip "Not supported before 2.11.55"
4419
4420         local qtype=$1
4421         local qid=$TSTUSR
4422         local dd_failed=false
4423         local tdir_dom=${tdir}_dom
4424         local LIMIT=20480 #20M
4425
4426         [ $qtype == "p" ] && ! is_project_quota_supported &&
4427                 echo "Project quota is not supported" && return 0
4428
4429         [ $qtype == "p" ] && qid=$TSTPRJID
4430
4431         setup_quota_test || error "setup quota failed with $?"
4432
4433         quota_init
4434
4435         # enable mdt/ost quota
4436         set_mdt_qtype $QTYPE || error "enable mdt quota failed"
4437         set_ost_qtype $QTYPE || error "enable ost quota failed"
4438
4439         # make sure the system is clean
4440         local USED=$(getquota -$qtype $qid global curspace)
4441         [ $USED -ne 0 ] && error "Used space for $qid isn't 0."
4442
4443         chown $TSTUSR.$TSTUSR $DIR/$tdir || error "chown $tdir failed"
4444
4445         mkdir $DIR/$tdir_dom || error "mkdir $tdir_dom failed"
4446         $LFS setstripe -E 1M -L mdt $DIR/$tdir_dom ||
4447                 error "setstripe $tdir_dom failed"
4448         chown $TSTUSR.$TSTUSR $DIR/$tdir_dom || error "chown $tdir_dom failed"
4449
4450         [ $qtype == "p" ] && {
4451                 change_project -sp $TSTPRJID $DIR/$tdir
4452                 change_project -sp $TSTPRJID $DIR/$tdir_dom
4453         }
4454
4455         $LFS setquota -$qtype $qid -b $LIMIT -B $LIMIT $DIR ||
4456                 error "set $qid quota failed"
4457
4458         for ((i = 0; i < $((LIMIT/2048)); i++)); do
4459                 $RUNAS $DD of=$DIR/$tdir_dom/$tfile-$i count=1 oflag=sync ||
4460                                                                 dd_failed=true
4461         done
4462
4463         $dd_failed && quota_error $qtype $qid "write failed, expect succeed"
4464
4465         for ((i = $((LIMIT/2048)); i < $((LIMIT/1024 + 10)); i++)); do
4466                 $RUNAS $DD of=$DIR/$tdir_dom/$tfile-$i count=1 oflag=sync ||
4467                                                                 dd_failed=true
4468         done
4469
4470         $dd_failed || quota_error $qtype $qid "write succeed, expect EDQUOT"
4471
4472         rm -f $DIR/$tdir_dom/*
4473
4474         # flush cache, ensure noquota flag is set on client
4475         cancel_lru_locks osc
4476         cancel_lru_locks mdc
4477         sync; sync_all_data || true
4478
4479         dd_failed=false
4480
4481         $RUNAS $DD of=$DIR/$tdir/file count=$((LIMIT/2048)) oflag=sync ||
4482                 quota_error $qtype $qid "write failed, expect succeed"
4483
4484         for ((i = 0; i < $((LIMIT/2048 + 10)); i++)); do
4485                 $RUNAS $DD of=$DIR/$tdir_dom/$tfile-$i count=1 oflag=sync ||
4486                                                                 dd_failed=true
4487         done
4488
4489         $dd_failed || quota_error $qtype $TSTID "write succeed, expect EDQUOT"
4490
4491         rm -f $DIR/$tdir/*
4492         rm -f $DIR/$tdir_dom/*
4493
4494         # flush cache, ensure noquota flag is set on client
4495         cancel_lru_locks osc
4496         cancel_lru_locks mdc
4497         sync; sync_all_data || true
4498
4499         dd_failed=false
4500
4501         for ((i = 0; i < $((LIMIT/2048)); i++)); do
4502                 $RUNAS $DD of=$DIR/$tdir_dom/$tfile-$i count=1 oflag=sync ||
4503                                                                 dd_failed=true
4504         done
4505
4506         $dd_failed && quota_error $qtype $qid "write failed, expect succeed"
4507
4508         $RUNAS $DD of=$DIR/$tdir/file count=$((LIMIT/2048 + 10)) oflag=sync &&
4509                 quota_error $qtype $qid "write succeed, expect EDQUOT"
4510
4511         rm -fr $DIR/$tdir
4512         rm -fr $DIR/$tdir_dom
4513
4514         $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I 0 $DIR ||
4515                 error "reset usr quota failed"
4516 }
4517
4518 test_63() {
4519         test_dom "u"
4520         test_dom "g"
4521         test_dom "p"
4522 }
4523 run_test 63 "quota on DoM tests"
4524
4525 test_64() {
4526         ! is_project_quota_supported &&
4527                 skip "Project quota is not supported"
4528         setup_quota_test || error "setup quota failed with $?"
4529         local dir1="$DIR/$tdir/"
4530
4531         touch $dir1/file
4532         ln -s $dir1/file $dir1/file_link
4533         mkfifo $dir1/fifo
4534
4535         $LFS project -srp $TSTPRJID $dir1 >&/dev/null ||
4536                 error "set project should succeed"
4537
4538         used=$(getquota -p $TSTPRJID global curinodes)
4539         [ $used -eq 4 ] || error "expected 4 got $used"
4540         $LFS project -rC $dir1 >&/dev/null ||
4541                 error "clear project should succeed"
4542
4543         used=$(getquota -p $TSTPRJID global curinodes)
4544         [ $used -eq 0 ] || error "expected 0 got $used"
4545 }
4546 run_test 64 "lfs project on non dir/files should succeed"
4547
4548 test_65() {
4549         local SIZE=10 # MB
4550         local TESTFILE="$DIR/$tdir/$tfile-0"
4551
4552         setup_quota_test || error "setup quota failed with $?"
4553         set_ost_qtype $QTYPE || error "enable ost quota failed"
4554         quota_init
4555
4556         echo "Write..."
4557         $RUNAS $DD of=$TESTFILE count=$SIZE ||
4558                 error "failed to write"
4559         # flush cache, ensure noquota flag is set on client
4560         cancel_lru_locks osc
4561         sync; sync_all_data || true
4562
4563         local quota_u=$($LFS quota -u $TSTUSR $DIR)
4564         local quota_g=$($LFS quota -g $TSTUSR $DIR)
4565         local quota_all=$($RUNAS $LFS quota $DIR)
4566
4567         [ "$(echo "$quota_all" | head -n3)" == "$quota_u" ] ||
4568                 error "usr quota not match"
4569         [ "$(echo "$quota_all" | tail -n3)" == "$quota_g" ] ||
4570                 error "grp quota not match"
4571 }
4572 run_test 65 "Check lfs quota result"
4573
4574 test_66() {
4575         ! is_project_quota_supported &&
4576                 skip "Project quota is not supported"
4577         [ "$MDS1_VERSION" -lt $(version_code 2.12.4) ] &&
4578                 skip "Not supported before 2.12.4"
4579         setup_quota_test || error "setup quota failed with $?"
4580         local old=$(do_facet mds1 $LCTL get_param -n \
4581                     mdt.*.enable_chprojid_gid | head -1)
4582         local testdir=$DIR/$tdir/foo
4583
4584         do_facet mds1 $LCTL set_param mdt.*.enable_chprojid_gid=0
4585         stack_trap "do_facet mds1 $LCTL \
4586                 set_param mdt.*.enable_chprojid_gid=$old" EXIT
4587
4588         mkdir_on_mdt0 $testdir || error "failed to mkdir"
4589         chown -R $TSTID:$TSTID $testdir
4590         change_project -sp $TSTPRJID $testdir
4591         $RUNAS mkdir $testdir/foo || error "failed to mkdir foo"
4592
4593         $RUNAS lfs project -p 0 $testdir/foo &&
4594                 error "nonroot user should fail to set projid"
4595
4596         $RUNAS lfs project -C $testdir/foo &&
4597                 error "nonroot user should fail to clear projid"
4598
4599         change_project -C $testdir/foo || error "failed to clear project"
4600
4601         do_facet mds1 $LCTL set_param mdt.*.enable_chprojid_gid=-1
4602         $RUNAS lfs project -p $TSTPRJID $testdir/foo || error \
4603         "failed to set projid with normal user when enable_chprojid_gid=-1"
4604
4605         $RUNAS lfs project -rC $testdir/ || error \
4606 "failed to clear project state with normal user when enable_chprojid_gid=-1"
4607
4608         touch $testdir/bar || error "failed touch $testdir/bar"
4609         $RUNAS lfs project -p $TSTPRJID $testdir/bar && error \
4610         "normal user should not be able to set projid on root owned file"
4611
4612         change_project -p $TSTPRJID $testdir/bar || error \
4613                 "root should be able to change its own file's projid"
4614 }
4615 run_test 66 "nonroot user can not change project state in default"
4616
4617 test_67_write() {
4618         local file="$1"
4619         local qtype="$2"
4620         local size=$3
4621         local _runas=""
4622         local short_qtype=${qtype:0:1}
4623
4624         echo "file "$file
4625         echo "0 $0 1 $1 2 $2 3 $3 4 $4"
4626         case "$4" in
4627                 $TSTUSR)  _runas=$RUNAS;;
4628                 $TSTUSR2) _runas=$RUNAS2;;
4629                 *)          error "unknown quota parameter $4";;
4630         esac
4631
4632         log "Write..."
4633         date
4634         $_runas $DD of=$file count=$size ||
4635                 quota_error $short_qtype $TSTUSR \
4636                         "$qtype write failure, but expect success"
4637         date
4638         cancel_lru_locks osc
4639         date
4640         sync; sync_all_data || true
4641         date
4642 }
4643
4644 getgranted() {
4645         local pool=$1
4646         local ptype=$2
4647         local userid=$3
4648         local qtype=$4
4649         local param=qmt.$FSNAME-QMT0000.$ptype-$pool.glb-$qtype
4650
4651         do_facet mds1 $LCTL get_param $param |
4652                 grep -A2 $userid | awk -F'[, ]*' 'NR==2{print $9}'
4653 }
4654
4655 test_67() {
4656         local limit=20 # MB
4657         local testfile="$DIR/$tdir/$tfile-0"
4658         local testfile2="$DIR/$tdir/$tfile-1"
4659         local testfile3="$DIR/$tdir/$tfile-2"
4660         local qpool="qpool1"
4661         local used
4662         local granted
4663         local granted_mb
4664
4665         mds_supports_qp
4666         [ "$ost1_FSTYPE" == zfs ] &&
4667                 skip "ZFS grants some block space together with inode"
4668
4669         setup_quota_test || error "setup quota failed with $?"
4670
4671         # enable ost quota
4672         set_ost_qtype $QTYPE || error "enable ost quota failed"
4673
4674         # test for user
4675         log "User quota (block hardlimit:$limit MB)"
4676         $LFS setquota -u $TSTUSR -b 0 -B ${limit}M -i 0 -I 0 $DIR ||
4677                 error "set user quota failed"
4678
4679         # make sure the system is clean
4680         used=$(getquota -u $TSTUSR global curspace)
4681         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
4682
4683         granted=$(getgranted "0x0" "dt" $TSTID "usr")
4684         echo "granted 0x0 before write $granted"
4685
4686         # trigger reintegration
4687         local procf="osd-$(facet_fstype ost1).$FSNAME-OST*."
4688         procf=${procf}quota_slave.force_reint
4689         do_facet ost1 $LCTL set_param $procf=1 ||
4690                 error "force reintegration failed"
4691         wait_ost_reint "u" || error "reintegration failed"
4692         granted=$(getgranted "0x0" "dt" $TSTID "usr")
4693         [ $granted -ne 0 ] &&
4694                 error "Granted($granted) for $TSTUSR in $qpool isn't 0."
4695
4696         $LFS setstripe $testfile -c 1 -i 0 || error "setstripe $testfile failed"
4697         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
4698
4699         # write 10 MB to testfile
4700         test_67_write "$testfile" "user" 10 "$TSTUSR"
4701
4702         # create qpool and add OST1
4703         pool_add $qpool || error "pool_add failed"
4704         pool_add_targets $qpool 1 1 || error "pool_add_targets failed"
4705         # as $TSTUSR hasn't limits, lqe may absent. But it should be
4706         # created after the 1st direct qmt_get.
4707         used=$(getquota -u $TSTUSR global bhardlimit $qpool)
4708
4709         # check granted - should be 0, as testfile is located only on OST0
4710         granted=$(getgranted "0x0" "dt" $TSTID "usr")
4711         echo "global granted $granted"
4712         granted=$(getgranted $qpool "dt" $TSTID "usr")
4713         echo "$qpool granted $granted"
4714         [ $granted -ne 0 ] &&
4715                 error "Granted($granted) for $TSTUSR in $qpool isn't 0."
4716
4717         # add OST0 to qpool and check granted space
4718         pool_add_targets $qpool 0 1 ||
4719                 error "pool_add_targets failed"
4720         granted_mb=$(($(getgranted $qpool "dt" $TSTID "usr")/1024))
4721         echo "Granted $granted_mb MB"
4722         #should be 10M + qunit for each OST
4723         [ $granted_mb -ge 10 -a $granted_mb -lt $limit ] ||
4724                 error "Granted($granted_mb) for $TSTUSR in $qpool is wrong."
4725
4726         $LFS setstripe $testfile2 -c 1 -i 1 ||
4727                 error "setstripe $testfile2 failed"
4728         chown $TSTUSR2.$TSTUSR2 $testfile2 || error "chown $testfile2 failed"
4729         # Write from another user and check that qpool1
4730         # shows correct granted, despite $TSTUSR2 hasn't limits in qpool1.
4731         test_67_write "$testfile2" "user" 10 "$TSTUSR2"
4732         used=$(getquota -u $TSTUSR2 global curspace $qpool)
4733         granted=$(getgranted $qpool "dt" $TSTID2 "usr")
4734         [ $granted -ne 0 ] &&
4735                 error "Granted($granted) for $TSTUSR2 in $qpool isn't 0."
4736
4737         # Granted space for $TSTUSR2 in qpool1 should appear only
4738         # when global lqe for this user becomes enforced.
4739         $LFS setquota -u $TSTUSR2 -B ${limit}M $DIR ||
4740                 error "set user quota failed"
4741         granted_mb=$(($(getgranted $qpool "dt" $TSTID2 "usr")/1024))
4742         echo "granted_mb $granted_mb"
4743         [ $granted_mb -ge 10 -a $granted_mb -lt $limit ] ||
4744                 error "Granted($granted) for $TSTUSR in $qpool is wrong."
4745
4746         $LFS setstripe $testfile3 -c 1 -i 0 ||
4747                 error "setstripe $testfile3 failed"
4748         chown $TSTUSR2.$TSTUSR2 $testfile3 || error "chown $testfile3 failed"
4749         test_67_write "$testfile3" "user" 10 "$TSTUSR2"
4750         granted_mb=$(($(getgranted $qpool "dt" $TSTID2 "usr")/1024))
4751         echo "$testfile3 granted_mb $granted_mb"
4752         [ $granted_mb -eq $limit ] ||
4753                 error "Granted($granted_mb) for $TSTUSR2 is not equal to 20M"
4754
4755         # remove OST1 from the qpool1 and check granted space
4756         # should be 0 for TSTUSR and 10M for TSTUSR2
4757         pool_remove_target $qpool 0
4758         granted_mb=$(($(getgranted $qpool "dt" $TSTID "usr")/1024))
4759         [ $granted_mb -eq 0 ] ||
4760                 error "Granted($granted_mb) for $TSTUSR in $qpool != 0."
4761         granted_mb=$(($(getgranted $qpool "dt" $TSTID2 "usr")/1024))
4762         [ $granted_mb -eq 10 ] ||
4763                 error "Granted($granted_mb) for $TSTUSR2 is not equal to 10M"
4764
4765         rm -f $testfile
4766         wait_delete_completed || error "wait_delete_completed failed"
4767         sync_all_data || true
4768         used=$(getquota -u $TSTUSR global curspace)
4769         [ $used -eq 0 ] || quota_error u $TSTUSR \
4770                 "user quota isn't released after deletion"
4771 }
4772 run_test 67 "quota pools recalculation"
4773
4774 get_slave_nr() {
4775         local pool=$1
4776         local qtype=$2
4777         local nr
4778
4779         wait_update_facet mds1 \
4780                 "$LCTL get_param -n qmt.$FSNAME-QMT0000.dt-$pool.info \
4781                         >/dev/null 2>&1 || echo foo" "" ||
4782         error "mds1: failed to create quota pool $pool"
4783
4784         do_facet mds1 $LCTL get_param -n qmt.$FSNAME-QMT0000.dt-$pool.info |
4785                 awk '/usr/ {getline; print $2}'
4786 }
4787
4788 test_68()
4789 {
4790         local qpool="qpool1"
4791
4792         mds_supports_qp
4793         setup_quota_test || error "setup quota failed with $?"
4794
4795         # enable ost quota
4796         set_ost_qtype $QTYPE || error "enable ost quota failed"
4797
4798         # check slave number for glbal pool
4799         local nr=$(get_slave_nr "0x0" "usr")
4800         echo "nr result $nr"
4801         [[ $nr != $((OSTCOUNT + MDSCOUNT)) ]] &&
4802                 error "Slave_nr $nr for global pool != ($OSTCOUNT + $MDSCOUNT)"
4803
4804         # create qpool and add OST1
4805         pool_add $qpool || error "pool_add failed"
4806         nr=$(get_slave_nr $qpool "usr")
4807         [[ $nr != 0 ]] && error "Slave number $nr for $qpool != 0"
4808
4809         # add OST1 to qpool
4810         pool_add_targets $qpool 1 1 || error "pool_add_targets failed"
4811         nr=$(get_slave_nr $qpool "usr")
4812         [[ $nr != 1 ]] && error "Slave number $nr for $qpool != 1"
4813
4814         # add OST0 to qpool
4815         pool_add_targets $qpool 0 1 || error "pool_add_targets failed"
4816         nr=$(get_slave_nr $qpool "usr")
4817         [[ $nr != 2 ]] && error "Slave number $nr for $qpool != 2"
4818
4819         # remove OST0
4820         pool_remove_target $qpool 0
4821         nr=$(get_slave_nr $qpool "usr")
4822         [[ $nr != 1 ]] && error "Slave number $nr for $qpool != 1"
4823
4824         # remove OST1
4825         pool_remove_target $qpool 1
4826         nr=$(get_slave_nr $qpool "usr")
4827         [[ $nr != 0 ]] && error "Slave number $nr for $qpool != 0"
4828
4829         # Check again that all is fine with global pool
4830         nr=$(get_slave_nr "0x0" "usr")
4831         [[ $nr == $((OSTCOUNT + MDSCOUNT)) ]] ||
4832                 error "Slave_nr $nr for global pool != ($OSTCOUNT + $MDSCOUNT)"
4833 }
4834 run_test 68 "slave number in quota pool changed after each add/remove OST"
4835
4836 test_69()
4837 {
4838         local global_limit=200 # MB
4839         local limit=10 # MB
4840         local testfile="$DIR/$tdir/$tfile-0"
4841         local dom0="$DIR/$tdir/dom0"
4842         local qpool="qpool1"
4843
4844         mds_supports_qp
4845         setup_quota_test || error "setup quota failed with $?"
4846
4847         # enable ost quota
4848         set_ost_qtype $QTYPE || error "enable ost quota failed"
4849         set_mdt_qtype $QTYPE || error "enable mdt quota failed"
4850
4851         # Save DOM only at MDT0
4852         $LFS setdirstripe -c 1 -i 0 $dom0 || error "cannot create $dom0"
4853         $LFS setstripe -E 1M $dom0 -L mdt || error "setstripe to $dom0 failed"
4854         chmod 0777 $dom0
4855         $LFS setstripe -c 1 -i 0 "$DIR/$tdir/"
4856
4857         # create qpool and add OST0
4858         pool_add $qpool || error "pool_add failed"
4859         pool_add_targets $qpool 0 0 || error "pool_add_targets failed"
4860
4861         log "User quota (block hardlimit:$global_limit MB)"
4862         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
4863                 error "set user quota failed"
4864
4865         log "User quota (block hardlimit:$limit MB)"
4866         $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR ||
4867                 error "set user quota failed"
4868
4869         $RUNAS dd if=/dev/zero of="$dom0/f1" bs=1K count=512 oflag=sync ||
4870                 quota_error u $TSTUSR "write failed"
4871
4872         $RUNAS dd if=/dev/zero of="$dom0/f1" bs=1K count=512 seek=512 \
4873                 oflag=sync || quota_error u $TSTUSR "write failed"
4874
4875         $RUNAS $DD of=$testfile count=$limit || true
4876
4877         # flush cache, ensure noquota flag is set on client
4878         cancel_lru_locks osc
4879         sync; sync_all_data || true
4880
4881         # MDT0 shouldn't get EDQUOT with glimpse.
4882         $RUNAS $DD of=$testfile count=$limit seek=$limit &&
4883                 quota_error u $TSTUSR \
4884                         "user write success, but expect EDQUOT"
4885
4886         # Now all members of qpool1 should get EDQUOT. Expect success
4887         # when write to DOM on MDT0, as it belongs to global pool.
4888         $RUNAS dd if=/dev/zero of="$dom0/f1" bs=1K count=512 \
4889                 oflag=sync || quota_error u $TSTUSR "write failed"
4890
4891         $RUNAS dd if=/dev/zero of="$dom0/f1" bs=1K count=512 seek=512 \
4892                 oflag=sync || quota_error u $TSTUSR "write failed"
4893 }
4894 run_test 69 "EDQUOT at one of pools shouldn't affect DOM"
4895
4896 test_70a()
4897 {
4898         local qpool="qpool1"
4899         local limit=20 # MB
4900         local err=0
4901         local bhard
4902
4903         [[ CLIENT_VERSION -lt $(version_code $VERSION_WITH_QP) ]] &&
4904                 skip "Needs a client >= $VERSION_WITH_QP"
4905
4906         setup_quota_test || error "setup quota failed with $?"
4907
4908         # MDS returns EFAULT for unsupported quotactl command
4909         [[ $MDS1_VERSION -lt $(version_code $VERSION_WITH_QP) ]] && err=14
4910
4911         # create qpool and add OST0
4912         pool_add $qpool || error "pool_add failed"
4913         pool_add_targets $qpool 0 0 || error "pool_add_targets failed"
4914
4915         $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR
4916         rc=$?
4917         [ $rc -eq $err ] || error "setquota res $rc != $err"
4918
4919         # If MDS supports QP, check that limit was set properly.
4920         if [[ $MDS1_VERSION -ge $(version_code $VERSION_WITH_QP) ]]; then
4921                 bhard=$(getquota -u $TSTUSR global bhardlimit $qpool)
4922                 echo "hard limit $bhard limit $limit"
4923                 [ $bhard -ne $((limit*1024)) ] &&
4924                         error "bhard:$bhard for $qpool!=$((limit*1024))"
4925         fi
4926
4927         $LFS quota -u $TSTUSR --pool $qpool $DIR
4928         rc=$?
4929         [ $rc -eq $err ] || error "quota res $rc != $err"
4930 }
4931 run_test 70a "check lfs setquota/quota with a pool option"
4932
4933 test_70b()
4934 {
4935         local glbl_hard=200 # 200M
4936         local glbl_soft=100 # 100M
4937         local pool_hard=10 # 10M
4938         local qpool="qpool1"
4939
4940         pool_add $qpool || error "pool_add failed"
4941         pool_add_targets $qpool 0 1 || error "pool_add_targets failed"
4942
4943         $LFS setquota -u $TSTUSR -b ${glbl_soft}M -B ${glbl_hard}M $DIR ||
4944                 error "set user quota failed"
4945         $LFS setquota -u $TSTUSR -B ${pool_hard}M --pool $qpool $DIR ||
4946                 error "set user quota failed"
4947
4948         local tmp=$(getquota -u $TSTUSR global bhardlimit $qpool)
4949         [ $tmp -eq $((pool_hard * 1024)) ] ||
4950                 error "wrong block hard limit $tmp for $qpool"
4951         local tmp=$(getquota -u $TSTUSR global bsoftlimit $qpool)
4952         # soft limit hasn't been set and should be zero
4953         [ $tmp -eq 0 ] || error "wrong soft block limit $tmp for $qpool"
4954 }
4955 run_test 70b "lfs setquota pool works properly"
4956
4957 test_71a()
4958 {
4959         local limit=10 # MB
4960         local global_limit=100 # MB
4961         local testfile="$DIR/$tdir/$tfile-0"
4962         local qpool="qpool1"
4963         local qpool2="qpool2"
4964
4965         [ "$ost1_FSTYPE" == zfs ] &&
4966                 skip "ZFS grants some block space together with inode"
4967         [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs"
4968         mds_supports_qp
4969         setup_quota_test || error "setup quota failed with $?"
4970
4971         # enable ost quota
4972         set_ost_qtype $QTYPE || error "enable ost quota failed"
4973
4974         # test for user
4975         log "User quota (block hardlimit:$global_limit MB)"
4976         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
4977                 error "set user quota failed"
4978
4979         pool_add $qpool || error "pool_add failed"
4980         pool_add_targets $qpool 0 1 ||
4981                 error "pool_add_targets failed"
4982
4983         $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR ||
4984                 error "set user quota failed"
4985
4986         pool_add $qpool2 || error "pool_add failed"
4987         pool_add_targets $qpool2 1 1 ||
4988                 error "pool_add_targets failed"
4989
4990         $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool2 $DIR ||
4991                 error "set user quota failed"
4992
4993         # make sure the system is clean
4994         local used=$(getquota -u $TSTUSR global curspace)
4995
4996         echo "used $used"
4997         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
4998
4999         # create 1st component 1-10M
5000         $LFS setstripe -E 10M -S 1M -c 1 -i 0 $testfile
5001         #create 2nd component 10-30M
5002         $LFS setstripe --component-add -E 30M -c 1 -i 1 $testfile
5003         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
5004
5005         # сheck normal use and out of quota with PFL
5006         # 1st element is in qppol1(OST0), 2nd in qpool2(OST2).
5007         test_1_check_write $testfile "user" $((limit*2))
5008         rm -f $testfile
5009         wait_delete_completed || error "wait_delete_completed failed"
5010         sync_all_data || true
5011         used=$(getquota -u $TSTUSR global curspace)
5012         [ $used -ne 0 ] && quota_error u $TSTUSR \
5013                 "user quota isn't released after deletion"
5014
5015         # create 1st component 1-10M
5016         $LFS setstripe -E 10M -S 1M -c 1 -i 0 $testfile
5017         # create 2nd component 10-30M
5018         $LFS setstripe --component-add -E 30M -c 1 -i 1 $testfile
5019         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
5020
5021         # write to the 2nd component
5022         $RUNAS $DD of=$testfile count=$limit seek=10 ||
5023                 quota_error u $TSTUSR \
5024                         "write failure, but expect success"
5025         # this time maybe cache write,  ignore it's failure
5026         $RUNAS $DD of=$testfile count=$((2*limit)) seek=10 || true
5027         cancel_lru_locks osc
5028         sync; sync_all_data || true
5029         # write over limit in qpool2(2nd component 10-30M)
5030         $RUNAS $DD of=$testfile count=1 seek=$((10 + 2*limit)) &&
5031                 quota_error u $TSTUSR "user write success, but expect EDQUOT"
5032         # write to the 1st component - OST0 is empty
5033         $RUNAS $DD of=$testfile count=$limit seek=0 ||
5034                 quota_error u $TSTUSR "write failed"
5035 }
5036 run_test 71a "Check PFL with quota pools"
5037
5038 test_71b()
5039 {
5040         local global_limit=1000 # MB
5041         local limit1=160 # MB
5042         local limit2=10 # MB
5043         local testfile="$DIR/$tdir/$tfile-0"
5044         local qpool="qpool1"
5045         local qpool2="qpool2"
5046
5047         [ "$ost1_FSTYPE" == zfs ] &&
5048                 skip "ZFS grants some block space together with inode"
5049         [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs" && return
5050         mds_supports_qp
5051         setup_quota_test || error "setup quota failed with $?"
5052
5053         # enable ost quota
5054         set_ost_qtype $QTYPE || error "enable ost quota failed"
5055
5056         # test for user
5057         log "User quota (block hardlimit:$global_limit MB)"
5058         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
5059                 error "set user quota failed"
5060
5061         pool_add $qpool || error "pool_add failed"
5062         pool_add_targets $qpool 0 1 ||
5063                 error "pool_add_targets failed"
5064
5065         $LFS setquota -u $TSTUSR -B ${limit1}M --pool $qpool $DIR ||
5066                 error "set user quota failed"
5067
5068         pool_add $qpool2 || error "pool_add failed"
5069         pool_add_targets $qpool2 1 1 ||
5070                 error "pool_add_targets failed"
5071
5072         $LFS setquota -u $TSTUSR -B ${limit2}M --pool $qpool2 $DIR ||
5073                 error "set user quota failed"
5074
5075         # make sure the system is clean
5076         local used=$(getquota -u $TSTUSR global curspace)
5077
5078         echo "used $used"
5079         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
5080
5081         # First component is on OST0, 2nd on OST1
5082         $LFS setstripe -E 128M -i 0 -z 64M -E -1 -i 1 -z 64M $testfile
5083         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
5084
5085         # fill the 1st component on OST0
5086         $RUNAS $DD of=$testfile count=128 ||
5087                 quota_error u $TSTUSR "write failed"
5088         # write to the 2nd cmpnt on OST1
5089         $RUNAS $DD of=$testfile count=$((limit2/2)) seek=128 ||
5090                 quota_error u $TSTUSR "write failed"
5091         # this time maybe cache write,  ignore it's failure
5092         $RUNAS $DD of=$testfile count=$((limit2/2)) seek=$((128 + limit2/2)) ||
5093                 true
5094         cancel_lru_locks osc
5095         sync; sync_all_data || true
5096         # write over limit in qpool2
5097         $RUNAS $DD of=$testfile count=2 seek=$((128 + limit2)) &&
5098                 quota_error u $TSTUSR "user write success, but expect EDQUOT"
5099         return 0
5100 }
5101 run_test 71b "Check SEL with quota pools"
5102
5103 test_72()
5104 {
5105         local limit=10 # MB
5106         local global_limit=50 # MB
5107         local testfile="$DIR/$tdir/$tfile-0"
5108         local qpool="qpool1"
5109
5110         mds_supports_qp
5111         setup_quota_test || error "setup quota failed with $?"
5112
5113         # enable ost quota
5114         set_ost_qtype $QTYPE || error "enable ost quota failed"
5115
5116         # test for user
5117         log "User quota (block hardlimit:$global_limit MB)"
5118         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
5119                 error "set user quota failed"
5120
5121         pool_add $qpool || error "pool_add failed"
5122         pool_add_targets $qpool 1 1 || error "pool_add_targets failed"
5123
5124         $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR ||
5125                 error "set user quota failed"
5126
5127         # make sure the system is clean
5128         local used=$(getquota -u $TSTUSR global curspace)
5129         echo "used $used"
5130         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
5131
5132         used=$(getquota -u $TSTUSR global bhardlimit $qpool)
5133
5134         $LFS setstripe $testfile -c 1 -i 1 || error "setstripe $testfile failed"
5135         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
5136         test_1_check_write $testfile "user" $limit
5137         used=$(getquota -u $TSTUSR global bhardlimit $qpool)
5138         echo "used $used"
5139         [ $used -ge $limit ] || error "used($used) is less than limit($limit)"
5140         # check that lfs quota -uv --pool prints only OST that
5141         # was added in a pool
5142         lfs quota -v -u $TSTUSR --pool $qpool $DIR | grep -v "OST0001" |
5143                 grep "OST\|MDT" && error "$qpool consists wrong targets"
5144         return 0
5145 }
5146 run_test 72 "lfs quota --pool prints only pool's OSTs"
5147
5148 test_73a()
5149 {
5150         local qpool="qpool1"
5151
5152         mds_supports_qp
5153
5154         pool_add $qpool || error "pool_add failed"
5155         pool_add_targets $qpool 0 $((OSTCOUNT - 1)) ||
5156                 error "pool_add_targets failed"
5157
5158         test_default_quota "-u" "data" "qpool1"
5159 }
5160 run_test 73a "default limits at OST Pool Quotas"
5161
5162 test_73b()
5163 {
5164         local TESTFILE1="$DIR/$tdir/$tfile-1"
5165         local limit=20 #20M
5166         local qpool="qpool1"
5167
5168         mds_supports_qp
5169
5170         setup_quota_test || error "setup quota failed with $?"
5171         quota_init
5172         set_ost_qtype $QTYPE || error "enable ost quota failed"
5173
5174         # pool quotas don't work properly without global limit
5175         $LFS setquota -u $TSTUSR -b 0 -B ${limit}M -i 0 -I 0 $DIR ||
5176                 error "set global limit failed"
5177
5178         pool_add $qpool || error "pool_add failed"
5179         pool_add_targets $qpool 0 $((OSTCOUNT - 1)) ||
5180                 error "pool_add_targets failed"
5181
5182         log "set default quota for $qpool"
5183         $LFS setquota -U --pool $qpool -b ${limit}M -B ${limit}M $DIR ||
5184                 error "set default quota failed"
5185
5186         log "Write from user that hasn't lqe"
5187         # Check that it doesn't cause a panic or a deadlock
5188         # due to nested lqe lookups that rewrite 1st lqe in qti_lqes array.
5189         # Have to use RUNAS_ID as resetquota creates lqes in
5190         # the beginning for TSTUSR/TSTUSR2 when sets limits to 0.
5191         runas -u $RUNAS_ID -g $RUNAS_GID $DD of=$TESTFILE1 count=10
5192
5193         cancel_lru_locks osc
5194         sync; sync_all_data || true
5195 }
5196 run_test 73b "default OST Pool Quotas limit for new user"
5197
5198 test_74()
5199 {
5200         local global_limit=200 # 200M
5201         local limit=10 # 10M
5202         local limit2=50 # 50M
5203         local qpool="qpool1"
5204         local qpool2="qpool2"
5205         local tmp=0
5206
5207         mds_supports_qp
5208         setup_quota_test || error "setup quota failed with $?"
5209
5210         # enable ost quota
5211         set_ost_qtype $QTYPE || error "enable ost quota failed"
5212
5213         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
5214                 error "set user quota failed"
5215
5216         pool_add $qpool || error "pool_add failed"
5217         pool_add_targets $qpool 0 1 ||
5218                 error "pool_add_targets failed"
5219
5220         $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR ||
5221                 error "set user quota failed"
5222
5223         pool_add $qpool2 || error "pool_add failed"
5224         pool_add_targets $qpool2 1 1 ||
5225                 error "pool_add_targets failed"
5226
5227         $LFS setquota -u $TSTUSR -B ${limit2}M --pool $qpool2 $DIR ||
5228                 error "set user quota failed"
5229
5230         tmp=$(getquota -u $TSTUSR global bhardlimit)
5231         [ $tmp -eq $((global_limit * 1024)) ] ||
5232                 error "wrong global limit $global_limit"
5233
5234         tmp=$(getquota -u $TSTUSR global bhardlimit $qpool)
5235         [ $tmp -eq $((limit * 1024)) ] || error "wrong limit $tmp for $qpool"
5236
5237         tmp=$(getquota -u $TSTUSR global bhardlimit $qpool2)
5238         [ $tmp -eq $((limit2 * 1024)) ] || error "wrong limit $tmp for $qpool2"
5239
5240         # check limits in pools
5241         tmp=$($LFS quota -u $TSTUSR --pool $DIR | \
5242               grep -A4 $qpool | awk 'NR == 4{print $4}')
5243         echo "pool limit for $qpool $tmp"
5244         [ $tmp -eq $((limit * 1024)) ] || error "wrong limit:tmp for $qpool"
5245         tmp=$($LFS quota -u $TSTUSR --pool $DIR | \
5246               grep -A4 $qpool2 | awk 'NR == 4{print $4}')
5247         echo "pool limit for $qpool2 $tmp"
5248         [ $tmp -eq $((limit2 * 1024)) ] || error "wrong limit:$tmp for $qpool2"
5249 }
5250 run_test 74 "check quota pools per user"
5251
5252 function cleanup_quota_test_75()
5253 {
5254         do_facet mgs $LCTL nodemap_modify --name default \
5255                 --property admin --value 1
5256         do_facet mgs $LCTL nodemap_modify --name default \
5257                 --property trusted --value 1
5258         do_facet mgs $LCTL nodemap_modify --name default \
5259                 --property squash_uid --value 99
5260         do_facet mgs $LCTL nodemap_modify --name default \
5261                 --property squash_gid --value 99
5262
5263         wait_nm_sync default admin_nodemap
5264         wait_nm_sync default trusted_nodemap
5265
5266         do_facet mgs $LCTL nodemap_activate 0
5267         wait_nm_sync active
5268
5269         resetquota -u $TSTUSR
5270 }
5271
5272 test_dom_75() {
5273         local dd_failed=false
5274         local LIMIT=20480 #20M
5275         local qid=$TSTID
5276
5277         for ((i = 0; i < $((LIMIT/2048-1)); i++)); do
5278                 $DD of=$DIR/$tdir_dom/$tfile-$i count=1 \
5279                         conv=fsync || dd_failed=true
5280         done
5281
5282         $dd_failed && quota_error u $qid "write failed, expect succeed (1)"
5283
5284         for ((i = $((LIMIT/2048-1)); i < $((LIMIT/1024 + 10)); i++)); do
5285                 $DD of=$DIR/$tdir_dom/$tfile-$i count=1 \
5286                         conv=fsync || dd_failed=true
5287         done
5288
5289         $dd_failed || quota_error u $qid "write succeed, expect EDQUOT (1)"
5290
5291         rm -f $DIR/$tdir_dom/*
5292
5293         # flush cache, ensure noquota flag is set on client
5294         cancel_lru_locks
5295         sync; sync_all_data || true
5296
5297         dd_failed=false
5298
5299         $DD of=$DIR/$tdir/file count=$((LIMIT/2048-1)) conv=fsync ||
5300                 quota_error u $qid "write failed, expect succeed (2)"
5301
5302         for ((i = 0; i < $((LIMIT/2048 + 10)); i++)); do
5303                 $DD of=$DIR/$tdir_dom/$tfile-$i count=1 \
5304                         conv=fsync || dd_failed=true
5305         done
5306
5307         $dd_failed || quota_error u $TSTID "write succeed, expect EDQUOT (2)"
5308
5309         rm -f $DIR/$tdir/*
5310         rm -f $DIR/$tdir_dom/*
5311
5312         # flush cache, ensure noquota flag is set on client
5313         cancel_lru_locks
5314         sync; sync_all_data || true
5315
5316         dd_failed=false
5317
5318         for ((i = 0; i < $((LIMIT/2048-1)); i++)); do
5319                 $DD of=$DIR/$tdir_dom/$tfile-$i count=1 \
5320                         conv=fsync || dd_failed=true
5321         done
5322
5323         $dd_failed && quota_error u $qid "write failed, expect succeed (3)"
5324
5325         $DD of=$DIR/$tdir/file count=$((LIMIT/2048 + 10)) conv=fsync &&
5326                 quota_error u $qid "write succeed, expect EDQUOT (3)"
5327         true
5328 }
5329
5330 test_75()
5331 {
5332         local soft_limit=10 # MB
5333         local hard_limit=20 # MB
5334         local limit=$soft_limit
5335         local testfile="$DIR/$tdir/$tfile-0"
5336         local grace=20 # seconds
5337         local tdir_dom=${tdir}_dom
5338
5339         if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
5340             grace=60
5341         fi
5342
5343         setup_quota_test || error "setup quota failed with $?"
5344         stack_trap cleanup_quota_test_75 EXIT
5345
5346         # enable ost quota
5347         set_ost_qtype $QTYPE || error "enable ost quota failed"
5348         set_mdt_qtype $QTYPE || error "enable mdt quota failed"
5349
5350         local used=$(getquota -u $TSTID global curspace)
5351         $LFS setquota -t -u --block-grace $grace --inode-grace \
5352                 $MAX_IQ_TIME $DIR || error "set user grace time failed"
5353         $LFS setquota -u $TSTUSR -b $((soft_limit+used/1024))M \
5354                         -B $((hard_limit+used/1024))M -i 0 -I 0 $DIR ||
5355                 error "set user quota failed"
5356
5357         chmod 777 $DIR/$tdir || error "chmod 777 $DIR/$tdir failed"
5358         mkdir $DIR/$tdir_dom
5359         chmod 777 $DIR/$tdir_dom
5360         $LFS setstripe -E 1M -L mdt $DIR/$tdir_dom ||
5361                 error "setstripe $tdir_dom failed"
5362
5363         do_facet mgs $LCTL nodemap_activate 1
5364         wait_nm_sync active
5365         do_facet mgs $LCTL nodemap_modify --name default \
5366                 --property admin --value 0
5367         do_facet mgs $LCTL nodemap_modify --name default \
5368                 --property trusted --value 0
5369         do_facet mgs $LCTL nodemap_modify --name default \
5370                 --property deny_unknown --value 0
5371         do_facet mgs $LCTL nodemap_modify --name default \
5372                 --property squash_uid --value $TSTID
5373         do_facet mgs $LCTL nodemap_modify --name default \
5374                 --property squash_gid --value $TSTID
5375         cancel_lru_locks mdc
5376         wait_nm_sync default admin_nodemap
5377         wait_nm_sync default trusted_nodemap
5378         wait_nm_sync default squash_uid
5379
5380         # mmap write when over soft limit
5381         limit=$soft_limit
5382         $DD of=$testfile count=${limit} ||
5383                 quota_error a  "root write failure, but expect success (1)"
5384         OFFSET=$((limit * 1024))
5385         cancel_lru_locks osc
5386
5387         echo "Write to exceed soft limit"
5388         dd if=/dev/zero of=$testfile bs=1K count=10 seek=$OFFSET ||
5389               quota_error a $TSTUSR "root write failure, but expect success (2)"
5390         OFFSET=$((OFFSET + 1024)) # make sure we don't write to same block
5391         cancel_lru_locks osc
5392
5393         echo "mmap write when over soft limit"
5394         $MULTIOP $testfile.mmap OT40960SMW ||
5395                 quota_error a $TSTUSR "mmap write failure, but expect success"
5396         cancel_lru_locks osc
5397         rm -f $testfile*
5398         wait_delete_completed || error "wait_delete_completed failed (1)"
5399         sync_all_data || true
5400
5401         # test for user hard limit
5402         limit=$hard_limit
5403         log "Write..."
5404         $DD of=$testfile bs=1M count=$((limit/2)) ||
5405                 quota_error u $TSTID \
5406                         "root write failure, but expect success (3)"
5407
5408         log "Write out of block quota ..."
5409         # possibly a cache write, ignore failure
5410         $DD of=$testfile bs=1M count=$((limit/2)) seek=$((limit/2)) || true
5411         # flush cache, ensure noquota flag is set on client
5412         cancel_lru_locks osc
5413         sync; sync_all_data || true
5414         # sync forced cache flush, but did not guarantee that slave
5415         # got new edquot through glimpse, so wait to make sure
5416         sleep 5
5417         $DD of=$testfile bs=1M count=1 seek=$limit conv=fsync &&
5418                 quota_error u $TSTID \
5419                         "user write success, but expect EDQUOT"
5420         rm -f $testfile
5421         wait_delete_completed || error "wait_delete_completed failed (2)"
5422         sync_all_data || true
5423         [ $(getquota -u $TSTUSR global curspace) -eq $used ] ||
5424                 quota_error u $TSTID "user quota not released after deletion"
5425
5426         test_dom_75
5427 }
5428 run_test 75 "nodemap squashed root respects quota enforcement"
5429
5430 test_76() {
5431         ! is_project_quota_supported &&
5432                 skip "skip project quota unsupported"
5433
5434         setup_quota_test || error "setup quota failed with $?"
5435         quota_init
5436
5437         local testfile="$DIR/$tdir/$tfile-0"
5438
5439         touch $testfile
5440         $LFS project -p 4294967295 $testfile &&
5441                 error "set project ID should fail"
5442         return 0
5443 }
5444 run_test 76 "project ID 4294967295 should be not allowed"
5445
5446 test_77()
5447 {
5448         mount_client $MOUNT2 "ro"
5449         lfs setquota -u $TSTUSR -b 100M -B 100M -i 10K -I 10K $MOUNT2 &&
5450                 error "lfs setquota should fail in read-only Lustre mount"
5451         umount $MOUNT2
5452 }
5453 run_test 77 "lfs setquota should fail in Lustre mount with 'ro'"
5454
5455 test_78()
5456 {
5457         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
5458                 skip "need OST at least 2.14.55"
5459         check_set_fallocate_or_skip
5460
5461         setup_quota_test || error "setup quota failed with $?"
5462
5463         # enable ost quota
5464         set_ost_qtype $QTYPE || error "enable ost quota failed"
5465
5466         mkdir -p $DIR/$tdir || error "failed to create $tdir"
5467         chown $TSTUSR $DIR/$tdir || error "failed to chown $tdir"
5468
5469         # setup quota limit
5470         $LFS setquota -u $TSTUSR -b25M -B25M $DIR/$tdir ||
5471                 error "lfs setquota failed"
5472
5473         # call fallocate
5474         runas -u $TSTUSR -g $TSTUSR fallocate -l 204800 $DIR/$tdir/$tfile
5475
5476         kbytes=$(lfs quota -u $TSTUSR $DIR |
5477                 awk -v pattern=$DIR 'match($0, pattern) {printf $2}')
5478         echo "kbytes returned:$kbytes"
5479
5480         # For file size of 204800. We should be having roughly 200 kbytes
5481         # returned. Anything alarmingly low (50 taken as arbitrary value)
5482         # would bail out this TC. Also this also avoids $kbytes of 0
5483         # to be used in calculation below.
5484         (( $kbytes > 50 )) ||
5485                 error "fallocate did not use quota. kbytes returned:$kbytes"
5486
5487         local expect_lo=$(($kbytes * 95 / 100)) # 5% below
5488         local expect_hi=$(($kbytes * 105 / 100)) # 5% above
5489
5490         # Verify kbytes is 200 (204800/1024). With a permited  5% drift
5491         (( $kbytes >= $expect_lo && $kbytes <= $expect_hi )) ||
5492                 error "fallocate did not use quota correctly"
5493 }
5494 run_test 78 "Check fallocate increase quota usage"
5495
5496 test_78a()
5497 {
5498         (( $CLIENT_VERSION >= $(version_code 2.15.0) )) ||
5499                 skip "need client at least 2.15.0"
5500         (( $OST1_VERSION >= $(version_code 2.15.0) )) ||
5501                 skip "need OST at least 2.15.0"
5502         check_set_fallocate_or_skip
5503
5504         setup_quota_test || error "setup quota failed with $?"
5505
5506         # enable ost quota
5507         set_ost_qtype $QTYPE || error "enable ost quota failed"
5508
5509         mkdir -p $DIR/$tdir || error "failed to create $tdir"
5510
5511         local projectid=5200 # Random project id to test
5512
5513         change_project -sp $projectid $DIR/$tdir
5514
5515         # setup quota limit
5516         $LFS setquota -p $projectid -b25M -B25M $DIR/$tdir ||
5517                 error "lfs setquota project failed"
5518
5519         # call fallocate
5520         fallocate -l 204800 $DIR/$tdir/$tfile
5521
5522         # Get curspace (kbytes) for $projectid
5523         local kbytes=$(getquota -p $projectid global curspace)
5524
5525         echo "kbytes returned:$kbytes"
5526
5527         # For file size of 204800. We should be having roughly 200 kbytes
5528         # returned. Anything alarmingly low (50 taken as arbitrary value)
5529         # would bail out this TC. Also this also avoids $kbytes of 0
5530         # to be used in calculation below.
5531         (( $kbytes > 50 )) ||
5532                 error "fallocate did not use projectid. kbytes returned:$kbytes"
5533
5534         local expect_lo=$(($kbytes * 95 / 100)) # 5% below
5535         local expect_hi=$(($kbytes * 105 / 100)) # 5% above
5536
5537         # Verify kbytes is 200 (204800/1024). With a permited  5% drift
5538         (( $kbytes >= $expect_lo && $kbytes <= $expect_hi )) ||
5539                 error "fallocate did not use quota projectid correctly"
5540 }
5541 run_test 78a "Check fallocate increase projectid usage"
5542
5543 test_79()
5544 {
5545         local qpool="qpool1"
5546         local cmd="$LCTL get_param -n qmt.$FSNAME-QMT0000.dt-$qpool.info"
5547         local stopf=$TMP/$tfile
5548
5549         do_facet mds1 "touch $stopf"
5550         stack_trap "do_facet mds1 'rm -f $stopf'"
5551         do_facet mds1 "while [ -e $stopf ]; do $cmd &>/dev/null; done"&
5552         local pid=$!
5553         pool_add $qpool || error "pool_add failed"
5554         do_facet mds1 "rm $stopf"
5555         wait $pid
5556 }
5557 run_test 79 "access to non-existed dt-pool/info doesn't cause a panic"
5558
5559 test_80()
5560 {
5561         local dir1="$DIR/$tdir/dir1"
5562         local dir2="$DIR/$tdir/dir2"
5563         local TESTFILE0="$dir1/$tfile-0"
5564         local TESTFILE1="$dir1/$tfile-1"
5565         local TESTFILE2="$dir1/$tfile-2"
5566         local TESTFILE3="$dir2/$tfile-0"
5567         local global_limit=100 # 100M
5568         local limit=10 # 10M
5569         local qpool="qpool1"
5570
5571         [ "$OSTCOUNT" -lt "2" ] && skip "needs >= 2 OSTs"
5572         mds_supports_qp
5573         [ "$ost1_FSTYPE" == zfs ] &&
5574                 skip "ZFS grants some block space together with inode"
5575         setup_quota_test || error "setup quota failed with $?"
5576         set_ost_qtype $QTYPE || error "enable ost quota failed"
5577
5578         # make sure the system is clean
5579         local used=$(getquota -u $TSTUSR global curspace)
5580         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR is not 0."
5581
5582         pool_add $qpool || error "pool_add failed"
5583         pool_add_targets $qpool 0 1 ||
5584                 error "pool_add_targets failed"
5585
5586         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
5587                 error "set user quota failed"
5588
5589         $LFS setquota -u $TSTUSR -B ${global_limit}M --pool $qpool $DIR ||
5590                 error "set user quota failed"
5591         $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR ||
5592                 error "set user quota failed"
5593
5594         mkdir -p $dir1 || error "failed to mkdir"
5595         chown $TSTUSR.$TSTUSR $dir1 || error "chown $dir1 failed"
5596         mkdir -p $dir2 || error "failed to mkdir"
5597         chown $TSTUSR.$TSTUSR $dir2 || error "chown $dir2 failed"
5598
5599         $LFS setstripe $dir1 -i 1 -c 1|| error "setstripe $testfile failed"
5600         $LFS setstripe $dir2 -i 0 -c 1|| error "setstripe $testfile failed"
5601         lfs getstripe $dir1
5602         lfs getstripe $dir2
5603         sleep 3
5604
5605         $LFS quota -uv $TSTUSR $DIR
5606         #define OBD_FAIL_QUOTA_PREACQ            0xA06
5607         do_facet mds1 $LCTL set_param fail_loc=0xa06
5608         $RUNAS $DD of=$TESTFILE3 count=3 ||
5609                 quota_error u $TSTUSR "write failed"
5610         $RUNAS $DD of=$TESTFILE2 count=7 ||
5611                 quota_error u $TSTUSR "write failed"
5612         $RUNAS $DD of=$TESTFILE1 count=1 oflag=direct ||
5613                 quota_error u $TSTUSR "write failed"
5614         sync
5615         sleep 3
5616         $LFS quota -uv --pool $qpool $TSTUSR $DIR
5617
5618         rm -f $TESTFILE2
5619         stop ost2
5620         do_facet mds1 $LCTL set_param fail_loc=0
5621         start ost2 $(ostdevname 2) $OST_MOUNT_OPTS || error "start ost2 failed"
5622         $LFS quota -uv $TSTUSR --pool $qpool $DIR
5623         # OST0 needs some time to update quota usage after removing TESTFILE2
5624         sleep 4
5625         $LFS quota -uv $TSTUSR --pool $qpool $DIR
5626         $RUNAS $DD of=$TESTFILE0 count=2 oflag=direct ||
5627                 quota_error u $TSTUSR "write failure, but expect success"
5628 }
5629 run_test 80 "check for EDQUOT after OST failover"
5630
5631 test_81() {
5632         local global_limit=20  # 100M
5633         local testfile="$DIR/$tdir/$tfile-0"
5634         local qpool="qpool1"
5635
5636         mds_supports_qp
5637         setup_quota_test || error "setup quota failed with $?"
5638
5639         # enable ost quota
5640         set_ost_qtype $QTYPE || error "enable ost quota failed"
5641
5642         # test for user
5643         log "User quota (block hardlimit:$global_limit MB)"
5644         $LFS setquota -u $TSTUSR -B 1G $DIR || error "set user quota failed"
5645
5646         pool_add $qpool || error "pool_add failed"
5647         #define OBD_FAIL_QUOTA_RECALC   0xA07
5648         do_facet mds1 $LCTL set_param fail_loc=0x80000A07 fail_val=30
5649         # added OST casues to start pool recalculation
5650         pool_add_targets $qpool 0 0 1
5651         stop mds1 -f || error "MDS umount failed"
5652
5653         #start mds1 back to destroy created pool
5654         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
5655         clients_up || true
5656 }
5657 run_test 81 "Race qmt_start_pool_recalc with qmt_pool_free"
5658
5659 test_82()
5660 {
5661         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
5662                 skip "need MDS 2.14.55 or later"
5663         is_project_quota_supported ||
5664                 skip "skip project quota unsupported"
5665
5666         setup_quota_test || error "setup quota failed with $?"
5667         quota_init
5668
5669         local parent_dir="$DIR/$tdir.parent"
5670         local child_dir="$parent_dir/child"
5671
5672         mkdir -p $child_dir
5673         stack_trap "chown -R 0:0 $parent_dir"
5674
5675         chown $TSTUSR:$TSTUSR $parent_dir ||
5676                 error "failed to chown on $parent_dir"
5677         chown $TSTUSR2:$TSTUSRS2 $child_dir ||
5678                 error "failed to chown on $parent_dir"
5679
5680         $LFS project -p 1000 $parent_dir ||
5681                 error "failed to set project id on $parent_dir"
5682         $LFS project -p 1001 $child_dir ||
5683                 error "failed to set project id on $child_dir"
5684
5685         rmdir $child_dir || error "cannot remove child dir, test failed"
5686 }
5687 run_test 82 "verify more than 8 qids for single operation"
5688
5689 test_grace_with_default_quota()
5690 {
5691         local qtype=$1
5692         local qdtype=$2
5693         local bgrace
5694         local igrace
5695         local bgrace2
5696         local igrace2
5697         echo "ttt1"
5698         $LFS setquota $qdtype -b 0 -B 0 -i 0 -I 0 $DIR ||
5699                 error "clear default quota [$qdtype] failed"
5700         echo "ttt2"
5701         $LFS setquota -t $qtype --block-grace 1w --inode-grace 1w $DIR ||
5702                 error "reset quota [$qdtype] grace failed"
5703         echo "ttt3"
5704
5705         eval $($LFS quota -t $qtype $DIR | awk -F "[; ]" \
5706                         '{printf("bgrace=%s;igrace=%s;", $4, $9)}')
5707         echo "ttt4"
5708
5709         $LFS setquota $qdtype -B 10G -i 10k $DIR
5710         echo "ttt5"
5711
5712         eval $($LFS quota -t $qtype $DIR | awk -F "[; ]" \
5713                         '{printf("bgrace2=%s;igrace2=%s;", $4, $9)}')
5714
5715         [ "$bgrace" == "$bgrace2" ] ||
5716                         error "set default quota shouldn't affect block grace"
5717         [ "$igrace" == "$igrace2" ] ||
5718                         error "set default quota shouldn't affect inode grace"
5719
5720 }
5721
5722 test_83()
5723 {
5724         setup_quota_test || error "setup quota failed with $?"
5725         test_grace_with_default_quota "-u" "-U"
5726         test_grace_with_default_quota "-g" "-G"
5727
5728         is_project_quota_supported || return 0
5729         test_grace_with_default_quota "-p" "-P"
5730 }
5731 run_test 83 "Setting default quota shouldn't affect grace time"
5732
5733 test_84()
5734 {
5735         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
5736                 skip "need MDS 2.15.53 or later"
5737
5738         local dir1="$DIR/$tdir/dir1"
5739         local TESTFILE1="$dir1/$tfile-1"
5740         local waited=0
5741         local grant=0
5742         local grant2=0
5743         local qp="qpool1"
5744
5745         mds_supports_qp
5746
5747         setup_quota_test || error "setup quota failed with $?"
5748         quota_init
5749         set_ost_qtype $QTYPE || error "enable ost quota failed"
5750
5751         pool_add $qp || error "pool_add failed"
5752         pool_add_targets $qp 0 $(($OSTCOUNT - 1)) ||
5753                 error "pool_add_targets failed"
5754
5755         $LFS setquota -g $TSTUSR -B 10G $DIR ||
5756                 error "failed to set group quota for $TSTUSR"
5757         $LFS setquota -g $TSTUSR -B 5G --pool $qp $DIR ||
5758                 error "set user quota failed"
5759         $LFS quota -gv $TSTUSR $DIR
5760
5761         wait_quota_setting_synced "grp" $TSTID "hardlimit" $((10*1024*1024))
5762
5763         mkdir -p $dir1 || error "failed to mkdir"
5764         chown $TSTUSR.$TSTUSR $dir1 || error "chown $dir1 failed"
5765
5766         $LFS setstripe -c 1 -i 0 $TESTFILE1
5767         $LFS getstripe $TESTFILE1
5768         chown $TSTUSR.$TSTUSR $TESTFILE1
5769
5770         $RUNAS $DD of=$TESTFILE1 count=60 conv=nocreat oflag=direct ||
5771                 quota_error g $TSTUSR "write failed"
5772
5773         sync
5774         sleep 3
5775         $LFS quota -gv $TSTUSR $DIR
5776
5777 #define OBD_FAIL_QUOTA_GRANT 0xA08
5778         lustre_fail mds 0xa08
5779         lustre_fail ost 0xa08
5780         sleep 1
5781
5782         # clear quota limits to trigger updating grant quota
5783         $LFS setquota -g $TSTUSR -b 0 -B 0 $DIR ||
5784                 error "failed to clear the group quota for $TSTUSR"
5785         $LFS quota -gv $TSTUSR $DIR
5786
5787         # the grant quota should be set as insane value
5788         waited=0
5789         while (( $waited < 60 )); do
5790                 grant=$(getquota -g $TSTUSR lustre-OST0000_UUID bhardlimit $qp)
5791                 grant2=$(getquota -g $TSTUSR lustre-OST0000_UUID bhardlimit)
5792                 (( ${#grant} == 20 && ${#grant2} == 20 )) && break
5793
5794                 sleep 1
5795                 waited=$((waited + 1))
5796         done
5797
5798         (( ${#grant} == 20 )) || error "pool grant is not set as insane value"
5799         (( ${#grant2} == 20 )) || error "grant is not set as insane value"
5800
5801         lustre_fail mds_ost 0
5802         sleep 1
5803
5804         # reset the quota
5805         $LFS setquota -g $TSTUSR -r $DIR ||
5806                 error "failed to reset group quota for $TSTUSR"
5807
5808         sleep 3
5809         $LFS quota -gv $TSTUSR $DIR
5810
5811         # the grant quota should be reset
5812         grant=$(getquota -g $TSTUSR lustre-OST0000_UUID bhardlimit)
5813         (( ${#grant} == 20 )) && error "grant is not cleared"
5814         grant=$(getquota -g $TSTUSR lustre-OST0000_UUID bhardlimit $qp)
5815         (( ${#grant} == 20 )) && error "pool grant is not cleared"
5816
5817         $LFS quota -gv $TSTUSR --pool $qp $DIR
5818         local hlimit=$(getquota -g $TSTUSR global bhardlimit $qp)
5819          [ $hlimit -eq 5242880 ] || error "pool limit is changed"
5820
5821         # test whether the quota still works
5822         $LFS setquota -g $TSTUSR -B 100M $DIR ||
5823                 error "failed to set group quota for $TSTUSR"
5824         $LFS quota -gv $TSTUSR $DIR
5825
5826         $RUNAS $DD of=$TESTFILE1 count=200 conv=nocreat oflag=direct &&
5827                 quota_error g $TSTUSR "dd succeed, expect EDQUOT"
5828
5829         $LFS setquota -g $TSTUSR -B 300M $DIR ||
5830                 error "failed to set group quota for $TSTUSR"
5831         $LFS quota -gv $TSTUSR $DIR
5832
5833         $RUNAS $DD of=$TESTFILE1 count=200 conv=nocreat oflag=direct ||
5834                 quota_error g $TSTUSR "dd failed, expect succeed"
5835 }
5836 run_test 84 "Reset quota should fix the insane granted quota"
5837
5838 quota_fini()
5839 {
5840         do_nodes $(comma_list $(nodes_list)) \
5841                 "lctl set_param -n debug=-quota-trace"
5842         if $PQ_CLEANUP; then
5843                 disable_project_quota
5844         fi
5845 }
5846 reset_quota_settings
5847 quota_fini
5848
5849 cd $ORIG_PWD
5850 complete $SECONDS
5851 check_and_cleanup_lustre
5852 export QUOTA_AUTO=$QUOTA_AUTO_OLD
5853 exit_status