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
}
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:
/* 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);
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;
/* 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);
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;
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);
}
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;
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}
}
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()
{