* or inode_create rpc. When need to acquire quota, return QUOTA_RET_ACQUOTA
*/
static int quota_check_common(struct obd_device *obd, unsigned int uid,
- unsigned int gid, int count, int cycle, int isblk)
+ unsigned int gid, int count, int cycle, int isblk,
+ struct inode *inode, int frags, int *pending)
{
struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
int i;
__u32 id[MAXQUOTAS] = { uid, gid };
struct qunit_data qdata[MAXQUOTAS];
+ int mb = 0;
int rc = 0, rc2[2] = { 0, 0 };
ENTRY;
rc2[i] = compute_remquota(obd, qctxt, &qdata[i], isblk);
spin_lock(&lqs->lqs_lock);
if (!cycle) {
- rc = QUOTA_RET_INC_PENDING;
- if (isblk)
- lqs->lqs_bwrite_pending += count;
- else
- lqs->lqs_iwrite_pending += count;
+ if (isblk) {
+ *pending = count * CFS_PAGE_SIZE;
+ /* in order to complete this write, we need extra
+ * meta blocks. This function can get it through
+ * data needed to be written b=16542 */
+ if (inode) {
+ mb = *pending;
+ rc = fsfilt_get_mblk(obd, qctxt->lqc_sb,
+ &mb, inode,frags);
+ if (rc)
+ CDEBUG(D_ERROR,
+ "can't get extra "
+ "meta blocks.\n");
+ else
+ *pending += mb;
+ }
+ lqs->lqs_bwrite_pending += *pending;
+ } else {
+ *pending = count;
+ lqs->lqs_iwrite_pending += *pending;
+ }
}
if (rc2[i] == QUOTA_RET_OK) {
- if (isblk && qdata[i].qd_count <
- lqs->lqs_bwrite_pending * CFS_PAGE_SIZE)
+ if (isblk && qdata[i].qd_count < lqs->lqs_bwrite_pending)
rc2[i] = QUOTA_RET_ACQUOTA;
if (!isblk && qdata[i].qd_count <
lqs->lqs_iwrite_pending)
rc2[i] = QUOTA_RET_ACQUOTA;
}
spin_unlock(&lqs->lqs_lock);
- CDEBUG(D_QUOTA, "count: %d, write pending: %lu, qd_count: "LPU64
- ".\n", count,
+ CDEBUG(D_QUOTA, "count: %d, lqs pending: %lu, qd_count: "LPU64
+ ", metablocks: %d, isblk: %d, pending: %d.\n", count,
isblk ? lqs->lqs_bwrite_pending : lqs->lqs_iwrite_pending,
- qdata[i].qd_count);
+ qdata[i].qd_count, mb, isblk, *pending);
/* When cycle is zero, lqs_*_pending will be changed. We will
* get reference of the lqs here and put reference of lqs in
}
if (rc2[0] == QUOTA_RET_ACQUOTA || rc2[1] == QUOTA_RET_ACQUOTA)
- RETURN(rc | QUOTA_RET_ACQUOTA);
+ RETURN(QUOTA_RET_ACQUOTA);
else
RETURN(rc);
}
static int quota_chk_acq_common(struct obd_device *obd, unsigned int uid,
unsigned int gid, int count, int *pending,
quota_acquire acquire,
- struct obd_trans_info *oti, int isblk)
+ struct obd_trans_info *oti, int isblk,
+ struct inode *inode, int frags)
{
struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
struct timeval work_start;
* have to wait for the completion of in flight dqacq/dqrel,
* in order to get enough quota for write b=12588 */
do_gettimeofday(&work_start);
- while ((rc = quota_check_common(obd, uid, gid, count, cycle, isblk)) &
+ while ((rc = quota_check_common(obd, uid, gid, count, cycle, isblk,
+ inode, frags, pending)) &
QUOTA_RET_ACQUOTA) {
spin_lock(&qctxt->lqc_lock);
spin_unlock(&qctxt->lqc_lock);
}
- if (rc & QUOTA_RET_INC_PENDING)
- *pending = 1;
-
cycle++;
if (isblk)
OBD_FAIL_TIMEOUT(OBD_FAIL_OST_HOLD_WRITE_RPC, 90);
CDEBUG(D_QUOTA, "recheck quota with rc: %d, cycle: %d\n", rc,
cycle);
}
-
- if (!cycle && rc & QUOTA_RET_INC_PENDING)
- *pending = 1;
-
do_gettimeofday(&work_end);
timediff = cfs_timeval_sub(&work_end, &work_start, NULL);
lprocfs_counter_add(qctxt->lqc_stats,
* pending blocks and inodes
*/
static int quota_pending_commit(struct obd_device *obd, unsigned int uid,
- unsigned int gid, int count, int isblk)
+ unsigned int gid, int pending, int isblk)
{
struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
struct timeval work_start;
quota_search_lqs(&qdata[i], NULL, qctxt, &lqs);
if (lqs) {
int flag = 0;
- CDEBUG(D_QUOTA, "pending: %lu, count: %d.\n",
- isblk ? lqs->lqs_bwrite_pending :
- lqs->lqs_iwrite_pending, count);
spin_lock(&lqs->lqs_lock);
if (isblk) {
- if (lqs->lqs_bwrite_pending >= count) {
- lqs->lqs_bwrite_pending -= count;
+ if (lqs->lqs_bwrite_pending >= pending) {
+ lqs->lqs_bwrite_pending -= pending;
spin_unlock(&lqs->lqs_lock);
flag = 1;
} else {
"there are too many blocks!\n");
}
} else {
- if (lqs->lqs_iwrite_pending >= count) {
- lqs->lqs_iwrite_pending -= count;
+ if (lqs->lqs_iwrite_pending >= pending) {
+ lqs->lqs_iwrite_pending -= pending;
spin_unlock(&lqs->lqs_lock);
flag = 1;
} else {
"there are too many files!\n");
}
}
+ CDEBUG(D_QUOTA, "lqs pending: %lu, pending: %d, "
+ "isblk: %d.\n",
+ isblk ? lqs->lqs_bwrite_pending :
+ lqs->lqs_iwrite_pending, pending, isblk);
lqs_putref(lqs);
/* When lqs_*_pening is changed back, we'll putref lqs
int rc;
ENTRY;
+ if (unlikely(mds->mds_quota)) {
+ CWARN("try to reinitialize quota context!\n");
+ RETURN(0);
+ }
+
init_rwsem(&obt->obt_rwsem);
obt->obt_qfmt = LUSTRE_QUOTA_V2;
mds->mds_quota_info.qi_version = LUSTRE_QUOTA_V2;
static int mds_quota_cleanup(struct obd_device *obd)
{
ENTRY;
- obd->u.mds.mds_quota = 0;
+ if (unlikely(!obd->u.mds.mds_quota))
+ RETURN(0);
+
qctxt_cleanup(&obd->u.obt.obt_qctxt, 0);
RETURN(0);
}
struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
ENTRY;
+ if (unlikely(!obd->u.mds.mds_quota))
+ RETURN(0);
+
if (data != NULL)
QUOTA_MASTER_READY(qctxt);
else
struct obd_quotactl oqctl;
ENTRY;
+ if (unlikely(!mds->mds_quota))
+ RETURN(0);
+
+ mds->mds_quota = 0;
memset(&oqctl, 0, sizeof(oqctl));
oqctl.qc_type = UGQUOTA;