Whamcloud - gitweb
Branch b1_6
authortianzy <tianzy>
Tue, 1 Jul 2008 13:26:03 +0000 (13:26 +0000)
committertianzy <tianzy>
Tue, 1 Jul 2008 13:26:03 +0000 (13:26 +0000)
when setquota is executed, quota limitation on slaves is always reset which leads
to this bug. Now only first setquota and cancelling quota will reset quota
limitation on slaves.
b=16053
i=andrew.perepechko
i=johann

lustre/quota/quota_context.c
lustre/quota/quota_master.c
lustre/tests/sanity-quota.sh

index 8be20ec..f638734 100644 (file)
@@ -553,14 +553,23 @@ dqacq_completion(struct obd_device *obd, struct lustre_quota_ctxt *qctxt,
                 }
 
                 CDEBUG(D_QUOTA, "hardlimt: "LPU64"\n", *hardlimit);
+
+                if (*hardlimit == 0)
+                        goto out_mem;
+
                 switch (opc) {
                 case QUOTA_DQACQ:
                         INC_QLIMIT(*hardlimit, count);
                         break;
                 case QUOTA_DQREL:
                         LASSERTF(count < *hardlimit,
-                                 "count: "LPU64", hardlimit: "LPU64".\n",
-                                 count, *hardlimit);
+                                 "id(%u) flag(%u) type(%c) isblk(%c) "
+                                 "count("LPU64") qd_qunit("LPU64") "
+                                 "hardlimit("LPU64").\n",
+                                 qdata->qd_id, qdata->qd_flags,
+                                 QDATA_IS_GRP(qdata) ? 'g' : 'u',
+                                 QDATA_IS_BLK(qdata) ? 'b': 'i',
+                                 qdata->qd_count, qdata->qd_qunit, *hardlimit);
                         *hardlimit -= count;
                         break;
                 default:
index fbead72..4d67195 100644 (file)
@@ -1063,7 +1063,7 @@ static int mds_init_slave_ilimits(struct obd_device *obd,
 
         /* if we are going to set zero limit, needn't init slaves */
         if (!oqctl->qc_dqblk.dqb_ihardlimit && !oqctl->qc_dqblk.dqb_isoftlimit &&
-            set)
+            !set)
                 RETURN(0);
 
         OBD_ALLOC_PTR(ioqc);
@@ -1071,7 +1071,7 @@ static int mds_init_slave_ilimits(struct obd_device *obd,
                 RETURN(-ENOMEM);
 
         flag = oqctl->qc_dqblk.dqb_ihardlimit ||
-               oqctl->qc_dqblk.dqb_isoftlimit || set;
+               oqctl->qc_dqblk.dqb_isoftlimit || !set;
         ioqc->qc_cmd = flag ? Q_INITQUOTA : Q_SETQUOTA;
         ioqc->qc_id = oqctl->qc_id;
         ioqc->qc_type = oqctl->qc_type;
@@ -1130,7 +1130,7 @@ static int mds_init_slave_blimits(struct obd_device *obd,
 
         /* if we are going to set zero limit, needn't init slaves */
         if (!oqctl->qc_dqblk.dqb_bhardlimit && !oqctl->qc_dqblk.dqb_bsoftlimit &&
-            set)
+            !set)
                 RETURN(0);
 
         OBD_ALLOC_PTR(ioqc);
@@ -1138,7 +1138,7 @@ static int mds_init_slave_blimits(struct obd_device *obd,
                 RETURN(-ENOMEM);
 
         flag = oqctl->qc_dqblk.dqb_bhardlimit ||
-               oqctl->qc_dqblk.dqb_bsoftlimit || set;
+               oqctl->qc_dqblk.dqb_bsoftlimit || !set;
         ioqc->qc_cmd = flag ? Q_INITQUOTA : Q_SETQUOTA;
         ioqc->qc_id = oqctl->qc_id;
         ioqc->qc_type = oqctl->qc_type;
@@ -1199,7 +1199,10 @@ int mds_set_dqblk(struct obd_device *obd, struct obd_quotactl *oqctl)
         time_t btime, itime;
         struct lustre_dquot *dquot;
         struct obd_dqblk *dqblk = &oqctl->qc_dqblk;
-        int set, rc, rc2 = 0, flag = 0;
+        /* orig_set means if quota was set before; now_set means we are
+         * setting/cancelling quota */
+        int orig_set, now_set;
+        int rc, rc2 = 0, flag = 0;
         ENTRY;
 
         OBD_ALLOC_PTR(oqaq);
@@ -1293,24 +1296,26 @@ int mds_set_dqblk(struct obd_device *obd, struct obd_quotactl *oqctl)
         }
 
         up(&mds->mds_qonoff_sem);
-        if (dqblk->dqb_valid & QIF_ILIMITS) {
-                set = !(ihardlimit || isoftlimit);
+        orig_set = ihardlimit || isoftlimit;
+        now_set  = dqblk->dqb_ihardlimit || dqblk->dqb_isoftlimit;
+        if (dqblk->dqb_valid & QIF_ILIMITS && orig_set != now_set) {
                 down(&dquot->dq_sem);
                 dquot->dq_dqb.dqb_curinodes = 0;
                 up(&dquot->dq_sem);
-                rc = mds_init_slave_ilimits(obd, oqctl, set, oqaq);
+                rc = mds_init_slave_ilimits(obd, oqctl, orig_set, oqaq);
                 if (rc) {
                         CERROR("init slave ilimits failed! (rc:%d)\n", rc);
                         goto revoke_out;
                 }
         }
 
-        if (dqblk->dqb_valid & QIF_BLIMITS) {
-                set = !(bhardlimit || bsoftlimit);
+        orig_set = bhardlimit || bsoftlimit;
+        now_set  = dqblk->dqb_bhardlimit || dqblk->dqb_bsoftlimit;
+        if (dqblk->dqb_valid & QIF_BLIMITS && orig_set != now_set) {
                 down(&dquot->dq_sem);
                 dquot->dq_dqb.dqb_curspace = 0;
                 up(&dquot->dq_sem);
-                rc = mds_init_slave_blimits(obd, oqctl, set, oqaq);
+                rc = mds_init_slave_blimits(obd, oqctl, orig_set, oqaq);
                 if (rc) {
                         CERROR("init slave blimits failed! (rc:%d)\n", rc);
                         goto revoke_out;
index 8da422a..a2b3576 100644 (file)
@@ -47,7 +47,7 @@ LUSTRE=${LUSTRE:-`dirname $0`/..}
 init_test_env $@
 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
 
-[ "$SLOW" = "no" ] && EXCEPT_SLOW="9 10 11"
+[ "$SLOW" = "no" ] && EXCEPT_SLOW="9 10 11 21"
 
 QUOTALOG=${TESTSUITELOG:-$TMP/$(basename $0 .sh).log}
 
@@ -1504,6 +1504,84 @@ test_20()
 }
 run_test 20 "test if setquota specifiers work properly (15754)"
 
+test_21_sub() {
+       local testfile=$1
+       local blk_number=$2
+       local seconds=$3
+
+       time=$(($(date +%s) + seconds))
+       while [ $(date +%s) -lt $time ]; do
+           $RUNAS dd if=/dev/zero of=$testfile  bs=$BLK_SZ count=$blk_number > /dev/null 2>&1
+           rm -f $testfile
+       done
+}
+
+# run for fixing bug16053, setquota shouldn't fail when writing and
+# deleting are happening
+test_21() {
+       set_blk_tunesz 512
+       set_blk_unitsz 1024
+
+       wait_delete_completed
+
+       TESTFILE="$DIR/$tdir/$tfile"
+
+       BLK_LIMIT=$((10 * 1024 * 1024)) # 10G
+       FILE_LIMIT=1000000
+
+       log "  Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT) for user: $TSTUSR"
+       $LFS setquota -u $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $MOUNT
+       log "  Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT) for group: $TSTUSR"
+       $LFS setquota -g $TSTUSR -b 0 -B $BLK_LIMIT -i 0 -I $FILE_LIMIT $MOUNT
+
+       # repeat writing on a 1M file
+       test_21_sub ${TESTFILE}_1 1024 30 &
+       DDPID1=$!
+       # repeat writing on a 128M file
+       test_21_sub ${TESTFILE}_2 $((1024 * 128)) 30 &
+       DDPID2=$!
+
+       time=$(($(date +%s) + 30))
+       i=1
+       while [ $(date +%s) -lt $time ]; do
+           log "  Set quota for $i times"
+           $LFS setquota -u $TSTUSR -b 0 -B $((BLK_LIMIT + 1024 * i)) -i 0 -I $((FILE_LIMIT + i)) $MOUNT
+           $LFS setquota -g $TSTUSR -b 0 -B $((BLK_LIMIT + 1024 * i)) -i 0 -I $((FILE_LIMIT + i)) $MOUNT
+           i=$((i+1))
+           sleep 1
+       done
+
+       count=0
+       while [ true ]; do
+           if [  $(ps -p ${DDPID1} | wc -l) -eq 1 ]; then break; fi
+           count=$[count+1]
+           if [ $count -gt 60 ]; then
+               error "dd should be finished!"
+           fi
+           sleep 1
+       done
+       echo "(dd_pid=$DDPID1, time=$count)successful"
+
+       count=0
+       while [ true ]; do
+           if [ $(ps -p ${DDPID2} | wc -l) -eq 1 ]; then break; fi
+           count=$[count+1]
+           if [ $count -gt 60 ]; then
+               error "dd should be finished!"
+           fi
+           sleep 1
+       done
+       echo "(dd_pid=$DDPID2, time=$count)successful"
+
+       set_blk_unitsz $((128 * 1024))
+       set_blk_tunesz $((128 * 1024 / 2))
+       $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I 0 $MOUNT
+       $LFS setquota -g $TSTUSR -b 0 -B 0 -i 0 -I 0 $MOUNT
+
+       return $RC
+}
+run_test 21 "run for fixing bug16053 ==========="
+
 # turn off quota
 test_99()
 {