when mds and osts use different quota unit(32bit and 64bit), quota will be released
repeatly. This patch voids sending multiple quota reqs to mds, which will keep the
status between the reqs.
b=12588
i=johann
i=wangdi
Description: client-side metadata stat-ahead during readdir(directory readahead)
Details : perform client-side metadata stat-ahead when the client detects
readdir and sequential stat of dir entries therein
+
+Severity : minor
+Bugzilla : 12588
+Description: when mds and osts use different quota unit(32bit and 64bit),
+ quota will be released repeatly.
+Details : void sending multiple quota reqs to mds, which will keep the status
+ between the reqs.
--------------------------------------------------------------------------------
2007-08-27 Cluster File Systems, Inc. <info@clusterfs.com>
#define ECHO_CONNECT_SUPPORTED (0)
#define MGS_CONNECT_SUPPORTED (OBD_CONNECT_VERSION | OBD_CONNECT_AT)
-#define MAX_QUOTA_COUNT32 ((0xffffffffULL >> QUOTABLOCK_BITS) << QUOTABLOCK_BITS)
+#define MAX_QUOTA_COUNT32 (0xffffffffULL)
#define OBD_OCD_VERSION(major,minor,patch,fix) (((major)<<24) + ((minor)<<16) +\
((patch)<<8) + (fix))
if (!d)
return NULL;
- LASSERT(d->qd_count <= MAX_QUOTA_COUNT32);
tmp = *d;
ret = (struct qunit_data_old *)d;
ret->qd_id = tmp.qd_id;
static int split_before_schedule_dqacq(struct obd_device *obd, struct lustre_quota_ctxt *qctxt,
struct qunit_data *qdata, int opc, int wait)
{
- int rc = 0, ret;
+ int rc = 0;
+ unsigned long factor;
struct qunit_data tmp_qdata;
ENTRY;
- LASSERT(qdata);
- if (qctxt->lqc_import)
- while (should_translate_quota(qctxt->lqc_import) &&
- qdata->qd_count > MAX_QUOTA_COUNT32) {
+ LASSERT(qdata && qdata->qd_count);
+ QDATA_DEBUG(qdata, "%s quota split.\n",
+ (qdata->qd_flags & QUOTA_IS_BLOCK) ? "block" : "inode");
+ if (qdata->qd_flags & QUOTA_IS_BLOCK)
+ factor = MAX_QUOTA_COUNT32 / qctxt->lqc_bunit_sz *
+ qctxt->lqc_bunit_sz;
+ else
+ factor = MAX_QUOTA_COUNT32 / qctxt->lqc_iunit_sz *
+ qctxt->lqc_iunit_sz;
+ if (qctxt->lqc_import && should_translate_quota(qctxt->lqc_import) &&
+ qdata->qd_count > factor) {
tmp_qdata = *qdata;
- tmp_qdata.qd_count = MAX_QUOTA_COUNT32;
+ tmp_qdata.qd_count = factor;
qdata->qd_count -= tmp_qdata.qd_count;
- ret = schedule_dqacq(obd, qctxt, &tmp_qdata, opc, wait);
- if (!rc)
- rc = ret;
- }
-
- if (qdata->qd_count){
- ret = schedule_dqacq(obd, qctxt, qdata, opc, wait);
- if (!rc)
- rc = ret;
+ QDATA_DEBUG((&tmp_qdata), "be split.\n");
+ rc = schedule_dqacq(obd, qctxt, &tmp_qdata, opc, wait);
+ } else{
+ QDATA_DEBUG(qdata, "don't be split.\n");
+ rc = schedule_dqacq(obd, qctxt, qdata, opc, wait);
}
RETURN(rc);
LASSERT(qdata);
qunit_sz = is_blk ? qctxt->lqc_bunit_sz : qctxt->lqc_iunit_sz;
div_r = do_div(qd_tmp, qunit_sz);
- LASSERT(!div_r);
+ LASSERTF(!div_r, "qunit_sz: %lu, return qunit_sz: "LPU64"\n",
+ qunit_sz, qd_tmp);
/* update local operational quota file */
if (rc == 0) {
switch (opc) {
case QUOTA_DQACQ:
+ CDEBUG(D_QUOTA, "%s(acq):count: %d, hardlimt: "LPU64
+ ",type: %s.\n", obd->obd_name, count, *hardlimit,
+ qdata_type ? "grp": "usr");
INC_QLIMIT(*hardlimit, count);
break;
case QUOTA_DQREL:
- LASSERT(count < *hardlimit);
+ CDEBUG(D_QUOTA, "%s(rel):count: %d, hardlimt: "LPU64
+ ",type: %s.\n", obd->obd_name, count, *hardlimit,
+ qdata_type ? "grp": "usr");
+ LASSERTF(count < *hardlimit,
+ "count: %d, hardlimit: "LPU64".\n",
+ count, *hardlimit);
*hardlimit -= count;
break;
default:
struct dqacq_async_args *aa;
int size[2] = { sizeof(struct ptlrpc_body), sizeof(*reqdata) };
struct obd_import *imp = NULL;
+ unsigned long factor;
int rc = 0;
ENTRY;
RETURN(-ENOMEM);
}
+ if (qdata->qd_flags & QUOTA_IS_BLOCK)
+ factor = MAX_QUOTA_COUNT32 / qctxt->lqc_bunit_sz *
+ qctxt->lqc_bunit_sz;
+ else
+ factor = MAX_QUOTA_COUNT32 / qctxt->lqc_iunit_sz *
+ qctxt->lqc_iunit_sz;
+
LASSERTF(!should_translate_quota(imp) ||
- qdata->qd_count <= MAX_QUOTA_COUNT32,
+ qdata->qd_count <= factor,
"qd_count: "LPU64"; should_translate_quota: %d.\n",
qdata->qd_count, should_translate_quota(imp));
if (should_translate_quota(imp))
qinfo->qi_info[1].dqi_free_entry, ## arg);
#define QDATA_DEBUG(qd, fmt, arg...) \
- CDEBUG(D_QUOTA, "id(%u) type(%lu) count(%llu) isblk(%lu):" \
+ CDEBUG(D_QUOTA, "id(%u) type(%lu) count("LPU64") isblk(%lu):" \
fmt, qd->qd_id, qd->qd_flags & QUOTA_IS_GRP, qd->qd_count, \
(qd->qd_flags & QUOTA_IS_BLOCK) >> 1, \
## arg);
SRCDIR=`dirname $0`
export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/../utils:$PATH:/sbin
-if [ "$1" == "9_10" ]; then
- echo "only run for test9 and test10"
- shift
- TEST_9_10=1
- ONLY="9 10"
-else
- TEST_9_10=0
-fi
ONLY=${ONLY:-"$*"}
ALWAYS_EXCEPT=${ALWAYS_EXCEPT:-""}
# UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
MOUNT_HINT2=$MOUNT_2
MOUNT="`mounted_lustre_filesystems 1`"
MOUNT_2="`mounted_lustre_filesystems 2`"
-if [ $TEST_9_10 -eq 1 -a "$MOUNT" ]; then
- echo "test9 and test10 will run on $MOUNT"
-elif [ "$MOUNT" -a "$MOUNT_2" ]; then
+if [ "$MOUNT" -a "$MOUNT_2" ]; then
echo "testing on $MOUNT and $MOUNT_2"
elif [ "$MOUNT" -o "$MOUNT_2" ]; then
error "test needs two mounts, only found $MOUNT $MOUNT_2!"
LPROC=/proc/fs/lustre
LOVNAME=`cat $LPROC/llite/*/lov/common_name | tail -n 1`
-if [ $TEST_9_10 -eq 1 ]; then
- OSTCOUNT=2
-else
- OSTCOUNT=`cat $LPROC/lov/$LOVNAME/numobd`
-fi
+OSTCOUNT=`cat $LPROC/lov/$LOVNAME/numobd`
STRIPECOUNT=`cat $LPROC/lov/$LOVNAME/stripecount`
STRIPESIZE=`cat $LPROC/lov/$LOVNAME/stripesize`
ORIGFREE=`cat $LPROC/lov/$LOVNAME/kbytesavail`
set_file_unitsz $IUNIT_SZ
fi
}
-if [ $TEST_9_10 -eq 0 ]; then
- pre_test
-fi
+pre_test
post_test() {
if [ -z "$NOSETUP" ]; then
return 0;
fi
+ set_blk_unitsz $((1024 * 100))
+ set_blk_tunesz $((1024 * 50))
+
# set the D_QUOTA flag
debugsave
sysctl -w lnet.debug="+quota"
TESTFILE="$TSTDIR/quota_tst90"
- echo " Set block limit $LIMIT kbytes to $TSTUSR.$TSTUSR"
BLK_LIMIT=$((100 * 1024 * 1024)) # 100G
FILE_LIMIT=1000000
- echo " Set enough high limit for user: $TSTUSR"
+ echo " Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT) for user: $TSTUSR"
$LFS setquota -u $TSTUSR 0 $BLK_LIMIT 0 $FILE_LIMIT $MOUNT
- echo " Set enough high limit for group: $TSTUSR"
+ echo " Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT) for group: $TSTUSR"
$LFS setquota -g $TSTUSR 0 $BLK_LIMIT 0 $FILE_LIMIT $MOUNT
echo " Set stripe"
touch $TESTFILE
chown $TSTUSR.$TSTUSR $TESTFILE
+ $SHOW_QUOTA_USER
+ $SHOW_QUOTA_GROUP
+
echo " Write the big file of $(($OSTCOUNT * 9 / 2 ))G ..."
$RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$size_file || error "(usr) write $((9 / 2 * $OSTCOUNT))G file failure, but expect success"
+ $SHOW_QUOTA_USER
+ $SHOW_QUOTA_GROUP
+
echo " delete the big file of $(($OSTCOUNT * 9 / 2))G..."
$RUNAS rm -f $TESTFILE
+ $SHOW_QUOTA_USER
+ $SHOW_QUOTA_GROUP
+
echo " write the big file of 2G..."
$RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$((1024 * 1024 * 2)) || error "(usr) write $((9 / 2 * $OSTCOUNT))G file failure, but expect seccess"
$RUNAS rm -f $TESTFILE
RC=$?
+ set_blk_tunesz $BTUNE_SZ
+ set_blk_unitsz $BUNIT_SZ
+
debugrestore
return $RC
}
sync; sleep 10; sync;
+ set_blk_unitsz $((1024 * 100))
+ set_blk_tunesz $((1024 * 50))
+
# set the D_QUOTA flag
debugsave
sysctl -w lnet.debug="+quota"
TESTFILE="$TSTDIR/quota_tst100"
- echo " Set block limit $LIMIT kbytes to $TSTUSR.$TSTUSR"
BLK_LIMIT=$((100 * 1024 * 1024)) # 100G
FILE_LIMIT=1000000
- echo " Set enough high limit for user: $TSTUSR"
+ echo " Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT) for user: $TSTUSR"
$LFS setquota -u $TSTUSR 0 $BLK_LIMIT 0 $FILE_LIMIT $MOUNT
- echo " Set enough high limit for group: $TSTUSR"
+ echo " Set enough high limit(block:$BLK_LIMIT; file: $FILE_LIMIT) for group: $TSTUSR"
$LFS setquota -g $TSTUSR 0 $BLK_LIMIT 0 $FILE_LIMIT $MOUNT
echo " Set stripe"
touch $TESTFILE
chown $TSTUSR.$TSTUSR $TESTFILE
+ $SHOW_QUOTA_USER
+ $SHOW_QUOTA_GROUP
+
echo " Write the big file of $(($OSTCOUNT * 9 / 2 ))G ..."
$RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$size_file || error "(usr) write $((9 / 2 * $OSTCOUNT))G file failure, but expect success"
+ $SHOW_QUOTA_USER
+ $SHOW_QUOTA_GROUP
+
echo " delete the big file of $(($OSTCOUNT * 9 / 2))G..."
$RUNAS rm -f $TESTFILE
+ $SHOW_QUOTA_USER
+ $SHOW_QUOTA_GROUP
+
echo " write the big file of 2G..."
$RUNAS dd if=/dev/zero of=$TESTFILE bs=$BLK_SZ count=$((1024 * 1024 * 2)) || error "(usr) write $((9 / 2 * $OSTCOUNT))G file failure, but expect success"
# make qd_count 64 bit
sysctl -w lustre.fail_loc=0
+ set_blk_tunesz $BTUNE_SZ
+ set_blk_unitsz $BUNIT_SZ
+
return $RC
}
run_test 10 "run for fixing bug10707(32bit) ==========="
log "cleanup: ======================================================"
if [ "`mount | grep ^$NAME`" ]; then
rm -fr $TSTDIR
- if [ $TEST_9_10 -eq 0 ]; then
post_test
- fi
# delete test user and group
userdel "$TSTUSR"
userdel "$TSTUSR2"