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