Whamcloud - gitweb
LU-14739 quota: nodemap squashed root cannot bypass quota
[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:  LU-5152
17 ALWAYS_EXCEPT+="                55"
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:-60000}
34 TSTID2=${TSTID2:-60001}
35 TSTUSR=${TSTUSR:-"quota_usr"}
36 TSTUSR2=${TSTUSR2:-"quota_2usr"}
37 TSTPRJID=${TSTPRJID:-1000}
38 BLK_SZ=1024
39 MAX_DQ_TIME=604800
40 MAX_IQ_TIME=604800
41 QTYPE="ugp"
42 # QP exists since this version. Should be finally set before landing.
43 VERSION_WITH_QP="2.13.53"
44 mds_supports_qp() {
45         [ $MDS1_VERSION -lt $(version_code $VERSION_WITH_QP) ] &&
46                 skip "Needs MDS version $VERSION_WITH_QP or later."
47 }
48
49 require_dsh_mds || exit 0
50 require_dsh_ost || exit 0
51
52 # Does e2fsprogs support quota feature?
53 if [ "$mds1_FSTYPE" == ldiskfs ] &&
54         do_facet $SINGLEMDS "! $DEBUGFS -c -R supported_features |
55                 grep -q 'quota'"; then
56         skip_env "e2fsprogs doesn't support quota"
57 fi
58
59 QUOTALOG=${TESTSUITELOG:-$TMP/$(basename $0 .sh).log}
60
61 [ "$QUOTALOG" ] && rm -f $QUOTALOG || true
62
63 DIR=${DIR:-$MOUNT}
64 DIR2=${DIR2:-$MOUNT2}
65
66 QUOTA_AUTO_OLD=$QUOTA_AUTO
67 export QUOTA_AUTO=0
68
69 check_and_setup_lustre
70
71 ENABLE_PROJECT_QUOTAS=${ENABLE_PROJECT_QUOTAS:-true}
72
73 SHOW_QUOTA_USER="$LFS quota -v -u $TSTUSR $DIR"
74 SHOW_QUOTA_USERID="$LFS quota -v -u $TSTID $DIR"
75 SHOW_QUOTA_GROUP="$LFS quota -v -g $TSTUSR $DIR"
76 SHOW_QUOTA_GROUPID="$LFS quota -v -g $TSTID $DIR"
77 SHOW_QUOTA_PROJID="eval is_project_quota_supported && $LFS quota -v -p $TSTPRJID $DIR"
78 SHOW_QUOTA_INFO_USER="$LFS quota -t -u $DIR"
79 SHOW_QUOTA_INFO_GROUP="$LFS quota -t -g $DIR"
80 SHOW_QUOTA_INFO_PROJID="eval is_project_quota_supported && $LFS quota -t -p $DIR"
81
82 lustre_fail() {
83         local fail_node=$1
84         local fail_loc=$2
85         local fail_val=${3:-0}
86         local NODES=
87
88         case $fail_node in
89         mds_ost|mdt_ost) NODES="$(comma_list $(mdts_nodes) $(osts_nodes))";;
90         mds|mdt) NODES="$(comma_list $(mdts_nodes))";;
91         ost) NODES="$(comma_list $(osts_nodes))";;
92         esac
93
94         do_nodes $NODES "lctl set_param fail_val=$fail_val fail_loc=$fail_loc"
95 }
96
97 change_project()
98 {
99         echo "lfs project $*"
100         lfs project $* || error "lfs project $* failed"
101 }
102
103 RUNAS="runas -u $TSTID -g $TSTID"
104 RUNAS2="runas -u $TSTID2 -g $TSTID2"
105 DD="dd if=/dev/zero bs=1M"
106
107 FAIL_ON_ERROR=false
108
109 # clear quota limits for a user or a group
110 # usage: resetquota -u username
111 #        resetquota -g groupname
112 #        resetquota -p projid
113
114 resetquota() {
115         [ "$#" != 2 ] && error "resetquota: wrong number of arguments: $#"
116         [ "$1" != "-u" -a "$1" != "-g" -a "$1" != "-p" ] &&
117                 error "resetquota: wrong specifier $1 passed"
118
119         if [ $1 == "-p" ]; then
120                 is_project_quota_supported || return 0
121         fi
122
123         $LFS setquota "$1" "$2" -b 0 -B 0 -i 0 -I 0 $MOUNT ||
124                 error "clear quota for [type:$1 name:$2] failed"
125         # give a chance to slave to release space
126         sleep 1
127 }
128
129 quota_scan() {
130         local local_ugp=$1
131         local local_id=$2
132
133         if [ "$local_ugp" == "a" -o "$local_ugp" == "u" ]; then
134                 $LFS quota -v -u $local_id $DIR
135                 log "Files for user ($local_id):"
136                 ($LFS find --user $local_id $DIR | head -n 4 |
137                         xargs stat 2>/dev/null)
138         fi
139
140         if [ "$local_ugp" == "a" -o "$local_ugp" == "g" ]; then
141                 $LFS quota -v -g $local_id $DIR
142                 log "Files for group ($local_id):"
143                 ($LFS find --group $local_id $DIR | head -n 4 |
144                         xargs stat 2>/dev/null)
145         fi
146
147         is_project_quota_supported || return 0
148         if [ "$local_ugp" == "a" -o "$local_ugp" == "p" ]; then
149                 $LFS quota -v -p $TSTPRJID $DIR
150                 log "Files for project ($TSTPRJID):"
151                 ($LFS find --projid $TSTPRJID $DIR | head -n 4 |
152                         xargs stat 2>/dev/null)
153         fi
154 }
155
156 quota_error() {
157         quota_scan $1 $2
158         shift 2
159         error "$*"
160 }
161
162 quota_log() {
163         quota_scan $1 $2
164         shift 2
165         log "$*"
166 }
167
168 # get quota for a user or a group
169 # usage: getquota -u|-g|-p <username>|<groupname>|<projid> global|<obd_uuid> \
170 #                 bhardlimit|bsoftlimit|bgrace|ihardlimit|isoftlimit|igrace \
171 #                 <pool_name>
172 getquota() {
173         local spec
174         local uuid
175         local pool_arg
176
177         sync_all_data > /dev/null 2>&1 || true
178
179         [ "$#" != 4 -a "$#" != 5 ] &&
180                 error "getquota: wrong number of arguments: $#"
181         [ "$1" != "-u" -a "$1" != "-g" -a "$1" != "-p" ] &&
182                 error "getquota: wrong u/g/p specifier $1 passed"
183
184         uuid="$3"
185
186         case "$4" in
187                 curspace)   spec=1;;
188                 bsoftlimit) spec=2;;
189                 bhardlimit) spec=3;;
190                 bgrace)     spec=4;;
191                 curinodes)  spec=5;;
192                 isoftlimit) spec=6;;
193                 ihardlimit) spec=7;;
194                 igrace)     spec=8;;
195                 *)          error "unknown quota parameter $4";;
196         esac
197
198         [ ! -z "$5" ] && pool_arg="--pool $5 "
199         [ "$uuid" = "global" ] && uuid=$DIR
200
201         $LFS quota -v "$1" "$2" $pool_arg $DIR |
202                 awk 'BEGIN { num='$spec' } { if ($1 == "'$uuid'") \
203                 { if (NF == 1) { getline } else { num++ } ; print $num;} }' \
204                 | tr -d "*"
205 }
206
207 # set mdt quota type
208 # usage: set_mdt_qtype ugp|u|g|p|none
209 set_mdt_qtype() {
210         local qtype=$1
211         local varsvc
212         local mdts=$(get_facets MDS)
213         local cmd
214         [[ "$qtype" =~ "p" ]] && ! is_project_quota_supported &&
215                 qtype=$(tr -d 'p' <<<$qtype)
216
217         if [[ $PERM_CMD == *"set_param -P"* ]]; then
218                 do_facet mgs $PERM_CMD \
219                         osd-*.$FSNAME-MDT*.quota_slave.enable=$qtype
220         else
221                 do_facet mgs $PERM_CMD $FSNAME.quota.mdt=$qtype
222         fi
223         # we have to make sure each MDT received config changes
224         for mdt in ${mdts//,/ }; do
225                 varsvc=${mdt}_svc
226                 cmd="$LCTL get_param -n "
227                 cmd=${cmd}osd-$(facet_fstype $mdt).${!varsvc}
228                 cmd=${cmd}.quota_slave.enabled
229
230                 if $(facet_up $mdt); then
231                         wait_update_facet $mdt "$cmd" "$qtype" || return 1
232                 fi
233         done
234         return 0
235 }
236
237 # set ost quota type
238 # usage: set_ost_qtype ugp|u|g|p|none
239 set_ost_qtype() {
240         local qtype=$1
241         local varsvc
242         local osts=$(get_facets OST)
243         local cmd
244         [[ "$qtype" =~ "p" ]] && ! is_project_quota_supported &&
245                 qtype=$(tr -d 'p' <<<$qtype)
246
247         if [[ $PERM_CMD == *"set_param -P"* ]]; then
248                 do_facet mgs $PERM_CMD \
249                         osd-*.$FSNAME-OST*.quota_slave.enable=$qtype
250         else
251                 do_facet mgs $PERM_CMD $FSNAME.quota.ost=$qtype
252         fi
253         # we have to make sure each OST received config changes
254         for ost in ${osts//,/ }; do
255                 varsvc=${ost}_svc
256                 cmd="$LCTL get_param -n "
257                 cmd=${cmd}osd-$(facet_fstype $ost).${!varsvc}
258                 cmd=${cmd}.quota_slave.enabled
259
260                 if $(facet_up $ost); then
261                         wait_update_facet $ost "$cmd" "$qtype" || return 1
262                 fi
263         done
264         return 0
265 }
266
267 wait_reintegration() {
268         local ntype=$1
269         local qtype=$2
270         local max=$3
271         local result="glb[1],slv[1],reint[0]"
272         local varsvc
273         local cmd
274         local tgts
275
276         if [ $ntype == "mdt" ]; then
277                 tgts=$(get_facets MDS)
278         else
279                 tgts=$(get_facets OST)
280         fi
281
282         for tgt in ${tgts//,/ }; do
283                 varsvc=${tgt}_svc
284                 cmd="$LCTL get_param -n "
285                 cmd=${cmd}osd-$(facet_fstype $tgt).${!varsvc}
286                 cmd=${cmd}.quota_slave.info
287
288                 if $(facet_up $tgt); then
289                         wait_update_facet $tgt "$cmd |
290                                 grep "$qtype" | awk '{ print \\\$3 }'" \
291                                         "$result" $max || return 1
292                 fi
293         done
294         return 0
295 }
296
297 wait_mdt_reint() {
298         local qtype=$1
299         local max=${2:-90}
300
301         if [[ "$qtype" =~ "u" ]]; then
302                 wait_reintegration "mdt" "user" $max || return 1
303         fi
304
305         if [[ "$qtype" =~ "g" ]]; then
306                 wait_reintegration "mdt" "group" $max || return 1
307         fi
308
309         if [[ "$qtype" =~ "p" ]]; then
310                 ! is_project_quota_supported && return 0
311                 wait_reintegration "mdt" "project" $max || return 1
312         fi
313         return 0
314 }
315
316 wait_ost_reint() {
317         local qtype=$1
318         local max=${2:-90}
319
320         if [[ "$qtype" =~ "u" ]]; then
321                 wait_reintegration "ost" "user" $max || return 1
322         fi
323
324         if [[ "$qtype" =~ "g" ]]; then
325                 wait_reintegration "ost" "group" $max || return 1
326         fi
327
328         if [[ "$qtype" =~ "p" ]]; then
329                 ! is_project_quota_supported && return 0
330                 wait_reintegration "ost" "project" $max || return 1
331         fi
332         return 0
333 }
334
335 wait_grace_time() {
336         local qtype=$1
337         local flavour=$2
338         local pool=${3:-}
339         local extrasleep=${4:-5}
340         local qarg
341         local parg
342
343         case $qtype in
344                 u|g) qarg=$TSTUSR ;;
345                 p) qarg=$TSTPRJID ;;
346                 *) error "get_grace_time: Invalid quota type: $qtype"
347         esac
348
349         if [ $pool ]; then
350                 parg="--pool "$pool
351                 echo "Quota info for $pool:"
352                 $LFS quota -$qtype $qarg $parg $DIR
353         fi
354
355         case $flavour in
356                 block)
357                         time=$(lfs quota -$qtype $qarg $parg $DIR|
358                                    awk 'NR == 3{ print $5 }')
359                         ;;
360                 file)
361                         time=$(lfs quota -$qtype $qarg $DIR|
362                                    awk 'NR == 3{ print $9 }')
363                         ;;
364                 *)
365                         error "Unknown quota type: $flavour"
366                         ;;
367         esac
368
369         local sleep_seconds=0
370         local orig_time=$time
371
372         echo "Grace time is $time"
373         # from lfs.c:__sec2str()
374         # const char spec[] = "smhdw";
375         # {1, 60, 60*60, 24*60*60, 7*24*60*60};
376         [[ $time == *w* ]] && w_time=${time%w*} &&
377                 let sleep_seconds+=$((w_time*7*24*60*60));
378         time=${time#*w}
379         [[ $time == *d* ]] && d_time=${time%d*} &&
380                 let sleep_seconds+=$((d_time*24*60*60));
381         time=${time#*d}
382         [[ $time == *h* ]] && h_time=${time%h*} &&
383                 let sleep_seconds+=$((h_time*60*60));
384         time=${time#*h}
385         [[ $time == *m* ]] && m_time=${time%m*} &&
386                 let sleep_seconds+=$((m_time*60));
387         time=${time#*m}
388         [[ $time == *s* ]] && s_time=${time%s*} &&
389                 let sleep_seconds+=$s_time
390
391         echo "Sleep through grace ..."
392         [ "$orig_time" == "-" ] &&
393             error "Grace timeout was not set or quota not exceeded"
394         if [ "$orig_time" == "none" ]; then
395             echo "...Grace timeout already expired"
396         else
397                 let sleep_seconds+=$extrasleep
398                 echo "...sleep $sleep_seconds seconds"
399                 sleep $sleep_seconds
400         fi
401 }
402
403 setup_quota_test() {
404         local mdt=${1:-0}
405         wait_delete_completed
406         echo "Creating test directory"
407         $LFS mkdir -i $mdt -c 1 $DIR/$tdir || return 1
408         chmod 0777 $DIR/$tdir || return 2
409         # always clear fail_loc in case of fail_loc isn't cleared
410         # properly when previous test failed
411         lustre_fail mds_ost 0
412 }
413
414 cleanup_quota_test() {
415         echo "Delete files..."
416         rm -rf $DIR/$tdir
417         echo "Wait for unlink objects finished..."
418         wait_delete_completed
419         sync_all_data || true
420         reset_quota_settings
421 }
422
423 quota_show_check() {
424         local bf=$1
425         local ugp=$2
426         local qid=$3
427         local usage
428
429         $LFS quota -v -$ugp $qid $DIR
430
431         if [ "$bf" == "a" -o "$bf" == "b" ]; then
432                 usage=$(getquota -$ugp $qid global curspace)
433                 if [ -z $usage ]; then
434                         quota_error $ugp $qid \
435                                 "Query block quota failed ($ugp:$qid)."
436                 else
437                         [ $usage -ne 0 ] && quota_log $ugp $qid \
438                                 "Block quota isn't 0 ($ugp:$qid:$usage)."
439                 fi
440         fi
441
442         if [ "$bf" == "a" -o "$bf" == "f" ]; then
443                 usage=$(getquota -$ugp $qid global curinodes)
444                 if [ -z $usage ]; then
445                         quota_error $ugp $qid \
446                                 "Query file quota failed ($ugp:$qid)."
447                 else
448                         [ $usage -ne 0 ] && quota_log $ugp $qid \
449                                 "File quota isn't 0 ($ugp:$qid:$usage)."
450                 fi
451         fi
452 }
453
454 project_quota_enabled () {
455         local rc=0
456         local zfeat="feature@project_quota"
457
458         for facet in $(seq -f mds%g $MDSCOUNT) $(seq -f ost%g $OSTCOUNT); do
459                 local facet_fstype=${facet:0:3}1_FSTYPE
460                 local devname
461
462                 if [ "${!facet_fstype}" = "zfs" ]; then
463                         devname=$(zpool_name ${facet})
464                         do_facet ${facet} $ZPOOL get -H "$zfeat" $devname |
465                                 grep -wq active || rc=1
466                 else
467                         [ ${facet:0:3} == "mds" ] &&
468                                 devname=$(mdsdevname ${facet:3}) ||
469                                 devname=$(ostdevname ${facet:3})
470                         do_facet ${facet} $DEBUGFS -R features $devname |
471                                 grep -q project || rc=1
472                 fi
473         done
474         [ $rc -eq 0 ] && PQ_CLEANUP=false || PQ_CLEANUP=true
475         return $rc
476 }
477
478 project_quota_enabled || enable_project_quota
479
480 reset_quota_settings() {
481         resetquota -u $TSTUSR
482         resetquota -u $TSTID
483         resetquota -g $TSTUSR
484         resetquota -g $TSTID
485         resetquota -u $TSTUSR2
486         resetquota -u $TSTID2
487         resetquota -g $TSTUSR2
488         resetquota -g $TSTID2
489         resetquota -p $TSTPRJID
490 }
491
492 # enable quota debug
493 quota_init() {
494         do_nodes $(comma_list $(nodes_list)) \
495                 "$LCTL set_param -n debug=+quota,trace"
496 }
497 quota_init
498 reset_quota_settings
499
500 check_runas_id_ret $TSTUSR $TSTUSR $RUNAS ||
501         error "Please create user $TSTUSR($TSTID) and group $TSTUSR($TSTID)"
502 check_runas_id_ret $TSTUSR2 $TSTUSR2 $RUNAS2 ||
503         error "Please create user $TSTUSR2($TSTID2) and group $TSTUSR2($TSTID2)"
504
505 test_quota_performance() {
506         local TESTFILE="$DIR/$tdir/$tfile-0"
507         local size=$1 # in MB
508         local stime=$(date +%s)
509         $RUNAS $DD of=$TESTFILE count=$size conv=fsync ||
510                 quota_error u $TSTUSR "write failure"
511         local etime=$(date +%s)
512         delta=$((etime - stime))
513         if [ $delta -gt 0 ]; then
514                 rate=$((size * 1024 / delta))
515                 if [ "$mds1_FSTYPE" = zfs ]; then
516                         # LU-2872 - see LU-2887 for fix
517                         [ $rate -gt 64 ] ||
518                                 error "SLOW IO for $TSTUSR (user): $rate KB/sec"
519                 else
520                         [ $rate -gt 1024 ] ||
521                                 error "SLOW IO for $TSTUSR (user): $rate KB/sec"
522                 fi
523         fi
524         rm -f $TESTFILE
525 }
526
527 # test basic quota performance b=21696
528 test_0() {
529         local MB=100 # MB
530         [ "$SLOW" = "no" ] && MB=10
531
532         local free_space=$(lfs_df | grep "summary" | awk '{print $4}')
533         [ $free_space -le $((MB * 1024)) ] &&
534                 skip "not enough space ${free_space} KB, " \
535                         "required $((MB * 1024)) KB"
536         setup_quota_test || error "setup quota failed with $?"
537         trap cleanup_quota_test EXIT
538
539         set_ost_qtype "none" || error "disable ost quota failed"
540         test_quota_performance $MB
541
542         set_ost_qtype $QTYPE || error "enable ost quota failed"
543         $LFS setquota -u $TSTUSR -b 0 -B 10G -i 0 -I 0 $DIR ||
544                 error "set quota failed"
545         test_quota_performance $MB
546
547         cleanup_quota_test
548 }
549 run_test 0 "Test basic quota performance"
550
551 # usage: test_1_check_write tfile user|group|project
552 test_1_check_write() {
553         local testfile="$1"
554         local qtype="$2"
555         local limit=$3
556         local short_qtype=${qtype:0:1}
557
558         log "Write..."
559         $RUNAS $DD of=$testfile count=$((limit/2)) ||
560                 quota_error $short_qtype $TSTUSR \
561                         "$qtype write failure, but expect success"
562         log "Write out of block quota ..."
563         # this time maybe cache write,  ignore it's failure
564         $RUNAS $DD of=$testfile count=$((limit/2)) seek=$((limit/2)) || true
565         # flush cache, ensure noquota flag is set on client
566         cancel_lru_locks osc
567         sync; sync_all_data || true
568         # sync means client wrote all it's cache, but id doesn't
569         # garantee that slave got new edquot trough glimpse.
570         # so wait a little to be sure slave got it.
571         sleep 5
572         $RUNAS $DD of=$testfile count=1 seek=$limit &&
573                 quota_error $short_qtype $TSTUSR \
574                         "user write success, but expect EDQUOT"
575 }
576
577 check_write_fallocate() {
578         local testfile="$1"
579         local qtype="$2"
580         local limit=$3
581         local short_qtype=${qtype:0:1}
582
583         count=$((limit/2))
584         log "Write ${count}MiB Using Fallocate"
585         $RUNAS fallocate -l${count}MiB $testfile ||
586                 quota_error $short_qtype $TSTUSR "Write ${count}MiB fail"
587
588         cancel_lru_locks osc
589         sync; sync_all_data || true
590         sleep 2
591
592         count=$((limit + 1))
593         log "Write ${count}MiB Using Fallocate"
594         $RUNAS fallocate -l${count}MiB $testfile &&
595                 quota_error $short_qtype $TSTUSR \
596                 "Write success, expect EDQUOT" || true
597 }
598
599 # test block hardlimit
600 test_1a() {
601         local limit=10 # MB
602         local testfile="$DIR/$tdir/$tfile-0"
603
604         setup_quota_test || error "setup quota failed with $?"
605         trap cleanup_quota_test EXIT
606
607         # enable ost quota
608         set_ost_qtype $QTYPE || error "enable ost quota failed"
609
610         # test for user
611         log "User quota (block hardlimit:$limit MB)"
612         $LFS setquota -u $TSTUSR -b 0 -B ${limit}M -i 0 -I 0 $DIR ||
613                 error "set user quota failed"
614
615         # make sure the system is clean
616         local used=$(getquota -u $TSTUSR global curspace)
617         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
618
619         $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
620         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
621
622         test_1_check_write $testfile "user" $limit
623
624         rm -f $testfile
625         wait_delete_completed || error "wait_delete_completed failed"
626         sync_all_data || true
627         used=$(getquota -u $TSTUSR global curspace)
628         [ $used -ne 0 ] && quota_error u $TSTUSR \
629                 "user quota isn't released after deletion"
630         resetquota -u $TSTUSR
631
632         # test for group
633         log "--------------------------------------"
634         log "Group quota (block hardlimit:$limit MB)"
635         $LFS setquota -g $TSTUSR -b 0 -B ${limit}M -i 0 -I 0 $DIR ||
636                 error "set group quota failed"
637
638         testfile="$DIR/$tdir/$tfile-1"
639         # make sure the system is clean
640         used=$(getquota -g $TSTUSR global curspace)
641         [ $used -ne 0 ] && error "Used space ($used) for group $TSTUSR isn't 0"
642
643         $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
644         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
645
646         test_1_check_write $testfile "group" $limit
647         rm -f $testfile
648         wait_delete_completed || error "wait_delete_completed failed"
649         sync_all_data || true
650         used=$(getquota -g $TSTUSR global curspace)
651         [ $used -ne 0 ] && quota_error g $TSTUSR \
652                                 "Group quota isn't released after deletion"
653         resetquota -g $TSTUSR
654
655         if ! is_project_quota_supported; then
656                 echo "Project quota is not supported"
657                 cleanup_quota_test
658                 return 0
659         fi
660
661         testfile="$DIR/$tdir/$tfile-2"
662         # make sure the system is clean
663         used=$(getquota -p $TSTPRJID global curspace)
664         [ $used -ne 0 ] &&
665                 error "used space($used) for project $TSTPRJID isn't 0"
666
667         # test for Project
668         log "--------------------------------------"
669         log "Project quota (block hardlimit:$limit mb)"
670         $LFS setquota -p $TSTPRJID -b 0 -B ${limit}M -i 0 -I 0 $DIR ||
671                 error "set project quota failed"
672
673         $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
674         chown $TSTUSR:$TSTUSR $testfile || error "chown $testfile failed"
675         change_project -p $TSTPRJID $testfile
676
677         test_1_check_write $testfile "project" $limit
678
679         # cleanup
680         cleanup_quota_test
681
682         used=$(getquota -p $TSTPRJID global curspace)
683         [ $used -ne 0 ] && quota_error p $TSTPRJID \
684                 "project quota isn't released after deletion"
685
686         resetquota -p $TSTPRJID
687 }
688 run_test 1a "Block hard limit (normal use and out of quota)"
689
690 test_1b() {
691         local limit=10 # MB
692         local global_limit=20 # MB
693         local testfile="$DIR/$tdir/$tfile-0"
694         local qpool="qpool1"
695
696         mds_supports_qp
697         setup_quota_test || error "setup quota failed with $?"
698         stack_trap cleanup_quota_test EXIT
699
700         # enable ost quota
701         set_ost_qtype $QTYPE || error "enable ost quota failed"
702
703         # test for user
704         log "User quota (block hardlimit:$global_limit MB)"
705         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
706                 error "set user quota failed"
707
708         pool_add $qpool || error "pool_add failed"
709         pool_add_targets $qpool 0 $(($OSTCOUNT - 1)) ||
710                 error "pool_add_targets failed"
711
712         $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR ||
713                 error "set user quota failed"
714
715         # make sure the system is clean
716         local used=$(getquota -u $TSTUSR global curspace)
717         echo "used $used"
718         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
719
720         used=$(getquota -u $TSTUSR global bhardlimit $qpool)
721
722         $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
723         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
724
725         test_1_check_write $testfile "user" $limit
726
727         rm -f $testfile
728         wait_delete_completed || error "wait_delete_completed failed"
729         sync_all_data || true
730         used=$(getquota -u $TSTUSR global curspace $qpool)
731         [ $used -ne 0 ] && quota_error u $TSTUSR \
732                 "user quota isn't released after deletion"
733         resetquota -u $TSTUSR
734
735         # test for group
736         log "--------------------------------------"
737         log "Group quota (block hardlimit:$global_limit MB)"
738         $LFS setquota -g $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
739                 error "set group quota failed"
740
741         $LFS setquota -g $TSTUSR -b 0 -B ${limit}M --pool $qpool $DIR ||
742                 error "set group quota failed"
743
744         testfile="$DIR/$tdir/$tfile-1"
745         # make sure the system is clean
746         used=$(getquota -g $TSTUSR global curspace $qpool)
747         [ $used -ne 0 ] && error "Used space ($used) for group $TSTUSR isn't 0"
748
749         $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
750         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
751
752         test_1_check_write $testfile "group" $limit
753
754         rm -f $testfile
755         wait_delete_completed || error "wait_delete_completed failed"
756         sync_all_data || true
757         used=$(getquota -g $TSTUSR global curspace $qpool)
758         [ $used -ne 0 ] && quota_error g $TSTUSR \
759                                 "Group quota isn't released after deletion"
760         resetquota -g $TSTUSR
761
762         if ! is_project_quota_supported; then
763                 echo "Project quota is not supported"
764                 cleanup_quota_test
765                 return 0
766         fi
767
768         testfile="$DIR/$tdir/$tfile-2"
769         # make sure the system is clean
770         used=$(getquota -p $TSTPRJID global curspace $qpool)
771         [ $used -ne 0 ] &&
772                 error "used space($used) for project $TSTPRJID isn't 0"
773
774         # test for Project
775         log "--------------------------------------"
776         log "Project quota (block hardlimit:$global_limit mb)"
777         $LFS setquota -p $TSTPRJID -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
778                 error "set project quota failed"
779
780         $LFS setquota -p $TSTPRJID -b 0 -B ${limit}M --pool $qpool $DIR ||
781                 error "set project quota failed"
782
783
784         $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
785         chown $TSTUSR:$TSTUSR $testfile || error "chown $testfile failed"
786         change_project -p $TSTPRJID $testfile
787
788         test_1_check_write $testfile "project" $limit
789
790         # cleanup
791         cleanup_quota_test
792
793         used=$(getquota -p $TSTPRJID global curspace)
794         [ $used -eq 0 ] || quota_error p $TSTPRJID \
795                 "project quota isn't released after deletion"
796 }
797 run_test 1b "Quota pools: Block hard limit (normal use and out of quota)"
798
799 test_1c() {
800         local global_limit=20 # MB
801         local testfile="$DIR/$tdir/$tfile-0"
802         local qpool1="qpool1"
803         local qpool2="qpool2"
804
805         mds_supports_qp
806         setup_quota_test || error "setup quota failed with $?"
807         stack_trap cleanup_quota_test EXIT
808
809         # enable ost quota
810         set_ost_qtype $QTYPE || error "enable ost quota failed"
811
812         # test for user
813         log "User quota (block hardlimit:$global_limit MB)"
814         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
815                 error "set user quota failed"
816
817         pool_add $qpool1 || error "pool_add failed"
818         pool_add_targets $qpool1 0 $(($OSTCOUNT - 1)) ||
819                 error "pool_add_targets failed"
820
821         pool_add $qpool2 || error "pool_add failed"
822         pool_add_targets $qpool2 0 $(($OSTCOUNT - 1)) ||
823                 error "pool_add_targets failed"
824
825         # create pools without hard limit
826         # initially such case raised several bugs
827         $LFS setquota -u $TSTUSR -B 0M --pool $qpool1 $DIR ||
828                 error "set user quota failed"
829
830         $LFS setquota -u $TSTUSR -B 0M --pool $qpool2 $DIR ||
831                 error "set user quota failed"
832
833         # make sure the system is clean
834         local used=$(getquota -u $TSTUSR global curspace)
835         echo "used $used"
836         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
837
838         used=$(getquota -u $TSTUSR global bhardlimit $qpool)
839
840         test_1_check_write $testfile "user" $global_limit
841
842         used=$(getquota -u $TSTUSR global curspace $qpool1)
843         echo "qpool1 used $used"
844         used=$(getquota -u $TSTUSR global curspace $qpool2)
845         echo "qpool2 used $used"
846
847         rm -f $testfile
848         wait_delete_completed || error "wait_delete_completed failed"
849         sync_all_data || true
850
851         used=$(getquota -u $TSTUSR global curspace $qpool1)
852         [ $used -ne 0 ] && quota_error u $TSTUSR \
853                 "user quota isn't released after deletion"
854         resetquota -u $TSTUSR
855
856         # cleanup
857         cleanup_quota_test
858 }
859 run_test 1c "Quota pools: check 3 pools with hardlimit only for global"
860
861 test_1d() {
862         local limit1=10 # MB
863         local limit2=12 # MB
864         local global_limit=20 # MB
865         local testfile="$DIR/$tdir/$tfile-0"
866         local qpool1="qpool1"
867         local qpool2="qpool2"
868
869         mds_supports_qp
870         setup_quota_test || error "setup quota failed with $?"
871         stack_trap cleanup_quota_test EXIT
872
873         # enable ost quota
874         set_ost_qtype $QTYPE || error "enable ost quota failed"
875
876         # test for user
877         log "User quota (block hardlimit:$global_limit MB)"
878         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
879                 error "set user quota failed"
880
881         pool_add $qpool1 || error "pool_add failed"
882         pool_add_targets $qpool1 0 $(($OSTCOUNT - 1)) ||
883                 error "pool_add_targets failed"
884
885         pool_add $qpool2 || error "pool_add failed"
886         pool_add_targets $qpool2 0 $(($OSTCOUNT - 1)) ||
887                 error "pool_add_targets failed"
888
889         $LFS setquota -u $TSTUSR -B ${limit1}M --pool $qpool1 $DIR ||
890                 error "set user quota failed"
891
892         $LFS setquota -u $TSTUSR -B ${limit2}M --pool $qpool2 $DIR ||
893         error "set user quota failed"
894
895         # make sure the system is clean
896         local used=$(getquota -u $TSTUSR global curspace)
897         echo "used $used"
898         [ $used -ne 0 ] && error "used space($used) for user $TSTUSR isn't 0."
899
900         used=$(getquota -u $TSTUSR global bhardlimit $qpool)
901
902         test_1_check_write $testfile "user" $limit1
903
904         used=$(getquota -u $TSTUSR global curspace $qpool1)
905         echo "qpool1 used $used"
906         used=$(getquota -u $TSTUSR global curspace $qpool2)
907         echo "qpool2 used $used"
908
909         rm -f $testfile
910         wait_delete_completed || error "wait_delete_completed failed"
911         sync_all_data || true
912
913         used=$(getquota -u $TSTUSR global curspace $qpool1)
914         [ $used -ne 0 ] && quota_error u $TSTUSR \
915                 "user quota isn't released after deletion"
916         resetquota -u $TSTUSR
917
918         # cleanup
919         cleanup_quota_test
920 }
921 run_test 1d "Quota pools: check block hardlimit on different pools"
922
923 test_1e() {
924         local limit1=10 # MB
925         local global_limit=53000000 # MB
926         local testfile="$DIR/$tdir/$tfile-0"
927         local testfile2="$DIR/$tdir/$tfile-1"
928         local qpool1="qpool1"
929
930         mds_supports_qp
931         setup_quota_test || error "setup quota failed with $?"
932         stack_trap cleanup_quota_test EXIT
933
934         # enable ost quota
935         set_ost_qtype $QTYPE || error "enable ost quota failed"
936
937         # global_limit is much greater than limit1 to get
938         # different qunit's on osts. Since 1st qunit shrinking
939         # on OST1(that belongs to qpool1), this qunit should
940         # be sent to OST1.
941         log "User quota (block hardlimit:$global_limit MB)"
942         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
943                 error "set user quota failed"
944
945         pool_add $qpool1 || error "pool_add failed"
946         pool_add_targets $qpool1 1 1 ||
947                 error "pool_add_targets failed"
948
949         $LFS setquota -u $TSTUSR -B ${limit1}M --pool $qpool1 $DIR ||
950                 error "set user quota failed"
951
952         # make sure the system is clean
953         local used=$(getquota -u $TSTUSR global curspace)
954         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
955
956         $LFS setstripe $testfile -c 1 -i 1 || error "setstripe $testfile failed"
957         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
958
959         test_1_check_write $testfile "user" $limit1
960
961         $LFS setstripe $testfile2 -c 1 -i 0 ||
962                 error "setstripe $testfile2 failed"
963         chown $TSTUSR.$TSTUSR $testfile2 || error "chown $testfile2 failed"
964         # Now write to file with a stripe on OST0, that doesn't belong to qpool1
965         log "Write..."
966         $RUNAS $DD of=$testfile2 count=20 ||
967                 quota_error u $TSTUSR \
968                         "$qtype write failure, but expect success"
969
970         rm -f $testfile
971         rm -f $testfile2
972         wait_delete_completed || error "wait_delete_completed failed"
973         sync_all_data || true
974
975         used=$(getquota -u $TSTUSR global curspace $qpool1)
976         [ $used -ne 0 ] && quota_error u $TSTUSR \
977                 "user quota isn't released after deletion"
978         resetquota -u $TSTUSR
979
980         # cleanup
981         cleanup_quota_test
982 }
983 run_test 1e "Quota pools: global pool high block limit vs quota pool with small"
984
985 test_1f() {
986         local global_limit=200 # MB
987         local limit1=10 # MB
988         local TESTDIR="$DIR/$tdir/"
989         local testfile="$TESTDIR/$tfile-0"
990         local qpool1="qpool1"
991
992         mds_supports_qp
993         setup_quota_test || error "setup quota failed with $?"
994         stack_trap cleanup_quota_test EXIT
995
996         # enable ost quota
997         set_ost_qtype $QTYPE || error "enable ost quota failed"
998
999         log "User quota (block hardlimit:$global_limit MB)"
1000         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
1001                 error "set user quota failed"
1002
1003         pool_add $qpool1 || error "pool_add failed"
1004         pool_add_targets $qpool1 0 0 ||
1005                 error "pool_add_targets failed"
1006
1007         $LFS setquota -u $TSTUSR -B ${limit1}M --pool $qpool1 $DIR ||
1008                 error "set user quota failed"
1009
1010         # make sure the system is clean
1011         local used=$(getquota -u $TSTUSR global curspace)
1012         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
1013
1014         $LFS setstripe $TESTDIR -c 1 -i 0 || error "setstripe $TESTDIR failed"
1015
1016         test_1_check_write $testfile "user" $limit1
1017
1018         pool_remove_target $qpool1 0
1019         rm -f $testfile
1020         wait_delete_completed || error "wait_delete_completed failed"
1021         sync_all_data || true
1022
1023         pool_add_targets $qpool1 0 0 || error "pool_add_targets failed"
1024         # qunit for appropriate element in lgd array should be set
1025         # correctly(4096). Earlier it was not changed continuing to be 1024.
1026         # This caused write to hung when it hit limit1 - qunit shrinking to 1024
1027         # for qpool1 lqe didn't cause changing qunit for OST0 in gld array
1028         # as it already was 1024. As flag "need_update" for this qunit was
1029         # not set, new qunit wasn't sent to OST0. Thus revoke was not set
1030         # for "qpool1" lqe and it couldn't set EDQUOT despite granted
1031         # became > 10M. QMT returned EINPROGRESS in a loop.
1032         # Check that it doesn't hung anymore.
1033         test_1_check_write $testfile "user" $limit1
1034
1035         # cleanup
1036         cleanup_quota_test
1037 }
1038 run_test 1f "Quota pools: correct qunit after removing/adding OST"
1039
1040 test_1g() {
1041         local limit=20 # MB
1042         local global_limit=40 # MB
1043         local testfile="$DIR/$tdir/$tfile-0"
1044         local qpool="qpool1"
1045         local mdmb_param="osc.*.max_dirty_mb"
1046         local max_dirty_mb=$($LCTL get_param -n $mdmb_param | head -1)
1047
1048         mds_supports_qp
1049         setup_quota_test || error "setup quota failed with $?"
1050         stack_trap cleanup_quota_test EXIT
1051         $LCTL set_param $mdmb_param=1
1052         stack_trap "$LCTL set_param $mdmb_param=$max_dirty_mb" EXIT
1053
1054         # enable ost quota
1055         set_ost_qtype $QTYPE || error "enable ost quota failed"
1056
1057         # test for user
1058         log "User quota (block hardlimit:$global_limit MB)"
1059         $LFS setquota -u $TSTUSR -b 0 -B ${global_limit}M -i 0 -I 0 $DIR ||
1060                 error "set user quota failed"
1061
1062         pool_add $qpool || error "pool_add failed"
1063         pool_add_targets $qpool 0 $(($OSTCOUNT - 1)) ||
1064                 error "pool_add_targets failed"
1065
1066         $LFS setquota -u $TSTUSR -B ${limit}M --pool $qpool $DIR ||
1067                 error "set user quota failed"
1068
1069         # make sure the system is clean
1070         local used=$(getquota -u $TSTUSR global curspace)
1071         echo "used $used"
1072         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
1073
1074         $LFS setstripe $testfile -C 200 || error "setstripe $testfile failed"
1075         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
1076
1077         log "Write..."
1078         $RUNAS $DD of=$testfile count=$((limit/2)) ||
1079                 quota_error u $TSTUSR \
1080                         "$qtype write failure, but expect success"
1081         log "Write out of block quota ..."
1082         # this time maybe cache write,  ignore it's failure
1083         $RUNAS $DD of=$testfile count=$((limit/2)) seek=$((limit/2)) || true
1084         # flush cache, ensure noquota flag is set on client
1085         cancel_lru_locks osc
1086         sync; sync_all_data || true
1087         sleep 5
1088         $RUNAS $DD of=$testfile count=$OSTCOUNT seek=$limit &&
1089                 quota_error u $TSTUSR \
1090                         "user write success, but expect EDQUOT"
1091
1092         rm -f $testfile
1093         wait_delete_completed || error "wait_delete_completed failed"
1094         sync_all_data || true
1095
1096         used=$(getquota -u $TSTUSR global curspace $qpool)
1097         [ $used -ne 0 ] && quota_error u $TSTUSR \
1098                 "user quota isn't released after deletion"
1099         return 0
1100 }
1101 run_test 1g "Quota pools: Block hard limit with wide striping"
1102
1103 test_1h() {
1104         local limit=10 # MB
1105         local testfile="$DIR/$tdir/$tfile-0"
1106
1107         check_set_fallocate_or_skip
1108
1109         setup_quota_test || error "setup quota failed with $?"
1110         trap cleanup_quota_test EXIT
1111
1112         # enable ost quota
1113         set_ost_qtype $QTYPE || error "enable ost quota failed"
1114
1115         # test for user
1116         log "User quota (block hardlimit:$limit MB)"
1117         $LFS setquota -u $TSTUSR -b 0 -B ${limit}M -i 0 -I 0 $DIR ||
1118                 error "set user quota failed"
1119
1120         # make sure the system is clean
1121         local used=$(getquota -u $TSTUSR global curspace)
1122         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
1123
1124         $LFS setstripe $testfile -c 1 || error "setstripe $testfile failed"
1125         chown $TSTUSR.$TSTUSR $testfile || error "chown $testfile failed"
1126
1127         check_write_fallocate $testfile "user" $limit
1128
1129         rm -f $testfile
1130         wait_delete_completed || error "wait_delete_completed failed"
1131         sync_all_data || true
1132         used=$(getquota -u $TSTUSR global curspace)
1133         [ $used -ne 0 ] && quota_error u $TSTUSR \
1134                 "user quota isn't released after deletion"
1135         resetquota -u $TSTUSR
1136 }
1137 run_test 1h "Block hard limit test using fallocate"
1138
1139 # test inode hardlimit
1140 test_2() {
1141         local TESTFILE="$DIR/$tdir/$tfile-0"
1142         local LIMIT=$(do_facet mds1 $LCTL get_param -n \
1143                 qmt.$FSNAME-QMT0000.md-0x0.info |
1144                 awk '/least qunit/{ print $3 }')
1145         local L2=$(do_facet mds1 $LCTL get_param -n \
1146                 qmt.$FSNAME-QMT0000.md-0x0.soft_least_qunit)
1147
1148         [ $L2 -le $LIMIT ] || LIMIT=$L2
1149
1150         [ "$SLOW" = "no" ] || LIMIT=$((LIMIT * 1024))
1151
1152         local FREE_INODES=$(mdt_free_inodes 0)
1153         echo "$FREE_INODES free inodes on master MDT"
1154         [ $FREE_INODES -lt $LIMIT ] &&
1155                 skip "not enough free inodes $FREE_INODES required $LIMIT"
1156
1157         setup_quota_test || error "setup quota failed with $?"
1158         trap cleanup_quota_test EXIT
1159
1160         # enable mdt quota
1161         set_mdt_qtype $QTYPE || error "enable mdt quota failed"
1162
1163         # test for user
1164         log "User quota (inode hardlimit:$LIMIT files)"
1165         $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I $LIMIT $DIR ||
1166                 error "set user quota failed"
1167
1168         # make sure the system is clean
1169         local USED=$(getquota -u $TSTUSR global curinodes)
1170         [ $USED -ne 0 ] && error "Used inodes($USED) for user $TSTUSR isn't 0."
1171
1172         log "Create $LIMIT files ..."
1173         $RUNAS createmany -m ${TESTFILE} $LIMIT ||
1174                 quota_error u $TSTUSR "user create failure, but expect success"
1175         log "Create out of file quota ..."
1176         $RUNAS touch ${TESTFILE}_xxx &&
1177                 quota_error u $TSTUSR "user create success, but expect EDQUOT"
1178
1179         # cleanup
1180         unlinkmany ${TESTFILE} $LIMIT || error "unlinkmany $TESTFILE failed"
1181         rm -f ${TESTFILE}_xxx
1182         wait_delete_completed
1183
1184         USED=$(getquota -u $TSTUSR global curinodes)
1185         [ $USED -ne 0 ] && quota_error u $TSTUSR \
1186                 "user quota isn't released after deletion"
1187         resetquota -u $TSTUSR
1188
1189         # test for group
1190         log "--------------------------------------"
1191         log "Group quota (inode hardlimit:$LIMIT files)"
1192         $LFS setquota -g $TSTUSR -b 0 -B 0 -i 0 -I $LIMIT $DIR ||
1193                 error "set group quota failed"
1194
1195         TESTFILE=$DIR/$tdir/$tfile-1
1196         # make sure the system is clean
1197         USED=$(getquota -g $TSTUSR global curinodes)
1198         [ $USED -ne 0 ] && error "Used inodes($USED) for group $TSTUSR isn't 0."
1199
1200         log "Create $LIMIT files ..."
1201         $RUNAS createmany -m ${TESTFILE} $LIMIT ||
1202                 quota_error g $TSTUSR "group create failure, but expect success"
1203         log "Create out of file quota ..."
1204         $RUNAS touch ${TESTFILE}_xxx &&
1205                 quota_error g $TSTUSR "group create success, but expect EDQUOT"
1206
1207         # cleanup
1208         unlinkmany ${TESTFILE} $LIMIT || error "unlinkmany $TESTFILE failed"
1209         rm -f ${TESTFILE}_xxx
1210         wait_delete_completed
1211
1212         USED=$(getquota -g $TSTUSR global curinodes)
1213         [ $USED -ne 0 ] && quota_error g $TSTUSR \
1214                 "user quota isn't released after deletion"
1215
1216         resetquota -g $TSTUSR
1217         ! is_project_quota_supported && cleanup_quota_test &&
1218                 echo "Skip project quota is not supported" && return 0
1219
1220         # test for project
1221         log "--------------------------------------"
1222         log "Project quota (inode hardlimit:$LIMIT files)"
1223         $LFS setquota -p $TSTPRJID -b 0 -B 0 -i 0 -I $LIMIT $DIR ||
1224                 error "set project quota failed"
1225
1226         TESTFILE=$DIR/$tdir/$tfile-1
1227         # make sure the system is clean
1228         USED=$(getquota -p $TSTPRJID global curinodes)
1229         [ $USED -ne 0 ] &&
1230                 error "Used inodes($USED) for project $TSTPRJID isn't 0"
1231
1232         change_project -sp $TSTPRJID $DIR/$tdir
1233         log "Create $LIMIT files ..."
1234         $RUNAS createmany -m ${TESTFILE} $((LIMIT-1)) || quota_error p \
1235                 $TSTPRJID "project create fail, but expect success"
1236         log "Create out of file quota ..."
1237         $RUNAS touch ${TESTFILE}_xxx && quota_error p $TSTPRJID \
1238                 "project create success, but expect EDQUOT"
1239         change_project -C $DIR/$tdir
1240
1241         cleanup_quota_test
1242         USED=$(getquota -p $TSTPRJID global curinodes)
1243         [ $USED -eq 0 ] || quota_error p $TSTPRJID \
1244                 "project quota isn't released after deletion"
1245
1246 }
1247 run_test 2 "File hard limit (normal use and out of quota)"
1248
1249 test_block_soft() {
1250         local testfile=$1
1251         local grace=$2
1252         local limit=$3
1253         local OFFSET=0
1254         local qtype=$4
1255         local pool=$5
1256         local soft_limit=$(do_facet $SINGLEMDS $LCTL get_param -n \
1257                 qmt.$FSNAME-QMT0000.dt-0x0.soft_least_qunit)
1258
1259         setup_quota_test
1260         stack_trap cleanup_quota_test EXIT
1261
1262         $LFS setstripe $testfile -c 1 -i 0
1263         chown $TSTUSR.$TSTUSR $testfile
1264         [ "$qtype" == "p" ] && is_project_quota_supported &&
1265                 change_project -p $TSTPRJID $testfile
1266
1267         echo "Write up to soft limit"
1268         $RUNAS $DD of=$testfile count=$limit ||
1269                 quota_error a $TSTUSR "write failure, but expect success"
1270         OFFSET=$((limit * 1024))
1271         cancel_lru_locks osc
1272
1273         echo "Write to exceed soft limit"
1274         $RUNAS dd if=/dev/zero of=$testfile bs=1K count=10 seek=$OFFSET ||
1275                 quota_error a $TSTUSR "write failure, but expect success"
1276         OFFSET=$((OFFSET + 1024)) # make sure we don't write to same block
1277         cancel_lru_locks osc
1278
1279         echo "mmap write when over soft limit"
1280         $RUNAS $MULTIOP $testfile.mmap OT40960SMW ||
1281                 quota_error a $TSTUSR "mmap write failure, but expect success"
1282         cancel_lru_locks osc
1283
1284         $SHOW_QUOTA_USER
1285         $SHOW_QUOTA_GROUP
1286         $SHOW_QUOTA_PROJID
1287         $SHOW_QUOTA_INFO_USER
1288         $SHOW_QUOTA_INFO_GROUP
1289         $SHOW_QUOTA_INFO_PROJID
1290
1291         echo "Write before timer goes off"
1292         $RUNAS dd if=/dev/zero of=$testfile bs=1K count=10 seek=$OFFSET ||
1293                 quota_error a $TSTUSR "write failure, but expect success"
1294         OFFSET=$((OFFSET + 1024))
1295         cancel_lru_locks osc
1296
1297         wait_grace_time $qtype "block" $pool
1298
1299         $SHOW_QUOTA_USER
1300         $SHOW_QUOTA_GROUP
1301         $SHOW_QUOTA_PROJID
1302         $SHOW_QUOTA_INFO_USER
1303         $SHOW_QUOTA_INFO_GROUP
1304         $SHOW_QUOTA_INFO_PROJID
1305
1306         log "Write after timer goes off"
1307         # maybe cache write, ignore.
1308         # write up to soft least quint to consume all
1309         # possible slave granted space.
1310         $RUNAS dd if=/dev/zero of=$testfile bs=1K \
1311                 count=$soft_limit seek=$OFFSET || true
1312         OFFSET=$((OFFSET + soft_limit))
1313         cancel_lru_locks osc
1314         log "Write after cancel lru locks"
1315         $RUNAS dd if=/dev/zero of=$testfile bs=1K count=10 seek=$OFFSET &&
1316                 quota_error a $TSTUSR "write success, but expect EDQUOT"
1317
1318         $SHOW_QUOTA_USER
1319         $SHOW_QUOTA_GROUP
1320         $SHOW_QUOTA_PROJID
1321         $SHOW_QUOTA_INFO_USER
1322         $SHOW_QUOTA_INFO_GROUP
1323         $SHOW_QUOTA_INFO_PROJID
1324
1325         echo "Unlink file to stop timer"
1326         rm -f $testfile
1327         wait_delete_completed
1328         sync_all_data || true
1329
1330         $SHOW_QUOTA_USER
1331         $SHOW_QUOTA_GROUP
1332         $SHOW_QUOTA_PROJID
1333         $SHOW_QUOTA_INFO_USER
1334         $SHOW_QUOTA_INFO_GROUP
1335         $SHOW_QUOTA_INFO_PROJID
1336
1337         $LFS setstripe $testfile -c 1 -i 0
1338         chown $TSTUSR.$TSTUSR $testfile
1339         [ "$qtype" == "p" ] && change_project -p $TSTPRJID $testfile
1340
1341         echo "Write ..."
1342         $RUNAS $DD of=$testfile count=$limit ||
1343                 quota_error a $TSTUSR "write failure, but expect success"
1344         # cleanup
1345         cleanup_quota_test
1346 }
1347
1348 # block soft limit
1349 test_3a() {
1350         local grace=20 # seconds
1351         if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
1352             grace=60
1353         fi
1354         local testfile=$DIR/$tdir/$tfile-0
1355
1356         # get minimum soft qunit size
1357         local limit=$(( $(do_facet $SINGLEMDS $LCTL get_param -n \
1358                 qmt.$FSNAME-QMT0000.dt-0x0.soft_least_qunit) / 1024 ))
1359
1360         set_ost_qtype $QTYPE || error "enable ost quota failed"
1361
1362         echo "User quota (soft limit:$limit MB  grace:$grace seconds)"
1363         # make sure the system is clean
1364         local used=$(getquota -u $TSTUSR global curspace)
1365         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
1366
1367         $LFS setquota -t -u --block-grace $grace --inode-grace \
1368                 $MAX_IQ_TIME $DIR || error "set user grace time failed"
1369         $LFS setquota -u $TSTUSR -b ${limit}M -B 0 -i 0 -I 0 $DIR ||
1370                 error "set user quota failed"
1371
1372         test_block_soft $testfile $grace $limit "u"
1373
1374         echo "Group quota (soft limit:$limit MB  grace:$grace seconds)"
1375         testfile=$DIR/$tdir/$tfile-1
1376         # make sure the system is clean
1377         used=$(getquota -g $TSTUSR global curspace)
1378         [ $used -ne 0 ] && error "Used space($used) for group $TSTUSR isn't 0."
1379
1380         $LFS setquota -t -g --block-grace $grace --inode-grace \
1381                 $MAX_IQ_TIME $DIR || error "set group grace time failed"
1382         $LFS setquota -g $TSTUSR -b ${limit}M -B 0 -i 0 -I 0 $DIR ||
1383                 error "set group quota failed"
1384
1385         test_block_soft $testfile $grace $limit "g"
1386
1387         if is_project_quota_supported; then
1388                 echo "Project quota (soft limit:$limit MB  grace:$grace sec)"
1389                 testfile=$DIR/$tdir/$tfile-2
1390                 # make sure the system is clean
1391                 used=$(getquota -p $TSTPRJID global curspace)
1392                 [ $used -ne 0 ] && error \
1393                         "Used space($used) for project $TSTPRJID isn't 0."
1394
1395                 $LFS setquota -t -p --block-grace $grace --inode-grace \
1396                         $MAX_IQ_TIME $DIR ||
1397                                 error "set project grace time failed"
1398                 $LFS setquota -p $TSTPRJID -b ${limit}M -B 0 -i 0 -I 0 \
1399                         $DIR || error "set project quota failed"
1400
1401                 test_block_soft $testfile $grace $limit "p"
1402                 resetquota -p $TSTPRJID
1403                 $LFS setquota -t -p --block-grace $MAX_DQ_TIME --inode-grace \
1404                         $MAX_IQ_TIME $DIR ||
1405                                 error "restore project grace time failed"
1406         fi
1407
1408         # cleanup
1409         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
1410                 $MAX_IQ_TIME $DIR || error "restore user grace time failed"
1411         $LFS setquota -t -g --block-grace $MAX_DQ_TIME --inode-grace \
1412                 $MAX_IQ_TIME $DIR || error "restore group grace time failed"
1413 }
1414 run_test 3a "Block soft limit (start timer, timer goes off, stop timer)"
1415
1416 test_3b() {
1417         local grace=20 # seconds
1418         local qpool="qpool1"
1419         if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
1420                 grace=60
1421         fi
1422         local testfile=$DIR/$tdir/$tfile-0
1423
1424         mds_supports_qp
1425         # get minimum soft qunit size
1426         local limit=$(( $(do_facet $SINGLEMDS $LCTL get_param -n \
1427                 qmt.$FSNAME-QMT0000.dt-0x0.soft_least_qunit) / 1024 ))
1428         local glbl_limit=$((2*limit))
1429         local glbl_grace=$((2*grace))
1430         echo "limit $limit glbl_limit $glbl_limit"
1431         echo "grace $grace glbl_grace $glbl_grace"
1432
1433         set_ost_qtype $QTYPE || error "enable ost quota failed"
1434
1435         echo "User quota in $qpool(soft limit:$limit MB  grace:$grace seconds)"
1436         # make sure the system is clean
1437         local used=$(getquota -u $TSTUSR global curspace)
1438         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
1439
1440         pool_add $qpool || error "pool_add failed"
1441         pool_add_targets $qpool 0 1 ||
1442                 error "pool_add_targets failed"
1443
1444         $LFS setquota -t -u --block-grace $glbl_grace --inode-grace \
1445                 $MAX_IQ_TIME $DIR || error "set user grace time failed"
1446         $LFS setquota -t -u --block-grace $grace \
1447                 --pool $qpool $DIR || error "set user grace time failed"
1448
1449         $LFS setquota -u $TSTUSR -b ${glbl_limit}M -B 0 -i 0 -I 0 $DIR ||
1450                 error "set user quota failed"
1451         $LFS setquota -u $TSTUSR -b ${limit}M -B 0 --pool $qpool $DIR ||
1452                 error "set user quota failed"
1453
1454         test_block_soft $testfile $grace $limit "u" $qpool
1455
1456         echo "Group quota in $qpool(soft limit:$limit MB  grace:$grace seconds)"
1457         testfile=$DIR/$tdir/$tfile-1
1458         # make sure the system is clean
1459         used=$(getquota -g $TSTUSR global curspace)
1460         [ $used -ne 0 ] && error "Used space($used) for group $TSTUSR isn't 0."
1461
1462         $LFS setquota -t -g --block-grace $glbl_grace --inode-grace \
1463                 $MAX_IQ_TIME $DIR || error "set group grace time failed"
1464         $LFS setquota -t -g --block-grace $grace \
1465                 --pool $qpool $DIR || error "set group grace time failed"
1466
1467         $LFS setquota -g $TSTUSR -b ${glbl_limit}M -B 0 -i 0 -I 0 $DIR ||
1468                 error "set group quota failed"
1469         $LFS setquota -g $TSTUSR -b ${limit}M -B 0 --pool $qpool $DIR ||
1470                 error "set group quota failed"
1471
1472         test_block_soft $testfile $grace $limit "g" $qpool
1473
1474         if is_project_quota_supported; then
1475                 echo "Project quota in $qpool(soft:$limit MB  grace:$grace sec)"
1476                 testfile=$DIR/$tdir/$tfile-2
1477                 # make sure the system is clean
1478                 used=$(getquota -p $TSTPRJID global curspace)
1479                 [ $used -ne 0 ] && error \
1480                         "Used space($used) for project $TSTPRJID isn't 0."
1481
1482                 $LFS setquota -t -p --block-grace $glbl_grace --inode-grace \
1483                         $MAX_IQ_TIME $DIR ||
1484                                 error "set project grace time failed"
1485                 $LFS setquota -t -p --block-grace $grace \
1486                         --pool $qpool $DIR ||
1487                                 error "set project grace time failed"
1488
1489                 $LFS setquota -p $TSTPRJID -b ${glbl_limit}M -B 0 -i 0 -I 0 \
1490                         $DIR || error "set project quota failed"
1491                 $LFS setquota -p $TSTPRJID -b ${limit}M -B 0 \
1492                         --pool $qpool $DIR || error "set project quota failed"
1493
1494                 test_block_soft $testfile $grace $limit "p" $qpool
1495                 resetquota -p $TSTPRJID
1496                 $LFS setquota -t -p --block-grace $MAX_DQ_TIME --inode-grace \
1497                         $MAX_IQ_TIME $DIR ||
1498                                 error "restore project grace time failed"
1499                 $LFS setquota -t -p --block-grace $MAX_DQ_TIME --pool $qpool \
1500                         $DIR || error "set project grace time failed"
1501         fi
1502
1503         # cleanup
1504         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
1505                 $MAX_IQ_TIME $DIR || error "restore user grace time failed"
1506         $LFS setquota -t -u --block-grace $MAX_DQ_TIME \
1507                 --pool $qpool $DIR || error "restore user grace time failed"
1508         $LFS setquota -t -g --block-grace $MAX_DQ_TIME --inode-grace \
1509                 $MAX_IQ_TIME $DIR || error "restore group grace time failed"
1510         $LFS setquota -t -g --block-grace $MAX_DQ_TIME \
1511                 --pool $qpool $DIR || error "restore group grace time failed"
1512 }
1513 run_test 3b "Quota pools: Block soft limit (start timer, expires, stop timer)"
1514
1515 test_3c() {
1516         local grace=20 # seconds
1517         local qpool="qpool1"
1518         local qpool2="qpool2"
1519         if [ $(facet_fstype $SINGLEMDS) = "zfs" ]; then
1520                 grace=60
1521         fi
1522         local testfile=$DIR/$tdir/$tfile-0
1523
1524         mds_supports_qp
1525         # get minimum soft qunit size
1526         local limit=$(( $(do_facet $SINGLEMDS $LCTL get_param -n \
1527                 qmt.$FSNAME-QMT0000.dt-0x0.soft_least_qunit) / 1024 ))
1528         local limit2=$((limit+4))
1529         local glbl_limit=$((limit+8))
1530         local grace1=$((grace+10))
1531         local grace2=$grace
1532         local glbl_grace=$((grace+20))
1533         echo "limit $limit limit2 $limit2 glbl_limit $glbl_limit"
1534         echo "grace1 $grace1 grace2 $grace2 glbl_grace $glbl_grace"
1535
1536         set_ost_qtype $QTYPE || error "enable ost quota failed"
1537
1538         echo "User quota in qpool2(soft:$limit2 MB grace:$grace2 seconds)"
1539         # make sure the system is clean
1540         local used=$(getquota -u $TSTUSR global curspace)
1541         [ $used -ne 0 ] && error "Used space($used) for user $TSTUSR isn't 0."
1542
1543         pool_add $qpool || error "pool_add failed"
1544         pool_add_targets $qpool 0 1 ||
1545                 error "pool_add_targets failed"
1546
1547         pool_add $qpool2 || error "pool_add failed"
1548         pool_add_targets $qpool2 0 1 ||
1549                 error "pool_add_targets failed"
1550
1551
1552         $LFS setquota -t -u --block-grace $glbl_grace --inode-grace \
1553                 $MAX_IQ_TIME $DIR || error "set user grace time failed"
1554         $LFS setquota -t -u --block-grace $grace1 \
1555                 --pool $qpool $DIR || error "set user grace time failed"
1556         $LFS setquota -t -u --block-grace $grace2 \
1557                 --pool $qpool2 $DIR || error "set user grace time failed"
1558
1559         $LFS setquota -u $TSTUSR -b ${glbl_limit}M -B 0 -i 0 -I 0 $DIR ||
1560                 error "set user quota failed"
1561         $LFS setquota -u $TSTUSR -b ${limit}M -B 0 --pool $qpool $DIR ||
1562                 error "set user quota failed"
1563         # qpool has minimum soft limit, but it's grace is grater than
1564         # grace period of qpool2. Thus write shouldn't fail when
1565         # hit qpool soft limit - only when reaches up qpool2 limit
1566         # after grace2 seconds.
1567         $LFS setquota -u $TSTUSR -b ${limit2}M -B 0 --pool $qpool2 $DIR ||
1568                 error "set user quota failed"
1569
1570         test_block_soft $testfile $grace2 $limit2 "u" $qpool2
1571
1572         # cleanup
1573         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
1574                 $MAX_IQ_TIME $DIR || error "restore user grace time failed"
1575         $LFS setquota -t -u --block-grace $MAX_DQ_TIME \
1576                 --pool $qpool $DIR || error "restore user grace time failed"
1577         $LFS setquota -t -u --block-grace $MAX_DQ_TIME \
1578                 --pool $qpool2 $DIR || error "restore user grace time failed"
1579 }
1580 run_test 3c "Quota pools: check block soft limit on different pools"
1581
1582 test_file_soft() {
1583         local TESTFILE=$1
1584         local LIMIT=$2
1585         local grace=$3
1586         local qtype=$4
1587         local SOFT_LIMIT=$(do_facet $SINGLEMDS $LCTL get_param -n \
1588                 qmt.$FSNAME-QMT0000.md-0x0.soft_least_qunit)
1589
1590         setup_quota_test 0
1591         trap cleanup_quota_test EXIT
1592         is_project_quota_supported && change_project -sp $TSTPRJID $DIR/$tdir
1593
1594         echo "Create files to exceed soft limit"
1595         $RUNAS createmany -m ${TESTFILE}_ $((LIMIT + 1)) ||
1596                 quota_error a $TSTUSR "create failure, but expect success"
1597         local trigger_time=$(date +%s)
1598
1599         sync_all_data || true
1600
1601         local cur_time=$(date +%s)
1602         [ $(($cur_time - $trigger_time)) -ge $grace ] &&
1603                 error "Passed grace time $grace, $trigger_time, $cur_time"
1604
1605         echo "Create file before timer goes off"
1606         $RUNAS touch ${TESTFILE}_before ||
1607                 quota_error a $TSTUSR "failed create before timer expired," \
1608                         "but expect success. $trigger_time, $cur_time"
1609         sync_all_data || true
1610
1611         wait_grace_time $qtype "file"
1612
1613         $SHOW_QUOTA_USER
1614         $SHOW_QUOTA_GROUP
1615         $SHOW_QUOTA_PROJID
1616         $SHOW_QUOTA_INFO_USER
1617         $SHOW_QUOTA_INFO_GROUP
1618         $SHOW_QUOTA_INFO_PROJID
1619
1620         echo "Create file after timer goes off"
1621         # exceed least soft limit is possible
1622         $RUNAS createmany -m ${TESTFILE}_after_3 $((SOFT_LIMIT + 1)) &&
1623                 quota_error a $TSTUSR "create after timer expired," \
1624                         "but expect EDQUOT"
1625         sync_all_data || true
1626
1627         $SHOW_QUOTA_USER
1628         $SHOW_QUOTA_GROUP
1629         $SHOW_QUOTA_PROJID
1630         $SHOW_QUOTA_INFO_USER
1631         $SHOW_QUOTA_INFO_GROUP
1632         $SHOW_QUOTA_INFO_PROJID
1633
1634         echo "Unlink files to stop timer"
1635         find $(dirname $TESTFILE) -name "$(basename ${TESTFILE})*" | xargs rm -f
1636         wait_delete_completed
1637
1638         echo "Create file"
1639         $RUNAS touch ${TESTFILE}_xxx ||
1640                 quota_error a $TSTUSR "touch after timer stop failure," \
1641                         "but expect success"
1642         sync_all_data || true
1643
1644         # cleanup
1645         cleanup_quota_test
1646 }
1647
1648 # file soft limit
1649 test_4a() {
1650         local LIMIT=$(do_facet $SINGLEMDS $LCTL get_param -n \
1651                 qmt.$FSNAME-QMT0000.md-0x0.soft_least_qunit)
1652         local TESTFILE=$DIR/$tdir/$tfile-0
1653         local GRACE=12
1654
1655         set_mdt_qtype $QTYPE || error "enable mdt quota failed"
1656
1657         echo "User quota (soft limit:$LIMIT files  grace:$GRACE seconds)"
1658         # make sure the system is clean
1659         local USED=$(getquota -u $TSTUSR global curinodes)
1660         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
1661
1662         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
1663                 $GRACE $DIR || error "set user grace time failed"
1664         $LFS setquota -u $TSTUSR -b 0 -B 0 -i $LIMIT -I 0 $DIR ||
1665                 error "set user quota failed"
1666
1667         [ "$mds1_FSTYPE" = zfs ] && GRACE=20
1668
1669         test_file_soft $TESTFILE $LIMIT $GRACE "u"
1670
1671         echo "Group quota (soft limit:$LIMIT files  grace:$GRACE seconds)"
1672         # make sure the system is clean
1673         USED=$(getquota -g $TSTUSR global curinodes)
1674         [ $USED -ne 0 ] && error "Used space($USED) for group $TSTUSR isn't 0."
1675
1676         $LFS setquota -t -g --block-grace $MAX_DQ_TIME --inode-grace \
1677                 $GRACE $DIR || error "set group grace time failed"
1678         $LFS setquota -g $TSTUSR -b 0 -B 0 -i $LIMIT -I 0 $DIR ||
1679                 error "set group quota failed"
1680         TESTFILE=$DIR/$tdir/$tfile-1
1681
1682         test_file_soft $TESTFILE $LIMIT $GRACE "g"
1683
1684         if is_project_quota_supported; then
1685                 echo "Project quota (soft limit:$LIMIT files grace:$GRACE sec)"
1686                 # make sure the system is clean
1687                 USED=$(getquota -p $TSTPRJID global curinodes)
1688                 [ $USED -ne 0 ] && error \
1689                         "Used space($USED) for project $TSTPRJID isn't 0."
1690
1691                 $LFS setquota -t -p --block-grace $MAX_DQ_TIME --inode-grace \
1692                         $GRACE $DIR || error "set project grace time failed"
1693                 $LFS setquota -p $TSTPRJID -b 0 -B 0 -i $LIMIT -I 0 $DIR ||
1694                         error "set project quota failed"
1695
1696                 TESTFILE=$DIR/$tdir/$tfile-1
1697                 # one less than limit, because of parent directory included.
1698                 test_file_soft $TESTFILE $((LIMIT-1)) $GRACE "p"
1699                 resetquota -p $TSTPRJID
1700                 $LFS setquota -t -p --block-grace $MAX_DQ_TIME --inode-grace \
1701                         $MAX_IQ_TIME $DIR ||
1702                                 error "restore project grace time failed"
1703         fi
1704
1705         # cleanup
1706         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
1707                 $MAX_IQ_TIME $DIR || error "restore user grace time failed"
1708         $LFS setquota -t -g --block-grace $MAX_DQ_TIME --inode-grace \
1709                 $MAX_IQ_TIME $DIR || error "restore group grace time failed"
1710 }
1711 run_test 4a "File soft limit (start timer, timer goes off, stop timer)"
1712
1713 test_4b() {
1714         local GR_STR1="1w3d"
1715         local GR_STR2="1000s"
1716         local GR_STR3="5s"
1717         local GR_STR4="1w2d3h4m5s"
1718         local GR_STR5="5c"
1719         local GR_STR6="18446744073709551615"
1720         local GR_STR7="-1"
1721
1722         wait_delete_completed
1723
1724         # test of valid grace strings handling
1725         echo "Valid grace strings test"
1726         $LFS setquota -t -u --block-grace $GR_STR1 --inode-grace \
1727                 $GR_STR2 $DIR || error "set user grace time failed"
1728         $LFS quota -u -t $DIR | grep "Block grace time: $GR_STR1"
1729         $LFS setquota -t -g --block-grace $GR_STR3 --inode-grace \
1730                 $GR_STR4 $DIR || error "set group grace time quota failed"
1731         $LFS quota -g -t $DIR | grep "Inode grace time: $GR_STR4"
1732
1733         # test of invalid grace strings handling
1734         echo "  Invalid grace strings test"
1735         ! $LFS setquota -t -u --block-grace $GR_STR4 --inode-grace $GR_STR5 $DIR
1736         ! $LFS setquota -t -g --block-grace $GR_STR4 --inode-grace $GR_STR6 $DIR
1737         ! $LFS setquota -t -g --block-grace $GR_STR4 --inode-grace \
1738                 $GR_STR7 $DIR
1739
1740         # cleanup
1741         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
1742                 $MAX_IQ_TIME $DIR || error "restore user grace time failed"
1743         $LFS setquota -t -g --block-grace $MAX_DQ_TIME --inode-grace \
1744                 $MAX_IQ_TIME $DIR || error "restore group grace time failed"
1745 }
1746 run_test 4b "Grace time strings handling"
1747
1748 # chown & chgrp (chown & chgrp successfully even out of block/file quota)
1749 test_5() {
1750         local BLIMIT=10 # MB
1751         local ILIMIT=10 # inodes
1752
1753         setup_quota_test || error "setup quota failed with $?"
1754         trap cleanup_quota_test EXIT
1755
1756         set_mdt_qtype $QTYPE || error "enable mdt quota failed"
1757         set_ost_qtype $QTYPE || error "enable ost quota failed"
1758
1759         echo "Set quota limit (0 ${BLIMIT}M 0 $ILIMIT) for $TSTUSR.$TSTUSR"
1760         $LFS setquota -u $TSTUSR -b 0 -B ${BLIMIT}M -i 0 -I $ILIMIT $DIR ||
1761                 error "set user quota failed"
1762         $LFS setquota -g $TSTUSR -b 0 -B ${BLIMIT}M -i 0 -I $ILIMIT $DIR ||
1763         if is_project_quota_supported; then
1764                 error "set group quota failed"
1765                 $LFS setquota -p $TSTPRJID -b 0 -B ${BLIMIT}M -i 0 \
1766                         -I $ILIMIT $DIR || error "set project quota failed"
1767         fi
1768
1769         # make sure the system is clean
1770         local USED=$(getquota -u $TSTUSR global curinodes)
1771         [ $USED -ne 0 ] && error "Used inode($USED) for user $TSTUSR isn't 0."
1772         USED=$(getquota -g $TSTUSR global curinodes)
1773         [ $USED -ne 0 ] && error "Used inode($USED) for group $TSTUSR isn't 0."
1774         USED=$(getquota -u $TSTUSR global curspace)
1775         [ $USED -ne 0 ] && error "Used block($USED) for user $TSTUSR isn't 0."
1776         USED=$(getquota -g $TSTUSR global curspace)
1777         [ $USED -ne 0 ] && error "Used block($USED) for group $TSTUSR isn't 0."
1778         if is_project_quota_supported; then
1779                 USED=$(getquota -p $TSTPRJID global curinodes)
1780                 [ $USED -ne 0 ] &&
1781                         error "Used inode($USED) for project $TSTPRJID isn't 0."
1782                 USED=$(getquota -p $TSTPRJID global curspace)
1783                 [ $USED -ne 0 ] &&
1784                         error "Used block($USED) for project $TSTPRJID isn't 0."
1785         fi
1786
1787         echo "Create more than $ILIMIT files and more than $BLIMIT MB ..."
1788         createmany -m $DIR/$tdir/$tfile-0_ $((ILIMIT + 1)) ||
1789                 error "create failure, expect success"
1790         if is_project_quota_supported; then
1791                 touch $DIR/$tdir/$tfile-0_1
1792                 change_project -p $TSTPRJID $DIR/$tdir/$tfile-0_1
1793         fi
1794         $DD of=$DIR/$tdir/$tfile-0_1 count=$((BLIMIT+1)) ||
1795                 error "write failure, expect success"
1796
1797         echo "Chown files to $TSTUSR.$TSTUSR ..."
1798         for i in $(seq 0 $ILIMIT); do
1799                 chown $TSTUSR.$TSTUSR $DIR/$tdir/$tfile-0_$i ||
1800                         quota_error a $TSTUSR "chown failure, expect success"
1801         done
1802
1803         # cleanup
1804         unlinkmany $DIR/$tdir/$tfile-0_ $((ILIMIT + 1)) ||
1805                 error "unlinkmany $DIR/$tdir/$tfile-0_ failed"
1806         cleanup_quota_test
1807 }
1808 run_test 5 "Chown & chgrp successfully even out of block/file quota"
1809
1810 # test dropping acquire request on master
1811 test_6() {
1812         local LIMIT=3 # MB
1813
1814         # Clear dmesg so watchdog is not triggered by previous
1815         # test output
1816         do_facet ost1 dmesg -c > /dev/null
1817
1818         setup_quota_test || error "setup quota failed with $?"
1819         trap cleanup_quota_test EXIT
1820
1821         # make sure the system is clean
1822         local USED=$(getquota -u $TSTUSR global curspace)
1823         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
1824
1825         # make sure no granted quota on ost
1826         set_ost_qtype $QTYPE || error "enable ost quota failed"
1827         resetquota -u $TSTUSR
1828
1829         # create file for $TSTUSR
1830         local TESTFILE=$DIR/$tdir/$tfile-$TSTUSR
1831         $LFS setstripe $TESTFILE -c 1 -i 0 || error "setstripe $TESTFILE failed"
1832         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
1833
1834         # create file for $TSTUSR2
1835         local TESTFILE2=$DIR/$tdir/$tfile-$TSTUSR2
1836         $LFS setstripe $TESTFILE2 -c 1 -i 0 || error "setstripe $TESTFILE2 failed"
1837         chown $TSTUSR2.$TSTUSR2 $TESTFILE2 || error "chown $TESTFILE2 failed"
1838
1839         # cache per-ID lock for $TSTUSR on slave
1840         $LFS setquota -u $TSTUSR -b 0 -B ${LIMIT}M -i 0 -I 0 $DIR ||
1841                 error "set quota failed"
1842         $RUNAS $DD of=$TESTFILE count=1 ||
1843                 error "write $TESTFILE failure, expect success"
1844         $RUNAS2 $DD of=$TESTFILE2 count=1 ||
1845                 error "write $TESTFILE2 failure, expect success"
1846
1847         if at_is_enabled; then
1848                 at_max_saved=$(at_max_get ost1)
1849                 at_max_set $TIMEOUT ost1
1850
1851                 # write to enforced ID ($TSTUSR) to exceed limit to make sure
1852                 # DQACQ is sent, which makes at_max to take effect
1853                 $RUNAS $DD of=$TESTFILE count=$LIMIT seek=1 oflag=sync \
1854                                                                 conv=notrunc
1855                 rm -f $TESTFILE
1856                 wait_delete_completed
1857         fi
1858
1859         sync; sync
1860         sync_all_data || true
1861
1862         #define QUOTA_DQACQ 601
1863         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC 0x513
1864         lustre_fail mds 0x513 601
1865
1866         do_facet ost1 $LCTL set_param \
1867                         osd-*.$FSNAME-OST*.quota_slave.timeout=$((TIMEOUT / 2))
1868
1869         # write to un-enforced ID ($TSTUSR2) should succeed
1870         $RUNAS2 $DD of=$TESTFILE2 count=$LIMIT seek=1 oflag=sync conv=notrunc ||
1871                 error "write failure, expect success"
1872
1873         # write to enforced ID ($TSTUSR) in background, exceeding limit
1874         # to make sure DQACQ is sent
1875         $RUNAS $DD of=$TESTFILE count=$LIMIT seek=1 oflag=sync conv=notrunc &
1876         DDPID=$!
1877
1878         # watchdog timer uses a factor of 2
1879         echo "Sleep for $((TIMEOUT * 2 + 1)) seconds ..."
1880         sleep $((TIMEOUT * 2 + 1))
1881
1882         [ $at_max_saved -ne 0 ] && at_max_set $at_max_saved ost1
1883
1884         # write should be blocked and never finished
1885         if ! ps -p $DDPID  > /dev/null 2>&1; then
1886                 lustre_fail mds 0 0
1887                 error "write finished incorrectly!"
1888         fi
1889
1890         lustre_fail mds 0 0
1891
1892         # no watchdog is triggered
1893         do_facet ost1 dmesg > $TMP/lustre-log-${TESTNAME}.log
1894         watchdog=$(awk '/[Ss]ervice thread pid/ && /was inactive/ \
1895                         { print; }' $TMP/lustre-log-${TESTNAME}.log)
1896         [ -z "$watchdog" ] || error "$watchdog"
1897
1898         rm -f $TMP/lustre-log-${TESTNAME}.log
1899
1900         # write should continue then fail with EDQUOT
1901         local count=0
1902         local c_size
1903         while [ true ]; do
1904                 if ! ps -p ${DDPID} > /dev/null 2>&1; then break; fi
1905                 if [ $count -ge 240 ]; then
1906                         quota_error u $TSTUSR "dd not finished in $count secs"
1907                 fi
1908                 count=$((count + 1))
1909                 if [ $((count % 30)) -eq 0 ]; then
1910                         c_size=$(stat -c %s $TESTFILE)
1911                         echo "Waiting $count secs. $c_size"
1912                         $SHOW_QUOTA_USER
1913                 fi
1914                 sleep 1
1915         done
1916
1917         cleanup_quota_test
1918 }
1919 run_test 6 "Test dropping acquire request on master"
1920
1921 # quota reintegration (global index)
1922 test_7a() {
1923         local TESTFILE=$DIR/$tdir/$tfile
1924         local LIMIT=20 # MB
1925
1926         [ "$SLOW" = "no" ] && LIMIT=5
1927
1928         setup_quota_test || error "setup quota failed with $?"
1929         trap cleanup_quota_test EXIT
1930
1931         # make sure the system is clean
1932         local USED=$(getquota -u $TSTUSR global curspace)
1933         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
1934
1935         # make sure no granted quota on ost1
1936         set_ost_qtype $QTYPE || error "enable ost quota failed"
1937         resetquota -u $TSTUSR
1938         set_ost_qtype "none" || error "disable ost quota failed"
1939
1940         local OSTUUID=$(ostuuid_from_index 0)
1941         USED=$(getquota -u $TSTUSR $OSTUUID bhardlimit)
1942         [ $USED -ne 0 ] &&
1943                 error "limit($USED) on $OSTUUID for user $TSTUSR isn't 0"
1944
1945         # create test file
1946         $LFS setstripe $TESTFILE -c 1 -i 0 || error "setstripe $TESTFILE failed"
1947         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
1948
1949         echo "Stop ost1..."
1950         stop ost1
1951
1952         echo "Enable quota & set quota limit for $TSTUSR"
1953         set_ost_qtype $QTYPE || error "enable ost quota failed"
1954         $LFS setquota -u $TSTUSR -b 0 -B ${LIMIT}M -i 0 -I 0 $DIR ||
1955                 error "set quota failed"
1956
1957         echo "Start ost1..."
1958         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "start ost1 failed"
1959         quota_init
1960
1961         wait_ost_reint $QTYPE || error "reintegration failed"
1962
1963         # hardlimit should have been fetched by slave during global
1964         # reintegration, write will exceed quota
1965         $RUNAS $DD of=$TESTFILE count=$((LIMIT + 1)) oflag=sync &&
1966                 quota_error u $TSTUSR "write success, but expect EDQUOT"
1967
1968         rm -f $TESTFILE
1969         wait_delete_completed
1970         sync_all_data || true
1971         sleep 3
1972
1973         echo "Stop ost1..."
1974         stop ost1
1975
1976         $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I 0 $DIR ||
1977                 error "clear quota failed"
1978
1979         echo "Start ost1..."
1980         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "start ost1 failed"
1981         quota_init
1982
1983         wait_ost_reint $QTYPE || error "reintegration failed"
1984
1985         # hardlimit should be cleared on slave during reintegration
1986         $RUNAS $DD of=$TESTFILE count=$((LIMIT + 1)) oflag=sync ||
1987                 quota_error u $TSTUSR "write error, but expect success"
1988
1989         cleanup_quota_test
1990 }
1991 run_test 7a "Quota reintegration (global index)"
1992
1993 # quota reintegration (slave index)
1994 test_7b() {
1995         local limit=100000 # MB
1996         local TESTFILE=$DIR/$tdir/$tfile
1997
1998         setup_quota_test || error "setup quota failed with $?"
1999         trap cleanup_quota_test EXIT
2000
2001         # make sure the system is clean
2002         local USED=$(getquota -u $TSTUSR global curspace)
2003         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
2004
2005         # make sure no granted quota on ost1
2006         set_ost_qtype $QTYPE || error "enable ost quota failed"
2007         resetquota -u $TSTUSR
2008         set_ost_qtype "none" || error "disable ost quota failed"
2009
2010         local OSTUUID=$(ostuuid_from_index 0)
2011         USED=$(getquota -u $TSTUSR $OSTUUID bhardlimit)
2012         [ $USED -ne 0 ] &&
2013                 error "limit($USED) on $OSTUUID for user $TSTUSR isn't 0"
2014
2015         # create test file
2016         $LFS setstripe $TESTFILE -c 1 -i 0 || error "setstripe $TESTFILE failed"
2017         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
2018
2019         # consume some space to make sure the granted space will not
2020         # be released during reconciliation
2021         $RUNAS $DD of=$TESTFILE count=1 oflag=sync ||
2022                 error "consume space failure, expect success"
2023
2024         # define OBD_FAIL_QUOTA_EDQUOT 0xa02
2025         lustre_fail mds 0xa02
2026
2027         set_ost_qtype $QTYPE || error "enable ost quota failed"
2028         $LFS setquota -u $TSTUSR -b 0 -B ${limit}M -i 0 -I 0 $DIR ||
2029                 error "set quota failed"
2030
2031         # ignore the write error
2032         $RUNAS $DD of=$TESTFILE count=1 seek=1 oflag=sync conv=notrunc
2033
2034         local old_used=$(getquota -u $TSTUSR $OSTUUID bhardlimit)
2035
2036         lustre_fail mds 0
2037
2038         echo "Restart ost to trigger reintegration..."
2039         stop ost1
2040         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "start ost1 failed"
2041         quota_init
2042
2043         wait_ost_reint $QTYPE || error "reintegration failed"
2044
2045         USED=$(getquota -u $TSTUSR $OSTUUID bhardlimit)
2046         [ $USED -gt $old_used ] || error "limit on $OSTUUID $USED <= $old_used"
2047
2048         cleanup_quota_test
2049         $SHOW_QUOTA_USER
2050 }
2051 run_test 7b "Quota reintegration (slave index)"
2052
2053 # quota reintegration (restart mds during reintegration)
2054 test_7c() {
2055         local LIMIT=20 # MB
2056         local TESTFILE=$DIR/$tdir/$tfile
2057
2058         [ "$SLOW" = "no" ] && LIMIT=5
2059
2060         setup_quota_test || error "setup quota failed with $?"
2061         trap cleanup_quota_test EXIT
2062
2063         # make sure the system is clean
2064         local USED=$(getquota -u $TSTUSR global curspace)
2065         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
2066
2067         set_ost_qtype "none" || error "disable ost quota failed"
2068         $LFS setquota -u $TSTUSR -b 0 -B ${LIMIT}M -i 0 -I 0 $DIR ||
2069                 error "set quota failed"
2070
2071         # define OBD_FAIL_QUOTA_DELAY_REINT 0xa03
2072         lustre_fail ost 0xa03
2073
2074         # enable ost quota
2075         set_ost_qtype $QTYPE || error "enable ost quota failed"
2076         # trigger reintegration
2077         local procf="osd-$ost1_FSTYPE.$FSNAME-OST*."
2078         procf=${procf}quota_slave.force_reint
2079         do_facet ost1 $LCTL set_param $procf=1 ||
2080                 error "force reintegration failed"
2081
2082         echo "Stop mds..."
2083         stop mds1
2084
2085         lustre_fail ost 0
2086
2087         echo "Start mds..."
2088         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
2089         quota_init
2090
2091         # wait longer than usual to make sure the reintegration
2092         # is triggered by quota wb thread.
2093         wait_ost_reint $QTYPE 200 || error "reintegration failed"
2094
2095         # hardlimit should have been fetched by slave during global
2096         # reintegration, write will exceed quota
2097         $RUNAS $DD of=$TESTFILE count=$((LIMIT + 1)) oflag=sync &&
2098                 quota_error u $TSTUSR "write success, but expect EDQUOT"
2099
2100         cleanup_quota_test
2101 }
2102 run_test 7c "Quota reintegration (restart mds during reintegration)"
2103
2104 # Quota reintegration (Transfer index in multiple bulks)
2105 test_7d(){
2106         local TESTFILE=$DIR/$tdir/$tfile
2107         local TESTFILE1="$DIR/$tdir/$tfile"-1
2108         local limit=20 # MB
2109
2110         setup_quota_test || error "setup quota failed with $?"
2111         trap cleanup_quota_test EXIT
2112
2113         set_ost_qtype "none" || error "disable ost quota failed"
2114         $LFS setquota -u $TSTUSR -B ${limit}M $DIR ||
2115                 error "set quota for $TSTUSR failed"
2116         $LFS setquota -u $TSTUSR2 -B ${limit}M $DIR ||
2117                 error "set quota for $TSTUSR2 failed"
2118
2119         #define OBD_FAIL_OBD_IDX_READ_BREAK 0x608
2120         lustre_fail mds 0x608 0
2121
2122         # enable quota to tirgger reintegration
2123         set_ost_qtype "u" || error "enable ost quota failed"
2124         wait_ost_reint "u" || error "reintegration failed"
2125
2126         lustre_fail mds 0
2127
2128         # hardlimit should have been fetched by slave during global
2129         # reintegration, write will exceed quota
2130         $RUNAS $DD of=$TESTFILE count=$((limit + 1)) oflag=sync &&
2131                 quota_error u $TSTUSR "$TSTUSR write success, expect EDQUOT"
2132
2133         $RUNAS2 $DD of=$TESTFILE1 count=$((limit + 1)) oflag=sync &&
2134                 quota_error u $TSTUSR2 "$TSTUSR2 write success, expect EDQUOT"
2135
2136         cleanup_quota_test
2137 }
2138 run_test 7d "Quota reintegration (Transfer index in multiple bulks)"
2139
2140 # quota reintegration (inode limits)
2141 test_7e() {
2142         [ "$MDSCOUNT" -lt "2" ] && skip "needs >= 2 MDTs"
2143
2144         # LU-2435: skip this quota test if underlying zfs version has not
2145         # supported native dnode accounting
2146         [ "$mds1_FSTYPE" == zfs ] && {
2147                 local F="feature@userobj_accounting"
2148                 local pool=$(zpool_name mds1)
2149                 local feature=$(do_facet mds1 $ZPOOL get -H $F $pool)
2150
2151                 [[ "$feature" != *" active "* ]] &&
2152                         skip "requires zpool with active userobj_accounting"
2153         }
2154
2155         local ilimit=$((1024 * 2)) # inodes
2156         local TESTFILE=$DIR/${tdir}-1/$tfile
2157
2158         setup_quota_test || error "setup quota failed with $?"
2159         trap cleanup_quota_test EXIT
2160
2161         # make sure the system is clean
2162         local USED=$(getquota -u $TSTUSR global curinodes)
2163         [ $USED -ne 0 ] && error "Used inode($USED) for user $TSTUSR isn't 0."
2164
2165         # make sure no granted quota on mdt1
2166         set_mdt_qtype $QTYPE || error "enable mdt quota failed"
2167         resetquota -u $TSTUSR
2168         set_mdt_qtype "none" || error "disable mdt quota failed"
2169
2170         local MDTUUID=$(mdtuuid_from_index $((MDSCOUNT - 1)))
2171         USED=$(getquota -u $TSTUSR $MDTUUID ihardlimit)
2172         [ $USED -ne 0 ] && error "limit($USED) on $MDTUUID for user" \
2173                 "$TSTUSR isn't 0."
2174
2175         echo "Stop mds${MDSCOUNT}..."
2176         stop mds${MDSCOUNT}
2177
2178         echo "Enable quota & set quota limit for $TSTUSR"
2179         set_mdt_qtype $QTYPE || error "enable mdt quota failed"
2180         $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I $ilimit $DIR ||
2181                 error "set quota failed"
2182
2183         echo "Start mds${MDSCOUNT}..."
2184         start mds${MDSCOUNT} $(mdsdevname $MDSCOUNT) $MDS_MOUNT_OPTS
2185         quota_init
2186
2187         wait_mdt_reint $QTYPE || error "reintegration failed"
2188
2189         echo "create remote dir"
2190         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/${tdir}-1 ||
2191                 error "create remote dir failed"
2192         chmod 0777 $DIR/${tdir}-1
2193
2194         # hardlimit should have been fetched by slave during global
2195         # reintegration, create will exceed quota
2196         $RUNAS createmany -m $TESTFILE $((ilimit + 1)) &&
2197                 quota_error u $TSTUSR "create succeeded, expect EDQUOT"
2198
2199         $RUNAS unlinkmany $TESTFILE $ilimit || error "unlink files failed"
2200         wait_delete_completed
2201         sync_all_data || true
2202
2203         echo "Stop mds${MDSCOUNT}..."
2204         stop mds${MDSCOUNT}
2205
2206         $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I 0 $DIR ||
2207                 error "clear quota failed"
2208
2209         echo "Start mds${MDSCOUNT}..."
2210         start mds${MDSCOUNT} $(mdsdevname $MDSCOUNT) $MDS_MOUNT_OPTS
2211         quota_init
2212
2213         wait_mdt_reint $QTYPE || error "reintegration failed"
2214
2215         # hardlimit should be cleared on slave during reintegration
2216         $RUNAS createmany -m $TESTFILE $((ilimit + 1)) ||
2217                 quota_error u $TSTUSR "create failed, expect success"
2218
2219         $RUNAS unlinkmany $TESTFILE $((ilimit + 1)) || error "unlink failed"
2220         rmdir $DIR/${tdir}-1 || error "unlink remote dir failed"
2221
2222         cleanup_quota_test
2223 }
2224 run_test 7e "Quota reintegration (inode limits)"
2225
2226 # run dbench with quota enabled
2227 test_8() {
2228         local BLK_LIMIT="100g" #100G
2229         local FILE_LIMIT=1000000
2230
2231         setup_quota_test || error "setup quota failed with $?"
2232         trap cleanup_quota_test EXIT
2233
2234         set_mdt_qtype $QTYPE || error "enable mdt quota failed"
2235         set_ost_qtype $QTYPE || error "enable ost quota failed"
2236
2237         echo "Set enough high limit for user: $TSTUSR"
2238         $LFS setquota -u $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $DIR ||
2239                 error "set user quota failed"
2240         echo "Set enough high limit for group: $TSTUSR"
2241         $LFS setquota -g $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $DIR ||
2242                 error "set group quota failed"
2243         if is_project_quota_supported; then
2244                 change_project -sp $TSTPRJID $DIR/$tdir
2245                 echo "Set enough high limit for project: $TSTPRJID"
2246                 $LFS setquota -p $TSTPRJID -b 0 \
2247                         -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $DIR ||
2248                         error "set project quota failed"
2249         fi
2250
2251         local duration=""
2252         [ "$SLOW" = "no" ] && duration=" -t 120"
2253         $RUNAS bash rundbench -D $DIR/$tdir 3 $duration ||
2254                 quota_error a $TSTUSR "dbench failed!"
2255
2256         is_project_quota_supported && change_project -C $DIR/$tdir
2257         cleanup_quota_test
2258 }
2259 run_test 8 "Run dbench with quota enabled"
2260
2261 # this check is just for test_9
2262 OST0_MIN=4900000 #4.67G
2263
2264 check_whether_skip () {
2265         local OST0_SIZE=$($LFS df $DIR | awk '/\[OST:0\]/ {print $4}')
2266         log "OST0_SIZE: $OST0_SIZE  required: $OST0_MIN"
2267         if [ $OST0_SIZE -lt $OST0_MIN ]; then
2268                 echo "WARN: OST0 has less than $OST0_MIN free, skip this test."
2269                 return 0
2270         else
2271                 return 1
2272         fi
2273 }
2274
2275 # run for fixing bug10707, it needs a big room. test for 64bit
2276 test_9() {
2277         local filesize=$((1024 * 9 / 2)) # 4.5G
2278
2279         check_whether_skip && return 0
2280
2281         setup_quota_test || error "setup quota failed with $?"
2282         trap cleanup_quota_test EXIT
2283
2284         set_ost_qtype "ug" || error "enable ost quota failed"
2285
2286         local TESTFILE="$DIR/$tdir/$tfile-0"
2287         local BLK_LIMIT=100G #100G
2288         local FILE_LIMIT=1000000
2289
2290         echo "Set block limit $BLK_LIMIT bytes to $TSTUSR.$TSTUSR"
2291
2292         log "Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT)" \
2293                 "for user: $TSTUSR"
2294         $LFS setquota -u $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $DIR ||
2295                 error "set user quota failed"
2296
2297         log "Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT)" \
2298                 "for group: $TSTUSR"
2299         $LFS setquota -g $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $DIR ||
2300                 error "set group quota failed"
2301
2302         quota_show_check a u $TSTUSR
2303         quota_show_check a g $TSTUSR
2304
2305         echo "Create test file"
2306         $LFS setstripe $TESTFILE -c 1 -i 0 || error "setstripe $TESTFILE failed"
2307         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
2308
2309         log "Write the big file of 4.5G ..."
2310         $RUNAS $DD of=$TESTFILE count=$filesize ||
2311                 quota_error a $TSTUSR "write 4.5G file failure, expect success"
2312
2313         $SHOW_QUOTA_USER
2314         $SHOW_QUOTA_GROUP
2315
2316         cleanup_quota_test
2317
2318         $SHOW_QUOTA_USER
2319         $SHOW_QUOTA_GROUP
2320 }
2321 run_test 9 "Block limit larger than 4GB (b10707)"
2322
2323 test_10() {
2324         local TESTFILE=$DIR/$tdir/$tfile
2325
2326         setup_quota_test || error "setup quota failed with $?"
2327         trap cleanup_quota_test EXIT
2328
2329         # set limit to root user should fail
2330         $LFS setquota -u root -b 100G -B 500G -i 1K -I 1M $DIR &&
2331                 error "set limit for root user successfully, expect failure"
2332         $LFS setquota -g root -b 1T -B 10T -i 5K -I 100M $DIR &&
2333                 error "set limit for root group successfully, expect failure"
2334         $LFS setquota -p 0 -b 1T -B 10T -i 5K -I 100M $DIR &&
2335                 error "set limit for project 0 successfully, expect failure"
2336
2337         # root user can overrun quota
2338         set_ost_qtype "ug" || error "enable ost quota failed"
2339
2340         $LFS setquota -u $TSTUSR -b 0 -B 2M -i 0 -I 0 $DIR ||
2341                 error "set quota failed"
2342         quota_show_check b u $TSTUSR
2343
2344         $LFS setstripe $TESTFILE -c 1 || error "setstripe $TESTFILE failed"
2345         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
2346
2347         runas -u 0 -g 0 $DD of=$TESTFILE count=3 oflag=sync ||
2348                 error "write failure, expect success"
2349
2350         cleanup_quota_test
2351 }
2352 run_test 10 "Test quota for root user"
2353
2354 test_11() {
2355         local TESTFILE=$DIR/$tdir/$tfile
2356         setup_quota_test || error "setup quota failed with $?"
2357         trap cleanup_quota_test EXIT
2358
2359         set_mdt_qtype "ug" || error "enable mdt quota failed"
2360         $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I 1 $DIR ||
2361                 error "set quota failed"
2362
2363         touch "$TESTFILE"-0 || error "touch $TESTFILE-0 failed"
2364         touch "$TESTFILE"-1 || error "touch $TESTFILE-0 failed"
2365
2366         chown $TSTUSR.$TSTUSR "$TESTFILE"-0 || error "chown $TESTFILE-0 failed"
2367         chown $TSTUSR.$TSTUSR "$TESTFILE"-1 || error "chown $TESTFILE-1 failed"
2368
2369         $SHOW_QUOTA_USER
2370         local USED=$(getquota -u $TSTUSR global curinodes)
2371         [ $USED -ge 2 ] || error "Used inodes($USED) is less than 2"
2372
2373         cleanup_quota_test
2374 }
2375 run_test 11 "Chown/chgrp ignores quota"
2376
2377 test_12a() {
2378         [ "$OSTCOUNT" -lt "2" ] && skip "needs >= 2 OSTs"
2379
2380         local blimit=22 # MB
2381         local blk_cnt=$((blimit - 5))
2382         local TESTFILE0="$DIR/$tdir/$tfile"-0
2383         local TESTFILE1="$DIR/$tdir/$tfile"-1
2384
2385         setup_quota_test || error "setup quota failed with $?"
2386         trap cleanup_quota_test EXIT
2387
2388         set_ost_qtype "u" || error "enable ost quota failed"
2389         quota_show_check b u $TSTUSR
2390
2391         $LFS setquota -u $TSTUSR -b 0 -B ${blimit}M -i 0 -I 0 $DIR ||
2392                 error "set quota failed"
2393
2394         $LFS setstripe $TESTFILE0 -c 1 -i 0 || error "setstripe $TESTFILE0 failed"
2395         $LFS setstripe $TESTFILE1 -c 1 -i 1 || error "setstripe $TESTFILE1 failed"
2396         chown $TSTUSR.$TSTUSR $TESTFILE0 || error "chown $TESTFILE0 failed"
2397         chown $TSTUSR.$TSTUSR $TESTFILE1 || error "chown $TESTFILE1 failed"
2398
2399         echo "Write to ost0..."
2400         $RUNAS $DD of=$TESTFILE0 count=$blk_cnt oflag=sync ||
2401                 quota_error a $TSTUSR "dd failed"
2402
2403         echo "Write to ost1..."
2404         $RUNAS $DD of=$TESTFILE1 count=$blk_cnt oflag=sync &&
2405                 quota_error a $TSTUSR "dd succeed, expect EDQUOT"
2406
2407         echo "Free space from ost0..."
2408         rm -f $TESTFILE0
2409         wait_delete_completed
2410         sync_all_data || true
2411
2412         echo "Write to ost1 after space freed from ost0..."
2413         $RUNAS $DD of=$TESTFILE1 count=$blk_cnt oflag=sync ||
2414                 quota_error a $TSTUSR "rebalancing failed"
2415
2416         cleanup_quota_test
2417 }
2418 run_test 12a "Block quota rebalancing"
2419
2420 test_12b() {
2421         [ "$MDSCOUNT" -lt "2" ] && skip "needs >= 2 MDTs"
2422
2423         local ilimit=$((1024 * 2)) # inodes
2424         local TESTFILE0=$DIR/$tdir/$tfile
2425         local TESTFILE1=$DIR/${tdir}-1/$tfile
2426
2427         setup_quota_test || error "setup quota failed with $?"
2428         trap cleanup_quota_test EXIT
2429
2430         $LFS mkdir -i 1 $DIR/${tdir}-1 || error "create remote dir failed"
2431         chmod 0777 $DIR/${tdir}-1
2432
2433         set_mdt_qtype "u" || error "enable mdt quota failed"
2434         quota_show_check f u $TSTUSR
2435
2436         $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I $ilimit $DIR ||
2437                 error "set quota failed"
2438
2439         echo "Create $ilimit files on mdt0..."
2440         $RUNAS createmany -m $TESTFILE0 $ilimit ||
2441                 quota_error u $TSTUSR "create failed, but expect success"
2442
2443         echo "Create files on mdt1..."
2444         $RUNAS createmany -m $TESTFILE1 1 &&
2445                 quota_error a $TSTUSR "create succeeded, expect EDQUOT"
2446
2447         echo "Free space from mdt0..."
2448         $RUNAS unlinkmany $TESTFILE0 $ilimit || error "unlink mdt0 files failed"
2449         wait_delete_completed
2450         sync_all_data || true
2451
2452         echo "Create files on mdt1 after space freed from mdt0..."
2453         $RUNAS createmany -m $TESTFILE1 $((ilimit / 2)) ||
2454                 quota_error a $TSTUSR "rebalancing failed"
2455
2456         $RUNAS unlinkmany $TESTFILE1 $((ilimit / 2)) ||
2457                 error "unlink mdt1 files failed"
2458         rmdir $DIR/${tdir}-1 || error "unlink remote dir failed"
2459
2460         cleanup_quota_test
2461 }
2462 run_test 12b "Inode quota rebalancing"
2463
2464 test_13(){
2465         local TESTFILE=$DIR/$tdir/$tfile
2466         # the name of lwp on ost1 name is MDT0000-lwp-OST0000
2467         local procf="ldlm.namespaces.*MDT0000-lwp-OST0000.lru_size"
2468
2469         setup_quota_test || error "setup quota failed with $?"
2470         trap cleanup_quota_test EXIT
2471
2472         set_ost_qtype "u" || error "enable ost quota failed"
2473         quota_show_check b u $TSTUSR
2474
2475         $LFS setquota -u $TSTUSR -b 0 -B 10M -i 0 -I 0 $DIR ||
2476                 error "set quota failed"
2477         $LFS setstripe $TESTFILE -c 1 -i 0 || error "setstripe $TESTFILE failed"
2478         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
2479
2480         # clear the locks in cache first
2481         do_facet ost1 $LCTL set_param -n $procf=clear
2482         local nlock=$(do_facet ost1 $LCTL get_param -n $procf)
2483         [ $nlock -eq 0 ] || error "$nlock cached locks"
2484
2485         # write to acquire the per-ID lock
2486         $RUNAS $DD of=$TESTFILE count=1 oflag=sync ||
2487                 quota_error a $TSTUSR "dd failed"
2488
2489         nlock=$(do_facet ost1 $LCTL get_param -n $procf)
2490         [ $nlock -eq 1 ] || error "lock count($nlock) isn't 1"
2491
2492         # clear quota doesn't trigger per-ID lock cancellation
2493         resetquota -u $TSTUSR
2494         nlock=$(do_facet ost1 $LCTL get_param -n $procf)
2495         [ $nlock -eq 1 ] || error "per-ID lock is lost on quota clear"
2496
2497         # clear the per-ID lock
2498         do_facet ost1 $LCTL set_param -n $procf=clear
2499         nlock=$(do_facet ost1 $LCTL get_param -n $procf)
2500         [ $nlock -eq 0 ] || error "per-ID lock isn't cleared"
2501
2502         # spare quota should be released
2503         local OSTUUID=$(ostuuid_from_index 0)
2504         local limit=$(getquota -u $TSTUSR $OSTUUID bhardlimit)
2505         local space=$(getquota -u $TSTUSR $OSTUUID curspace)
2506         [ $limit -le $space ] ||
2507                 error "spare quota isn't released, limit:$limit, space:$space"
2508
2509         cleanup_quota_test
2510 }
2511 run_test 13 "Cancel per-ID lock in the LRU list"
2512
2513 test_15(){
2514         local LIMIT=$((24 * 1024 * 1024 * 1024 * 1024)) # 24 TB
2515
2516         wait_delete_completed
2517         sync_all_data || true
2518
2519         # test for user
2520         $LFS setquota -u $TSTUSR -b 0 -B $LIMIT -i 0 -I 0 $DIR ||
2521                 error "set user quota failed"
2522         local TOTAL_LIMIT=$(getquota -u $TSTUSR global bhardlimit)
2523         [ $TOTAL_LIMIT -eq $LIMIT ] ||
2524                 error "(user) limit:$TOTAL_LIMIT, expect:$LIMIT, failed!"
2525         resetquota -u $TSTUSR
2526
2527         # test for group
2528         $LFS setquota -g $TSTUSR -b 0 -B $LIMIT -i 0 -I 0 $DIR ||
2529                 error "set group quota failed"
2530         TOTAL_LIMIT=$(getquota -g $TSTUSR global bhardlimit)
2531         [ $TOTAL_LIMIT -eq $LIMIT ] ||
2532                 error "(group) limits:$TOTAL_LIMIT, expect:$LIMIT, failed!"
2533         resetquota -g $TSTUSR
2534 }
2535 run_test 15 "Set over 4T block quota"
2536
2537 test_17sub() {
2538         local err_code=$1
2539         local BLKS=1    # 1M less than limit
2540         local TESTFILE=$DIR/$tdir/$tfile
2541
2542         setup_quota_test || error "setup quota failed with $?"
2543         trap cleanup_quota_test EXIT
2544
2545         # make sure the system is clean
2546         local USED=$(getquota -u $TSTUSR global curspace)
2547         [ $USED -ne 0 ] && error "Used space($USED) for user $TSTUSR isn't 0."
2548
2549         set_ost_qtype "ug" || error "enable ost quota failed"
2550         # make sure no granted quota on ost
2551         resetquota -u $TSTUSR
2552         $LFS setquota -u $TSTUSR -b 0 -B 10M -i 0 -I 0 $DIR ||
2553                 error "set quota failed"
2554
2555         quota_show_check b u $TSTUSR
2556
2557         #define OBD_FAIL_QUOTA_RECOVERABLE_ERR 0xa04
2558         lustre_fail mds 0xa04 $err_code
2559
2560         # write in background
2561         $RUNAS $DD of=$TESTFILE count=$BLKS oflag=direct &
2562         local DDPID=$!
2563
2564         sleep 2
2565         # write should be blocked and never finished
2566         if ! ps -p $DDPID  > /dev/null 2>&1; then
2567                 lustre_fail mds 0 0
2568                 quota_error u $TSTUSR "write finished incorrectly!"
2569         fi
2570
2571         lustre_fail mds 0 0
2572
2573         local count=0
2574         local timeout=30
2575         while [ true ]; do
2576                 if ! ps -p ${DDPID} > /dev/null 2>&1; then break; fi
2577                 count=$((count+1))
2578                 if [ $count -gt $timeout ]; then
2579                         quota_error u $TSTUSR "dd is not finished!"
2580                 fi
2581                 sleep 1
2582         done
2583
2584         sync; sync_all_data || true
2585
2586         USED=$(getquota -u $TSTUSR global curspace)
2587         [ $USED -ge $((BLKS * 1024)) ] || quota_error u $TSTUSR \
2588                 "Used space(${USED}K) is less than ${BLKS}M"
2589
2590         cleanup_quota_test
2591 }
2592
2593 # DQACQ return recoverable error
2594 test_17() {
2595         echo "DQACQ return -ENOLCK"
2596         #define ENOLCK  37
2597         test_17sub 37 || error "Handle -ENOLCK failed"
2598
2599         echo "DQACQ return -EAGAIN"
2600         #define EAGAIN  11
2601         test_17sub 11 || error "Handle -EAGAIN failed"
2602
2603         echo "DQACQ return -ETIMEDOUT"
2604         #define ETIMEDOUT 110
2605         test_17sub 110 || error "Handle -ETIMEDOUT failed"
2606
2607         echo "DQACQ return -ENOTCONN"
2608         #define ENOTCONN 107
2609         test_17sub 107 || error "Handle -ENOTCONN failed"
2610 }
2611
2612 run_test 17 "DQACQ return recoverable error"
2613
2614 test_18_sub () {
2615         local io_type=$1
2616         local blimit=200 # MB
2617         local TESTFILE="$DIR/$tdir/$tfile"
2618
2619         setup_quota_test || error "setup quota failed with $?"
2620         trap cleanup_quota_test EXIT
2621
2622         set_ost_qtype "u" || error "enable ost quota failed"
2623         log "User quota (limit: $blimit)"
2624         $LFS setquota -u $TSTUSR -b 0 -B ${blimit}M -i 0 -I 0 $MOUNT ||
2625                 error "set quota failed"
2626         quota_show_check b u $TSTUSR
2627
2628         $LFS setstripe $TESTFILE -i 0 -c 1 || error "setstripe $TESTFILE failed"
2629         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
2630
2631         local timeout=$(sysctl -n lustre.timeout)
2632
2633         if [ $io_type = "directio" ]; then
2634                 log "Write 100M (directio) ..."
2635                 $RUNAS $DD of=$TESTFILE count=100 oflag=direct &
2636         else
2637                 log "Write 100M (buffered) ..."
2638                 $RUNAS $DD of=$TESTFILE count=100 &
2639         fi
2640         local DDPID=$!
2641
2642         replay_barrier $SINGLEMDS
2643         log "Fail mds for $((2 * timeout)) seconds"
2644         fail $SINGLEMDS $((2 * timeout))
2645
2646         local count=0
2647         if at_is_enabled; then
2648                 timeout=$(at_max_get mds)
2649         else
2650                 timeout=$(lctl get_param -n timeout)
2651         fi
2652
2653         while [ true ]; do
2654                 if ! ps -p ${DDPID} > /dev/null 2>&1; then break; fi
2655                 if [ $((++count % (2 * timeout) )) -eq 0 ]; then
2656                         log "it took $count second"
2657                 fi
2658                 sleep 1
2659         done
2660
2661         log "(dd_pid=$DDPID, time=$count, timeout=$timeout)"
2662         sync
2663         cancel_lru_locks mdc
2664         cancel_lru_locks osc
2665         $SHOW_QUOTA_USER
2666
2667         local testfile_size=$(stat -c %s $TESTFILE)
2668         if [ $testfile_size -ne $((BLK_SZ * 1024 * 100)) ] ; then
2669                 quota_error u $TSTUSR "expect $((BLK_SZ * 1024 * 100))," \
2670                         "got ${testfile_size}. Verifying file failed!"
2671         fi
2672         cleanup_quota_test
2673 }
2674
2675 # test when mds does failover, the ost still could work well
2676 # this test shouldn't trigger watchdog b=14840
2677 test_18() {
2678         # Clear dmesg so watchdog is not triggered by previous
2679         # test output
2680         do_facet ost1 dmesg -c > /dev/null
2681
2682         test_18_sub normal
2683         test_18_sub directio
2684
2685         # check if watchdog is triggered
2686         do_facet ost1 dmesg > $TMP/lustre-log-${TESTNAME}.log
2687         local watchdog=$(awk '/[Ss]ervice thread pid/ && /was inactive/ \
2688                         { print; }' $TMP/lustre-log-${TESTNAME}.log)
2689         [ -z "$watchdog" ] || error "$watchdog"
2690         rm -f $TMP/lustre-log-${TESTNAME}.log
2691 }
2692 run_test 18 "MDS failover while writing, no watchdog triggered (b14840)"
2693
2694 test_19() {
2695         local blimit=5 # MB
2696         local TESTFILE=$DIR/$tdir/$tfile
2697
2698         setup_quota_test || error "setup quota failed with $?"
2699         trap cleanup_quota_test EXIT
2700
2701         set_ost_qtype $QTYPE || error "enable ost quota failed"
2702
2703         # bind file to a single OST
2704         $LFS setstripe -c 1 $TESTFILE || error "setstripe $TESTFILE failed"
2705         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
2706
2707         echo "Set user quota (limit: ${blimit}M)"
2708         $LFS setquota -u $TSTUSR -b 0 -B ${blimit}M -i 0 -I 0 $MOUNT ||
2709                 error "set user quota failed"
2710         quota_show_check b u $TSTUSR
2711         echo "Update quota limits"
2712         $LFS setquota -u $TSTUSR -b 0 -B ${blimit}M -i 0 -I 0 $MOUNT ||
2713                 error "set group quota failed"
2714         quota_show_check b u $TSTUSR
2715
2716         # first wirte might be cached
2717         $RUNAS $DD of=$TESTFILE count=$((blimit + 1))
2718         cancel_lru_locks osc
2719         $SHOW_QUOTA_USER
2720         $RUNAS $DD of=$TESTFILE count=$((blimit + 1)) seek=$((blimit + 1)) &&
2721                 quota_error u $TSTUSR "Write success, expect failure"
2722         $SHOW_QUOTA_USER
2723
2724         cleanup_quota_test
2725 }
2726 run_test 19 "Updating admin limits doesn't zero operational limits(b14790)"
2727
2728 test_20() { # b15754
2729         local LSTR=(2g 1t 4k 3m) # limits strings
2730         # limits values
2731         local LVAL=($((2*1024*1024)) $((1*1024*1024*1024)) $((4*1024)) \
2732                     $((3*1024*1024)))
2733
2734         resetquota -u $TSTUSR
2735
2736         $LFS setquota -u $TSTUSR --block-softlimit ${LSTR[0]} \
2737                 $MOUNT || error "could not set quota limits"
2738         $LFS setquota -u $TSTUSR --block-hardlimit ${LSTR[1]} \
2739                                 --inode-softlimit ${LSTR[2]} \
2740                                 --inode-hardlimit ${LSTR[3]} \
2741                                 $MOUNT || error "could not set quota limits"
2742
2743         [ "$(getquota -u $TSTUSR global bsoftlimit)" = "${LVAL[0]}" ] ||
2744                 error "bsoftlimit was not set properly"
2745         [ "$(getquota -u $TSTUSR global bhardlimit)" = "${LVAL[1]}" ] ||
2746                 error "bhardlimit was not set properly"
2747         [ "$(getquota -u $TSTUSR global isoftlimit)" = "${LVAL[2]}" ] ||
2748                 error "isoftlimit was not set properly"
2749         [ "$(getquota -u $TSTUSR global ihardlimit)" = "${LVAL[3]}" ] ||
2750                 error "ihardlimit was not set properly"
2751
2752         resetquota -u $TSTUSR
2753 }
2754 run_test 20 "Test if setquota specifiers work properly (b15754)"
2755
2756 test_21_sub() {
2757         local testfile=$1
2758         local blk_number=$2
2759         local seconds=$3
2760
2761         local time=$(($(date +%s) + seconds))
2762         while [ $(date +%s) -lt $time ]; do
2763                 $RUNAS $DD of=$testfile count=$blk_number > /dev/null 2>&1
2764         done
2765 }
2766
2767 # run for fixing bug16053, setquota shouldn't fail when writing and
2768 # deleting are happening
2769 test_21() {
2770         local TESTFILE="$DIR/$tdir/$tfile"
2771         local BLIMIT=10 # 10G
2772         local ILIMIT=1000000
2773
2774         setup_quota_test || error "setup quota failed with $?"
2775         trap cleanup_quota_test EXIT
2776
2777         set_ost_qtype $QTYPE || error "Enable ost quota failed"
2778
2779         log "Set limit(block:${BLIMIT}G; file:$ILIMIT) for user: $TSTUSR"
2780         $LFS setquota -u $TSTUSR -b 0 -B ${BLIMIT}G -i 0 -I $ILIMIT $MOUNT ||
2781                 error "set user quota failed"
2782         log "Set limit(block:${BLIMIT}G; file:$ILIMIT) for group: $TSTUSR"
2783         $LFS setquota -g $TSTUSR -b 0 -B $BLIMIT -i 0 -I $ILIMIT $MOUNT ||
2784                 error "set group quota failed"
2785         if is_project_quota_supported; then
2786                 log "Set limit(block:${BLIMIT}G; file:$LIMIT) for " \
2787                         "project: $TSTPRJID"
2788                 $LFS setquota -p $TSTPRJID -b 0 -B $BLIMIT -i 0 -I $ILIMIT \
2789                          $MOUNT || error "set project quota failed"
2790         fi
2791
2792         # repeat writing on a 1M file
2793         test_21_sub ${TESTFILE}_1 1 30 &
2794         local DDPID1=$!
2795         # repeat writing on a 128M file
2796         test_21_sub ${TESTFILE}_2 128 30 &
2797         local DDPID2=$!
2798
2799         local time=$(($(date +%s) + 30))
2800         local i=1
2801         while [ $(date +%s) -lt $time ]; do
2802                 log "Set quota for $i times"
2803                 $LFS setquota -u $TSTUSR -b 0 -B "$((BLIMIT + i))G" -i 0 \
2804                         -I $((ILIMIT + i)) $MOUNT ||
2805                                 error "Set user quota failed"
2806                 $LFS setquota -g $TSTUSR -b 0 -B "$((BLIMIT + i))G" -i 0 \
2807                         -I $((ILIMIT + i)) $MOUNT ||
2808                                 error "Set group quota failed"
2809                 if is_project_quota_supported; then
2810                         $LFS setquota -p $TSTPRJID -b 0 -B \
2811                         "$((BLIMIT + i))G"  -i 0 -I $((ILIMIT + i)) $MOUNT ||
2812                                 error "Set project quota failed"
2813                 fi
2814                 i=$((i+1))
2815                 sleep 1
2816         done
2817
2818         local count=0
2819         while [ true ]; do
2820                 if ! ps -p ${DDPID1} > /dev/null 2>&1; then break; fi
2821                 count=$((count+1))
2822                 if [ $count -gt 60 ]; then
2823                         quota_error a $TSTUSR "dd should be finished!"
2824                 fi
2825                 sleep 1
2826         done
2827         echo "(dd_pid=$DDPID1, time=$count)successful"
2828
2829         count=0
2830         while [ true ]; do
2831                 if ! ps -p ${DDPID2} > /dev/null 2>&1; then break; fi
2832                 count=$((count+1))
2833                 if [ $count -gt 60 ]; then
2834                         quota_error a $TSTUSR "dd should be finished!"
2835                 fi
2836                 sleep 1
2837         done
2838         echo "(dd_pid=$DDPID2, time=$count)successful"
2839
2840         cleanup_quota_test
2841 }
2842 run_test 21 "Setquota while writing & deleting (b16053)"
2843
2844 # enable/disable quota enforcement permanently
2845 test_22() {
2846         echo "Set both mdt & ost quota type as ug"
2847         local qtype="ug"
2848         is_project_quota_supported && qtype=$QTYPE
2849         set_mdt_qtype $qtype || error "enable mdt quota failed"
2850         set_ost_qtype $qtype || error "enable ost quota failed"
2851
2852         echo "Restart..."
2853         stopall || error "failed to stopall (1)"
2854         mount
2855         setupall
2856
2857         echo "Verify if quota is enabled"
2858         local qtype1=$(mdt_quota_type)
2859         [ $qtype1 != $qtype ] && error "mdt quota setting is lost"
2860         qtype=$(ost_quota_type)
2861         [ $qtype1 != $qtype ] && error "ost quota setting is lost"
2862
2863         echo "Set both mdt & ost quota type as none"
2864         set_mdt_qtype "none" || error "disable mdt quota failed"
2865         set_ost_qtype "none" || error "disable ost quota failed"
2866
2867         echo "Restart..."
2868         stopall || error "failed to stopall (2)"
2869         mount
2870         setupall
2871         quota_init
2872
2873         echo "Verify if quota is disabled"
2874         qtype=$(mdt_quota_type)
2875         [ $qtype != "none" ] && error "mdt quota setting is lost"
2876         qtype=$(ost_quota_type)
2877         [ $qtype != "none" ] && error "ost quota setting is lost"
2878
2879         return 0
2880 }
2881 run_test 22 "enable/disable quota by 'lctl conf_param/set_param -P'"
2882
2883 test_23_sub() {
2884         local TESTFILE="$DIR/$tdir/$tfile"
2885         local LIMIT=$1
2886
2887         setup_quota_test || error "setup quota failed with $?"
2888         trap cleanup_quota_test EXIT
2889
2890         set_ost_qtype $QTYPE || error "Enable ost quota failed"
2891
2892         # test for user
2893         log "User quota (limit: $LIMIT MB)"
2894         $LFS setquota -u $TSTUSR -b 0 -B "$LIMIT"M -i 0 -I 0 $DIR ||
2895                 error "set quota failed"
2896         quota_show_check b u $TSTUSR
2897
2898         $LFS setstripe $TESTFILE -c 1 -i 0 || error "setstripe $TESTFILE failed"
2899         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
2900
2901         log "Step1: trigger EDQUOT with O_DIRECT"
2902         log "Write half of file"
2903         $RUNAS $DD of=$TESTFILE count=$((LIMIT/2)) oflag=direct ||
2904                 quota_error u $TSTUSR "(1) Write failure, expect success." \
2905                         "limit=$LIMIT"
2906         log "Write out of block quota ..."
2907         $RUNAS $DD of=$TESTFILE count=$((LIMIT/2 + 1)) seek=$((LIMIT/2)) \
2908                 oflag=direct conv=notrunc &&
2909                 quota_error u $TSTUSR "(2) Write success, expect EDQUOT." \
2910                         "limit=$LIMIT"
2911         log "Step1: done"
2912
2913         log "Step2: rewrite should succeed"
2914         $RUNAS $DD of=$TESTFILE count=1 oflag=direct conv=notrunc||
2915                 quota_error u $TSTUSR "(3) Write failure, expect success." \
2916                         "limit=$LIMIT"
2917         log "Step2: done"
2918
2919         cleanup_quota_test
2920
2921         local OST0_UUID=$(ostuuid_from_index 0)
2922         local OST0_QUOTA_USED=$(getquota -u $TSTUSR $OST0_UUID curspace)
2923         [ $OST0_QUOTA_USED -ne 0 ] &&
2924                 ($SHOW_QUOTA_USER; \
2925                 quota_error u $TSTUSR "quota isn't released")
2926         $SHOW_QUOTA_USER
2927 }
2928
2929 test_23() {
2930         [ "$ost1_FSTYPE" == zfs ] &&
2931                 skip "Overwrite in place is not guaranteed to be " \
2932                 "space neutral on ZFS"
2933
2934         local OST0_MIN=$((6 * 1024)) # 6MB, extra space for meta blocks.
2935         check_whether_skip && return 0
2936         log "run for 4MB test file"
2937         test_23_sub 4
2938
2939         OST0_MIN=$((60 * 1024)) # 60MB, extra space for meta blocks.
2940         check_whether_skip && return 0
2941         log "run for 40MB test file"
2942         test_23_sub 40
2943 }
2944 run_test 23 "Quota should be honored with directIO (b16125)"
2945
2946 test_24() {
2947         local blimit=5 # MB
2948         local TESTFILE="$DIR/$tdir/$tfile"
2949
2950         setup_quota_test || error "setup quota failed with $?"
2951         trap cleanup_quota_test EXIT
2952
2953         set_ost_qtype $QTYPE || error "enable ost quota failed"
2954
2955         # bind file to a single OST
2956         $LFS setstripe -c 1 $TESTFILE || error "setstripe $TESTFILE failed"
2957         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
2958
2959         echo "Set user quota (limit: ${blimit}M)"
2960         $LFS setquota -u $TSTUSR -b 0 -B "$blimit"M -i 0 -I 0 $MOUNT ||
2961                 error "set quota failed"
2962
2963         # overrun quota by root user
2964         runas -u 0 -g 0 $DD of=$TESTFILE count=$((blimit + 1)) ||
2965                 error "write failure, expect success"
2966         cancel_lru_locks osc
2967         sync_all_data || true
2968
2969         $SHOW_QUOTA_USER | grep '*' || error "no matching *"
2970
2971         cleanup_quota_test
2972 }
2973 run_test 24 "lfs draws an asterix when limit is reached (b16646)"
2974
2975 test_27a() { # b19612
2976         $LFS quota $TSTUSR $DIR &&
2977                 error "lfs succeeded with no type, but should have failed"
2978         $LFS setquota $TSTUSR $DIR &&
2979                 error "lfs succeeded with no type, but should have failed"
2980         return 0
2981 }
2982 run_test 27a "lfs quota/setquota should handle wrong arguments (b19612)"
2983
2984 test_27b() { # b20200
2985         $LFS setquota -u $TSTID -b 1000 -B 1000 -i 1000 -I 1000 $DIR ||
2986                 error "lfs setquota failed with uid argument"
2987         $LFS setquota -g $TSTID -b 1000 -B 1000 -i 1000 -I 1000 $DIR ||
2988                 error "lfs stequota failed with gid argument"
2989         if is_project_quota_supported; then
2990                 $LFS setquota -p $TSTPRJID -b 1000 -B 1000 -i 1000 -I \
2991                         1000 $DIR || error \
2992                                 "lfs stequota failed with projid argument"
2993         fi
2994         $SHOW_QUOTA_USERID || error "lfs quota failed with uid argument"
2995         $SHOW_QUOTA_GROUPID || error "lfs quota failed with gid argument"
2996         if is_project_quota_supported; then
2997                 $SHOW_QUOTA_PROJID ||
2998                         error "lfs quota failed with projid argument"
2999         fi
3000         resetquota -u $TSTID
3001         resetquota -g $TSTID
3002         resetquota -p $TSTPRJID
3003         return 0
3004 }
3005 run_test 27b "lfs quota/setquota should handle user/group/project ID (b20200)"
3006
3007 test_27c() {
3008         local limit
3009
3010         $LFS setquota -u $TSTID -b 30M -B 3T $DIR ||
3011                 error "lfs setquota failed"
3012
3013         limit=$($LFS quota -u $TSTID -v -h $DIR | grep $DIR | awk '{print $3}')
3014         [ $limit != "30M" ] && error "softlimit $limit isn't human-readable"
3015         limit=$($LFS quota -u $TSTID -v -h $DIR | grep $DIR | awk '{print $4}')
3016         [ $limit != "3T" ] && error "hardlimit $limit isn't human-readable"
3017
3018         $LFS setquota -u $TSTID -b 1500M -B 18500G $DIR ||
3019                 error "lfs setquota for $TSTID failed"
3020
3021         limit=$($LFS quota -u $TSTID -v -h $DIR | grep $DIR | awk '{print $3}')
3022         [ $limit != "1.465G" ] && error "wrong softlimit $limit"
3023         limit=$($LFS quota -u $TSTID -v -h $DIR | grep $DIR | awk '{print $4}')
3024         [ $limit != "18.07T" ] && error "wrong hardlimit $limit"
3025
3026         $LFS quota -u $TSTID -v -h $DIR | grep -q "Total allocated" ||
3027                 error "total allocated inode/block limit not printed"
3028
3029         resetquota -u $TSTUSR
3030 }
3031 run_test 27c "lfs quota should support human-readable output"
3032
3033 test_27d() {
3034         local softlimit=1.5
3035         local hardlimit=2.3
3036         local limit
3037
3038         $LFS setquota -u $TSTID -b ${softlimit}p -B ${hardlimit}P $DIR ||
3039                 error "set fraction block limit failed"
3040         limit=$($LFS quota -u $TSTID -h $DIR | grep $DIR | awk '{print $3}')
3041         [ $limit == ${softlimit}P ] || error "get fraction softlimit failed"
3042         limit=$($LFS quota -u $TSTID -h $DIR | grep $DIR | awk '{print $4}')
3043         [ $limit == ${hardlimit}P ] || error "get fraction hardlimit failed"
3044
3045         resetquota -u $TSTUSR
3046 }
3047 run_test 27d "lfs setquota should support fraction block limit"
3048
3049 test_30() {
3050         local LIMIT=4 # MB
3051         local TESTFILE="$DIR/$tdir/$tfile"
3052         local GRACE=10
3053
3054         setup_quota_test || error "setup quota failed with $?"
3055         trap cleanup_quota_test EXIT
3056
3057         set_ost_qtype "u" || error "enable ost quota failed"
3058
3059         $LFS setstripe $TESTFILE -i 0 -c 1 || error "setstripe $TESTFILE failed"
3060         chown $TSTUSR.$TSTUSR $TESTFILE || error "chown $TESTFILE failed"
3061
3062         $LFS setquota -t -u --block-grace $GRACE --inode-grace \
3063                 $MAX_IQ_TIME $DIR || error "set grace time failed"
3064         $LFS setquota -u $TSTUSR -b ${LIMIT}M -B 0 -i 0 -I 0 $DIR ||
3065                 error "set quota failed"
3066         $RUNAS $DD of=$TESTFILE count=$((LIMIT * 2)) || true
3067         cancel_lru_locks osc
3068         sleep $GRACE
3069         $LFS setquota -u $TSTUSR -B 0 $DIR || error "clear quota failed"
3070         # over-quota flag has not yet settled since we do not trigger async
3071         # events based on grace time period expiration
3072         $SHOW_QUOTA_USER
3073         $RUNAS $DD of=$TESTFILE conv=notrunc oflag=append count=4 || true
3074         cancel_lru_locks osc
3075         # now over-quota flag should be settled and further writes should fail
3076         $SHOW_QUOTA_USER
3077         $RUNAS $DD of=$TESTFILE conv=notrunc oflag=append count=4 &&
3078                 error "grace times were reset"
3079         # cleanup
3080         cleanup_quota_test
3081         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace \
3082                 $MAX_IQ_TIME $DIR || error "restore grace time failed"
3083 }
3084 run_test 30 "Hard limit updates should not reset grace times"
3085
3086 # basic usage tracking for user & group
3087 test_33() {
3088         local INODES=10 # files
3089         local BLK_CNT=2 # MB each
3090         local TOTAL_BLKS=$((INODES * BLK_CNT * 1024))
3091
3092         setup_quota_test || error "setup quota failed with $?"
3093         trap cleanup_quota_test EXIT
3094
3095         # make sure the system is clean
3096         local USED=$(getquota -u $TSTID global curspace)
3097         [ $USED -ne 0 ] &&
3098                 error "Used space ($USED) for user $TSTID isn't 0."
3099         USED=$(getquota -g $TSTID global curspace)
3100         [ $USED -ne 0 ] &&
3101                 error "Used space ($USED) for group $TSTID isn't 0."
3102         if is_project_quota_supported; then
3103                 USED=$(getquota -p $TSTPRJID global curspace)
3104                 [ $USED -ne 0 ] && error \
3105                         "Used space ($USED) for project $TSTPRJID isn't 0."
3106         fi
3107
3108         echo "Write files..."
3109         for i in $(seq 0 $INODES); do
3110                 $RUNAS $DD of=$DIR/$tdir/$tfile-$i count=$BLK_CNT 2>/dev/null ||
3111                         error "write failed"
3112                         is_project_quota_supported &&
3113                                 change_project -p $TSTPRJID $DIR/$tdir/$tfile-$i
3114                 echo "Iteration $i/$INODES completed"
3115         done
3116         cancel_lru_locks osc
3117
3118         echo "Wait for setattr on objects finished..."
3119         wait_delete_completed
3120
3121         sync; sync_all_data || true
3122
3123         echo "Verify disk usage after write"
3124         USED=$(getquota -u $TSTID global curspace)
3125         [ $USED -lt $TOTAL_BLKS ] &&
3126                 error "Used space for user $TSTID:$USED, expected:$TOTAL_BLKS"
3127         USED=$(getquota -g $TSTID global curspace)
3128         [ $USED -lt $TOTAL_BLKS ] &&
3129                 error "Used space for group $TSTID:$USED, expected:$TOTAL_BLKS"
3130         if is_project_quota_supported; then
3131                 USED=$(getquota -p $TSTPRJID global curspace)
3132                 [ $USED -lt $TOTAL_BLKS ] && error \
3133                         "Used space for project $TSTPRJID:$USED, expected:$TOTAL_BLKS"
3134         fi
3135
3136         echo "Verify inode usage after write"
3137         USED=$(getquota -u $TSTID global curinodes)
3138         [ $USED -lt $INODES ] &&
3139                 error "Used inode for user $TSTID is $USED, expected $INODES"
3140         USED=$(getquota -g $TSTID global curinodes)
3141         [ $USED -lt $INODES ] &&
3142                 error "Used inode for group $TSTID is $USED, expected $INODES"
3143         if is_project_quota_supported; then
3144                 USED=$(getquota -p $TSTPRJID global curinodes)
3145                 [ $USED -lt $INODES ] && error \
3146                         "Used inode for project $TSTPRJID is $USED, expected $INODES"
3147         fi
3148
3149         cleanup_quota_test
3150
3151         echo "Verify disk usage after delete"
3152         USED=$(getquota -u $TSTID global curspace)
3153         [ $USED -eq 0 ] || error "Used space for user $TSTID isn't 0. $USED"
3154         USED=$(getquota -u $TSTID global curinodes)
3155         [ $USED -eq 0 ] || error "Used inodes for user $TSTID isn't 0. $USED"
3156         USED=$(getquota -g $TSTID global curspace)
3157         [ $USED -eq 0 ] || error "Used space for group $TSTID isn't 0. $USED"
3158         USED=$(getquota -g $TSTID global curinodes)
3159         [ $USED -eq 0 ] || error "Used inodes for group $TSTID isn't 0. $USED"
3160         if is_project_quota_supported; then
3161                 USED=$(getquota -p $TSTPRJID global curspace)
3162                 [ $USED -eq 0 ] ||
3163                         error "Used space for project $TSTPRJID isn't 0. $USED"
3164                 USED=$(getquota -p $TSTPRJID global curinodes)
3165                 [ $USED -eq 0 ] ||
3166                         error "Used inodes for project $TSTPRJID isn't 0. $USED"
3167         fi
3168 }
3169 run_test 33 "Basic usage tracking for user & group & project"
3170
3171 # usage transfer test for user & group & project
3172 test_34() {
3173         local BLK_CNT=2 # MB
3174         local project_supported="no"
3175
3176         is_project_quota_supported && project_supported="yes"
3177         setup_quota_test || error "setup quota failed with $?"
3178         trap cleanup_quota_test EXIT
3179
3180         # make sure the system is clean
3181         local USED=$(getquota -u $TSTID global curspace)
3182         [ $USED -ne 0 ] && error "Used space ($USED) for user $TSTID isn't 0."
3183         USED=$(getquota -g $TSTID global curspace)
3184         [ $USED -ne 0 ] && error "Used space ($USED) for group $TSTID isn't 0."
3185
3186         local USED=$(getquota -u $TSTID2 global curspace)
3187         [ $USED -ne 0 ] && error "Used space ($USED) for user $TSTID2 isn't 0."
3188         if [ $project_supported == "yes" ]; then
3189                 USED=$(getquota -p $TSTPRJID global curspace)
3190                 [ $USED -ne 0 ] && error \
3191                         "Used space ($USED) for Project $TSTPRJID isn't 0."
3192         fi
3193
3194         echo "Write file..."
3195         $DD of=$DIR/$tdir/$tfile count=$BLK_CNT 2>/dev/null ||
3196                 error "write failed"
3197         cancel_lru_locks osc
3198         sync; sync_all_data || true
3199
3200         echo "chown the file to user $TSTID"
3201         chown $TSTID $DIR/$tdir/$tfile || error "chown failed"
3202
3203         echo "Wait for setattr on objects finished..."
3204         wait_delete_completed
3205
3206         BLK_CNT=$((BLK_CNT * 1024))
3207
3208         echo "Verify disk usage for user $TSTID"
3209         USED=$(getquota -u $TSTID global curspace)
3210         [ $USED -lt $BLK_CNT ] &&
3211                 error "Used space for user $TSTID is ${USED}, expected $BLK_CNT"
3212         USED=$(getquota -u $TSTID global curinodes)
3213         [ $USED -ne 1 ] &&
3214                 error "Used inodes for user $TSTID is $USED, expected 1"
3215
3216         echo "chgrp the file to group $TSTID"
3217         chgrp $TSTID $DIR/$tdir/$tfile || error "chgrp failed"
3218
3219         echo "Wait for setattr on objects finished..."
3220         wait_delete_completed
3221
3222         echo "Verify disk usage for group $TSTID"
3223         USED=$(getquota -g $TSTID global curspace)
3224         [ $USED -ge $BLK_CNT ] ||
3225                 error "Used space for group $TSTID is $USED, expected $BLK_CNT"
3226         USED=$(getquota -g $TSTID global curinodes)
3227         [ $USED -eq 1 ] ||
3228                 error "Used inodes for group $TSTID is $USED, expected 1"
3229
3230         # chown won't change the ost object group. LU-4345 */
3231         echo "chown the file to user $TSTID2"
3232         chown $TSTID2 $DIR/$tdir/$tfile || error "chown to $TSTID2 failed"
3233
3234         echo "Wait for setattr on objects finished..."
3235         wait_delete_completed
3236
3237         echo "change_project project id to $TSTPRJID"
3238         [ $project_supported == "yes" ] &&
3239                 change_project -p $TSTPRJID $DIR/$tdir/$tfile
3240         echo "Wait for setattr on objects finished..."
3241         wait_delete_completed
3242
3243         echo "Verify disk usage for user $TSTID2/$TSTID and group $TSTID"
3244         USED=$(getquota -u $TSTID2 global curspace)
3245         [ $USED -lt $BLK_CNT ] &&
3246                 error "Used space for user $TSTID2 is $USED, expected $BLK_CNT"
3247         USED=$(getquota -u $TSTID global curspace)
3248         [ $USED -ne 0 ] &&
3249                 error "Used space for user $TSTID is $USED, expected 0"
3250         USED=$(getquota -g $TSTID global curspace)
3251         [ $USED -lt $BLK_CNT ] &&
3252                 error "Used space for group $TSTID is $USED, expected $BLK_CNT"
3253         if [ $project_supported == "yes" ]; then
3254                 USED=$(getquota -p $TSTPRJID global curspace)
3255                 [ $USED -lt $BLK_CNT ] && error \
3256                         "Used space for group $TSTPRJID is $USED, expected $BLK_CNT"
3257         fi
3258
3259         cleanup_quota_test
3260 }
3261 run_test 34 "Usage transfer for user & group & project"
3262
3263 # usage is still accessible across restart
3264 test_35() {
3265         local BLK_CNT=2 # MB
3266
3267         setup_quota_test || error "setup quota failed with $?"
3268         trap cleanup_quota_test EXIT
3269
3270         echo "Write file..."
3271         $RUNAS $DD of=$DIR/$tdir/$tfile count=$BLK_CNT 2>/dev/null ||
3272                 error "write failed"
3273         is_project_quota_supported &&
3274                 change_project -p $TSTPRJID $DIR/$tdir/$tfile
3275         cancel_lru_locks osc
3276
3277         echo "Wait for setattr on objects finished..."
3278         wait_delete_completed
3279
3280         sync; sync_all_data || true
3281
3282         echo "Save disk usage before restart"
3283         local ORIG_USR_SPACE=$(getquota -u $TSTID global curspace)
3284         [ $ORIG_USR_SPACE -eq 0 ] &&
3285                 error "Used space for user $TSTID is 0, expected ${BLK_CNT}M"
3286         local ORIG_USR_INODES=$(getquota -u $TSTID global curinodes)
3287         [ $ORIG_USR_INODES -eq 0 ] &&
3288                 error "Used inodes for user $TSTID is 0, expected 1"
3289         echo "User $TSTID: ${ORIG_USR_SPACE}KB $ORIG_USR_INODES inodes"
3290         local ORIG_GRP_SPACE=$(getquota -g $TSTID global curspace)
3291         [ $ORIG_GRP_SPACE -eq 0 ] &&
3292                 error "Used space for group $TSTID is 0, expected ${BLK_CNT}M"
3293         local ORIG_GRP_INODES=$(getquota -g $TSTID global curinodes)
3294         [ $ORIG_GRP_INODES -eq 0 ] &&
3295                 error "Used inodes for group $TSTID is 0, expected 1"
3296         echo "Group $TSTID: ${ORIG_GRP_SPACE}KB $ORIG_GRP_INODES inodes"
3297
3298         if is_project_quota_supported; then
3299                 local ORIG_PRJ_SPACE=$(getquota -p $TSTPRJID global curspace)
3300                 [ $ORIG_PRJ_SPACE -eq 0 ] && error \
3301                         "Used space for project $TSTPRJID is 0, expected ${BLK_CNT}M"
3302                 local ORIG_PRJ_INODES=$(getquota -p $TSTPRJID global curinodes)
3303                 [ $ORIG_PRJ_INODES -eq 0 ] && error \
3304                         "Used inodes for project $TSTPRJID is 0, expected 1"
3305                 echo "Project $TSTPRJID: ${ORIG_PRJ_SPACE}KB $ORIG_PRJ_INODES inodes"
3306         fi
3307
3308         log "Restart..."
3309         stopall
3310         setupall
3311         quota_init
3312
3313         echo "Verify disk usage after restart"
3314         local USED=$(getquota -u $TSTID global curspace)
3315         [ $USED -eq $ORIG_USR_SPACE ] ||
3316                 error "Used space for user $TSTID changed from " \
3317                         "$ORIG_USR_SPACE to $USED"
3318         USED=$(getquota -u $TSTID global curinodes)
3319         [ $USED -eq $ORIG_USR_INODES ] ||
3320                 error "Used inodes for user $TSTID changed from " \
3321                         "$ORIG_USR_INODES to $USED"
3322         USED=$(getquota -g $TSTID global curspace)
3323         [ $USED -eq $ORIG_GRP_SPACE ] ||
3324                 error "Used space for group $TSTID changed from " \
3325                         "$ORIG_GRP_SPACE to $USED"
3326         USED=$(getquota -g $TSTID global curinodes)
3327         [ $USED -eq $ORIG_GRP_INODES ] ||
3328                 error "Used inodes for group $TSTID changed from " \
3329                         "$ORIG_GRP_INODES to $USED"
3330         if [ $project_supported == "yes" ]; then
3331                 USED=$(getquota -p $TSTPRJID global curinodes)
3332                 [ $USED -eq $ORIG_PRJ_INODES ] ||
3333                         error "Used inodes for project $TSTPRJID " \
3334                                 "changed from $ORIG_PRJ_INODES to $USED"
3335                 USED=$(getquota -p $TSTPRJID global curspace)
3336                 [ $USED -eq $ORIG_PRJ_SPACE ] ||
3337                         error "Used space for project $TSTPRJID "\
3338                                 "changed from $ORIG_PRJ_SPACE to $USED"
3339         fi
3340
3341         # check if the vfs_dq_init() is called before writing
3342         echo "Append to the same file..."
3343         $RUNAS $DD of=$DIR/$tdir/$tfile count=$BLK_CNT seek=1 2>/dev/null ||
3344                 error "write failed"
3345         cancel_lru_locks osc
3346         sync; sync_all_data || true
3347
3348         echo "Verify space usage is increased"
3349         USED=$(getquota -u $TSTID global curspace)
3350         [ $USED -gt $ORIG_USR_SPACE ] ||
3351                 error "Used space for user $TSTID isn't increased" \
3352                         "orig:$ORIG_USR_SPACE, now:$USED"
3353         USED=$(getquota -g $TSTID global curspace)
3354         [ $USED -gt $ORIG_GRP_SPACE ] ||
3355                 error "Used space for group $TSTID isn't increased" \
3356                         "orig:$ORIG_GRP_SPACE, now:$USED"
3357         if [ $project_supported == "yes" ]; then
3358                 USED=$(getquota -p $TSTPRJID global curspace)
3359                 [ $USED -gt $ORIG_PRJ_SPACE ] ||
3360                         error "Used space for project $TSTPRJID isn't " \
3361                                 "increased orig:$ORIG_PRJ_SPACE, now:$USED"
3362         fi
3363
3364         cleanup_quota_test
3365 }
3366 run_test 35 "Usage is still accessible across reboot"
3367
3368 # chown/chgrp to the file created with MDS_OPEN_DELAY_CREATE
3369 # LU-5006
3370 test_37() {
3371         [ "$MDS1_VERSION" -lt $(version_code 2.6.93) ] &&
3372                 skip "Old server doesn't have LU-5006 fix."
3373
3374         setup_quota_test || error "setup quota failed with $?"
3375         trap cleanup_quota_test EXIT
3376
3377         # make sure the system is clean
3378         local USED=$(getquota -u $TSTID global curspace)
3379         [ $USED -ne 0 ] &&
3380                 error "Used space ($USED) for user $TSTID isn't 0."
3381
3382         # create file with MDS_OPEN_DELAY_CREATE flag
3383         $LFS setstripe -c 1 -i 0 $DIR/$tdir/$tfile ||
3384                 error "Create file failed"
3385         # write to file
3386         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 conv=notrunc \
3387                 oflag=sync || error "Write file failed"
3388         # chown to the file
3389         chown $TSTID $DIR/$tdir/$tfile || error "Chown to file failed"
3390
3391         # wait for setattr on objects finished..."
3392         wait_delete_completed
3393
3394         USED=$(getquota -u $TSTID global curspace)
3395         [ $USED -ne 0 ] || quota_error u $TSTUSR "Used space is 0"
3396
3397         cleanup_quota_test
3398 }
3399 run_test 37 "Quota accounted properly for file created by 'lfs setstripe'"
3400
3401 # LU-8801
3402 test_38() {
3403         [ "$MDS1_VERSION" -lt $(version_code 2.8.60) ] &&
3404                 skip "Old server doesn't have LU-8801 fix."
3405
3406         [ "$UID" != 0 ] && skip_env "must run as root" && return
3407
3408         setup_quota_test 0 || error "setup quota failed with $?"
3409         trap cleanup_quota_test EXIT
3410
3411         # make sure the system is clean
3412         local USED=$(getquota -u $TSTID global curspace)
3413         [ $USED -ne 0 ] &&
3414                 error "Used space ($USED) for user $TSTID isn't 0."
3415         USED=$(getquota -u $TSTID2 global curspace)
3416         [ $USED -ne 0 ] &&
3417                 error "Used space ($USED) for user $TSTID2 isn't 0."
3418
3419         local TESTFILE="$DIR/$tdir/$tfile"
3420         local file_cnt=10000
3421
3422         # Generate id entries in accounting file
3423         echo "Create $file_cnt files..."
3424         for i in `seq $file_cnt`; do
3425                 touch $TESTFILE-$i
3426                 chown $((file_cnt - i)):$((file_cnt - i)) $TESTFILE-$i ||
3427                         error "failed to chown $TESTFILE-$i"
3428         done
3429         cancel_lru_locks osc
3430         sync; sync_all_data || true
3431
3432         local procf="osd-$mds1_FSTYPE.$FSNAME-MDT0000"
3433         procf=${procf}.quota_slave.acct_user
3434         local accnt_cnt
3435
3436         acct_cnt=$(do_facet mds1 $LCTL get_param $procf | grep "id:" | \
3437                    awk '{if ($3 < 10000) {print $3}}' | wc -l)
3438         echo "Found $acct_cnt id entries"
3439
3440         [ $file_cnt -eq $acct_cnt ] || {
3441                 do_facet mds1 $LCTL get_param $procf
3442                 error "skipped id entries"
3443         }
3444
3445         cleanup_quota_test
3446 }
3447 run_test 38 "Quota accounting iterator doesn't skip id entries"
3448
3449 test_39() {
3450         local TESTFILE="$DIR/$tdir/project"
3451         ! is_project_quota_supported &&
3452                 skip "Project quota is not supported"
3453
3454         setup_quota_test || error "setup quota failed with $?"
3455
3456         touch $TESTFILE
3457         projectid=$(lfs project $TESTFILE | awk '{print $1}')
3458         [ $projectid -ne 0 ] &&
3459                 error "Project id should be 0 not $projectid"
3460         change_project -p 1024 $TESTFILE
3461         projectid=$(lfs project $TESTFILE | awk '{print $1}')
3462         [ $projectid -ne 1024 ] &&
3463                 error "Project id should be 1024 not $projectid"
3464
3465         stopall || error "failed to stopall (1)"
3466         mount
3467         setupall
3468         projectid=$(lfs project $TESTFILE | awk '{print $1}')
3469         [ $projectid -ne 1024 ] &&
3470                 error "Project id should be 1024 not $projectid"
3471
3472         cleanup_quota_test
3473 }
3474 run_test 39 "Project ID interface works correctly"
3475
3476 test_40a() {
3477         ! is_project_quota_supported &&
3478                 skip "Project quota is not supported"
3479         local dir1="$DIR/$tdir/dir1"
3480         local dir2="$DIR/$tdir/dir2"
3481
3482         setup_quota_test || error "setup quota failed with $?"
3483
3484         mkdir -p $dir1 $dir2
3485         change_project -sp 1 $dir1 && touch $dir1/1
3486         change_project -sp 2 $dir2
3487
3488         ln $dir1/1 $dir2/1_link &&
3489                 error "Hard link across different project quota should fail"
3490         rm -rf $dir1 $dir2
3491
3492         cleanup_quota_test
3493 }
3494 run_test 40a "Hard link across different project ID"
3495
3496 test_40b() {
3497         ! is_project_quota_supported &&
3498                 skip "Project quota is not supported"
3499         local dir1="$DIR/$tdir/dir1"
3500         local dir2="$DIR/$tdir/dir2"
3501
3502         setup_quota_test || error "setup quota failed with $?"
3503         mkdir -p $dir1 $dir2
3504         change_project -sp 1 $dir1 && touch $dir1/1
3505         change_project -sp 2 $dir2
3506
3507         mv $dir1/1 $dir2/2 || error "mv failed $?"
3508         local projid=$(lfs project $dir2/2 | awk '{print $1}')
3509         if [ "$projid" != "2" ]; then
3510                 error "project id expected 2 not $projid"
3511         fi
3512         rm -rf $dir1 $dir2
3513         cleanup_quota_test
3514 }
3515 run_test 40b "Mv across different project ID"
3516
3517 test_40c() {
3518         [ "$MDSCOUNT" -lt "2" ] && skip "needs >= 2 MDTs"
3519                 ! is_project_quota_supported &&
3520                         skip "Project quota is not supported"
3521
3522         setup_quota_test || error "setup quota failed with $?"
3523         local dir="$DIR/$tdir/dir"
3524
3525         mkdir -p $dir && change_project -sp 1 $dir
3526         $LFS mkdir -i 1 $dir/remote_dir || error "create remote dir failed"
3527         local projid=$(lfs project -d $dir/remote_dir | awk '{print $1}')
3528         [ "$projid" != "1" ] && error "projid id expected 1 not $projid"
3529         touch $dir/remote_dir/file
3530         #verify inherit works file for remote dir.
3531         local projid=$(lfs project -d $dir/remote_dir/file | awk '{print $1}')
3532         [ "$projid" != "1" ] &&
3533                 error "file under remote dir expected 1 not $projid"
3534
3535         #Agent inode should be ignored for project quota
3536         USED=$(getquota -p 1 global curinodes)
3537         [ "$USED" != "3" ] &&
3538                 error "file count expected 3 got $USED"
3539
3540         rm -rf $dir
3541         cleanup_quota_test
3542         return 0
3543 }
3544 run_test 40c "Remote child Dir inherit project quota properly"
3545
3546 test_40d() {
3547         [ "$MDSCOUNT" -lt "2" ] && skip_env "needs >= 2 MDTs"
3548         is_project_quota_supported || skip "Project quota is not supported"
3549
3550         setup_quota_test || error "setup quota failed with $?"
3551         local dir="$DIR/$tdir/dir"
3552
3553         mkdir -p $dir
3554         $LFS setdirstripe -D -c 2 -i -1 $dir || error "setdirstripe failed"
3555         change_project -sp $TSTPRJID $dir ||
3556                 error "change project on $dir failed"
3557         for i in $(seq 5); do
3558                 mkdir -p $dir/d$i/d$i ||
3559                         error "mkdir $dir/d$i/d$i failed"
3560                 local projid=$($LFS project -d $dir/d$i/d$i |
3561                                awk '{print $1}')
3562                 [ "$projid" == "$TSTPRJID" ] ||
3563                         error "projid id expected $TSTPRJID not $projid"
3564                 touch $dir/d$i/d$i/file
3565                 #verify inherit works file for stripe dir.
3566                 local projid=$($LFS project -d $dir/d$i/d$i/file | awk '{print $1}')
3567                 [ "$projid" == "$TSTPRJID" ] ||
3568                         error "file under remote dir expected 1 not $projid"
3569         done
3570
3571         # account should be 1 + (2 + 1) *10 + 1 * 5
3572         USED=$(getquota -p $TSTPRJID global curinodes)
3573         [ "$USED" == "36" ] ||
3574                 error "file count expected 36 got $USED"
3575
3576         rm -rf $dir
3577         cleanup_quota_test
3578 }
3579 run_test 40d "Stripe Directory inherit project quota properly"
3580
3581 test_41() {
3582         is_project_quota_supported ||
3583                 skip "Project quota is not supported"