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