struct lustre_dquot *dquot = NULL;
ENTRY;
- OBD_SLAB_ALLOC(dquot, lustre_dquot_cachep, CFS_ALLOC_IO, sizeof(*dquot));
+ OBD_SLAB_ALLOC_PTR_GFP(dquot, lustre_dquot_cachep, CFS_ALLOC_IO);
if (dquot == NULL)
RETURN(NULL);
oqaq->qaq_id = id;
oqaq->qaq_flags = type;
- quota_search_lqs(NULL, oqaq, qctxt, &lqs);
- if (lqs) {
+ lqs = quota_search_lqs(LQS_KEY(type, id), qctxt, 0);
+ if (lqs && !IS_ERR(lqs)) {
spin_lock(&lqs->lqs_lock);
oqaq->qaq_bunit_sz = lqs->lqs_bunit_sz;
oqaq->qaq_iunit_sz = lqs->lqs_iunit_sz;
struct lov_obd *lov = &lov_mds_obd->u.lov;
__u32 ost_num = lov->desc.ld_tgt_count, mdt_num = 1;
struct quota_adjust_qunit *oqaq = NULL;
- unsigned int uid = 0, gid = 0;
+ unsigned int qid[MAXQUOTAS] = { 0, 0 };
struct lustre_quota_info *info = &mds->mds_quota_info;
struct lustre_dquot *dquot = NULL;
int adjust_res = 0;
}
if (type)
- gid = dquot->dq_id;
+ qid[GRPQUOTA] = dquot->dq_id;
else
- uid = dquot->dq_id;
+ qid[USRQUOTA] = dquot->dq_id;
up(&dquot->dq_sem);
- rc = qctxt_adjust_qunit(obd, qctxt, uid, gid, is_blk, 0, NULL);
+ rc = qctxt_adjust_qunit(obd, qctxt, qid, is_blk, 0, NULL);
if (rc == -EDQUOT || rc == -EBUSY) {
CDEBUG(D_QUOTA, "rc: %d.\n", rc);
rc = 0;
dqacq_adjust_qunit_sz(obd, qdata->qd_id, QDATA_IS_GRP(qdata),
QDATA_IS_BLK(qdata));
- quota_search_lqs(qdata, NULL, qctxt, &lqs);
- if (QDATA_IS_BLK(qdata)) {
- if (!lqs) {
- CDEBUG(D_INFO, "Can't find the lustre qunit size!\n");
- qdata->qd_qunit = qctxt->lqc_bunit_sz;
- } else {
- spin_lock(&lqs->lqs_lock);
- qdata->qd_qunit = lqs->lqs_bunit_sz;
- spin_unlock(&lqs->lqs_lock);
- }
- QDATA_SET_ADJBLK(qdata);
+ lqs = quota_search_lqs(LQS_KEY(QDATA_IS_GRP(qdata), qdata->qd_id),
+ qctxt, 0);
+ if (lqs == NULL || IS_ERR(lqs)) {
+ CDEBUG(D_INFO, "Can't find the lustre qunit size!\n");
+ qdata->qd_qunit = QDATA_IS_BLK(qdata) ? qctxt->lqc_bunit_sz :
+ qctxt->lqc_iunit_sz;
} else {
- if (!lqs) {
- CDEBUG(D_INFO, "Can't find the lustre qunit size!\n");
- qdata->qd_qunit = qctxt->lqc_iunit_sz;
- } else {
- spin_lock(&lqs->lqs_lock);
- qdata->qd_qunit = lqs->lqs_iunit_sz;
- spin_unlock(&lqs->lqs_lock);
- }
- QDATA_SET_ADJINO(qdata);
+ spin_lock(&lqs->lqs_lock);
+ qdata->qd_qunit = QDATA_IS_BLK(qdata) ? lqs->lqs_bunit_sz :
+ lqs->lqs_iunit_sz;
+ spin_unlock(&lqs->lqs_lock);
}
+ if (QDATA_IS_BLK(qdata))
+ QDATA_SET_ADJBLK(qdata);
+ else
+ QDATA_SET_ADJINO(qdata);
+
QDATA_DEBUG(qdata, "alloc/release qunit in dqacq_handler\n");
if (lqs)
lqs_putref(lqs);
return rc;
}
-int mds_quota_adjust(struct obd_device *obd, unsigned int qcids[],
- unsigned int qpids[], int rc, int opc)
+int mds_quota_adjust(struct obd_device *obd, const unsigned int qcids[],
+ const unsigned int qpids[], int rc, int opc)
{
struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
int rc2 = 0;
switch (opc) {
case FSFILT_OP_SETATTR:
/* release file quota on original owner */
- rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids[0], qpids[1], 0, 0,
- NULL);
+ rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids, 0, 0, NULL);
/* release block quota on original owner */
- rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids[0], qpids[1], 1, 0,
- NULL);
+ rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids, 1, 0, NULL);
/* acquire file quota on current owner */
- rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 0, 0,
- NULL);
+ rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 0, 0, NULL);
/* acquire block quota on current owner */
- rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 1, 0,
- NULL);
+ rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0, NULL);
break;
case FSFILT_OP_UNLINK_PARTIAL_CHILD:
/* release file quota on child */
- rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 0, 0,
- NULL);
+ rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 0, 0, NULL);
/* rlease block quota on child */
- rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 1, 0,
- NULL);
+ rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0, NULL);
break;
case FSFILT_OP_CREATE_PARTIAL_CHILD:
/* acquire file quota on child */
- rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 0, 0,
- NULL);
+ rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 0, 0, NULL);
/* acquire block quota on child */
- rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 1, 0,
- NULL);
+ rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0, NULL);
break;
case FSFILT_OP_LINK:
/* acquire block quota on parent */
- rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids[0], qpids[1], 1, 0,
- NULL);
+ rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids, 1, 0, NULL);
break;
case FSFILT_OP_UNLINK:
/* release block quota on parent */
- rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids[0], qpids[1], 1, 0,
- NULL);
+ rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids, 1, 0, NULL);
/* release file quota on child */
- rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 0, 0,
- NULL);
+ rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 0, 0, NULL);
if (qpids[0] != qcids[0] || qpids[1] != qcids[1])
/* release block quota on child */
- rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0],
- qcids[1], 1, 0, NULL);
+ rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0,
+ NULL);
break;
case FSFILT_OP_UNLINK_PARTIAL_PARENT:
/* release block quota on parent */
- rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids[0], qpids[1], 1, 0,
- NULL);
+ rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids, 1, 0, NULL);
break;
case FSFILT_OP_CREATE:
/* acquire block quota on parent */
- rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids[0], qpids[1], 1, 0,
- NULL);
+ rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids, 1, 0, NULL);
/* acquire file quota on child */
- rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 0, 0,
- NULL);
+ rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 0, 0, NULL);
if (qpids[0] != qcids[0] || qpids[1] != qcids[1])
/* acquire block quota on child */
- rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0],
- qcids[1], 1, 0, NULL);
+ rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0,
+ NULL);
break;
default:
LBUG();
RETURN(0);
}
-int filter_quota_adjust(struct obd_device *obd, unsigned int qcids[],
- unsigned int qpids[], int rc, int opc)
+int filter_quota_adjust(struct obd_device *obd, const unsigned int qcids[],
+ const unsigned int qpids[], int rc, int opc)
{
struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
int rc2 = 0;
switch (opc) {
case FSFILT_OP_SETATTR:
/* acquire/release block quota on original & current owner */
- rc = qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 1, 0,
- NULL);
- rc2 = qctxt_adjust_qunit(obd, qctxt, qpids[0], qpids[1], 1, 0,
- NULL);
+ rc = qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0, NULL);
+ rc2 = qctxt_adjust_qunit(obd, qctxt, qpids, 1, 0, NULL);
break;
case FSFILT_OP_UNLINK:
/* release block quota on this owner */
case FSFILT_OP_CREATE: /* XXX for write operation on obdfilter */
/* acquire block quota on this owner */
- rc = qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 1, 0,
- NULL);
+ rc = qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0, NULL);
break;
default:
LBUG();
LASSERT(qinfo->qi_version == LUSTRE_QUOTA_V2);
+ if (oqctl->qc_type != USRQUOTA &&
+ oqctl->qc_type != GRPQUOTA &&
+ oqctl->qc_type != UGQUOTA)
+ return -EINVAL;
+
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
down(&mds->mds_qonoff_sem);
int rc;
struct lvfs_run_ctxt saved;
+ if (oqctl->qc_type != USRQUOTA &&
+ oqctl->qc_type != GRPQUOTA &&
+ oqctl->qc_type != UGQUOTA)
+ RETURN(-EINVAL);
+
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
down(&mds->mds_qonoff_sem);
int rc;
ENTRY;
+ if (oqctl->qc_type != USRQUOTA &&
+ oqctl->qc_type != GRPQUOTA &&
+ oqctl->qc_type != UGQUOTA)
+ RETURN(-EINVAL);
+
if (!atomic_dec_and_test(&obt->obt_quotachecking)) {
CDEBUG(D_INFO, "other people are doing quotacheck\n");
atomic_inc(&obt->obt_quotachecking);
RETURN(-EBUSY);
}
+ LASSERT(!obt->obt_qctxt.lqc_immutable);
down(&mds->mds_qonoff_sem);
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
rc = mds_admin_quota_on(obd, oqctl);
struct mds_obd *mds = &obd->u.mds;
struct obd_device_target *obt = &obd->u.obt;
struct lvfs_run_ctxt saved;
- int rc, rc2;
+ int rc, rc2, imm;
ENTRY;
+ imm = oqctl->qc_type & IMMQUOTA;
+ oqctl->qc_type &= ~IMMQUOTA;
+
+ if (oqctl->qc_type != USRQUOTA &&
+ oqctl->qc_type != GRPQUOTA &&
+ oqctl->qc_type != UGQUOTA)
+ RETURN(-EINVAL);
+
if (!atomic_dec_and_test(&obt->obt_quotachecking)) {
CDEBUG(D_INFO, "other people are doing quotacheck\n");
atomic_inc(&obt->obt_quotachecking);
rc = obd_quotactl(mds->mds_osc_exp, oqctl);
rc2 = fsfilt_quotactl(obd, obd->u.obt.obt_sb, oqctl);
- if (!rc2)
+ if (!rc2) {
+ if (imm)
+ obt->obt_qctxt.lqc_immutable = 1;
obt->obt_qctxt.lqc_flags &= ~UGQUOTA2LQC(oqctl->qc_type);
-
+ }
pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
up(&mds->mds_qonoff_sem);
atomic_inc(&obt->obt_quotachecking);
int rc;
ENTRY;
+ if (oqctl->qc_type != USRQUOTA &&
+ oqctl->qc_type != GRPQUOTA)
+ RETURN(-EINVAL);
+
down(&mds->mds_qonoff_sem);
if (qinfo->qi_files[oqctl->qc_type] == NULL) {
rc = -ESRCH;
int rc = 0;
ENTRY;
+ if (oqctl->qc_type != USRQUOTA &&
+ oqctl->qc_type != GRPQUOTA)
+ RETURN(-EINVAL);
+
down(&mds->mds_qonoff_sem);
if (qinfo->qi_files[oqctl->qc_type] == NULL) {
rc = -ESRCH;
if ((type & LQUOTA_FLAGS_ADJBLK) && blimit) {
__u64 b_limitation =
- oqaq->qaq_bunit_sz * ost_num * shrink_qunit_limit;
+ oqaq->qaq_bunit_sz * (ost_num + 1) * shrink_qunit_limit;
/* enlarge block qunit size */
while (blimit >
QUSG(dquot->dq_dqb.dqb_curspace + 2 * b_limitation, 1)) {
oqaq->qaq_bunit_sz =
QUSG(oqaq->qaq_bunit_sz * cqs_factor, 1)
<< QUOTABLOCK_BITS;
- b_limitation = oqaq->qaq_bunit_sz * ost_num *
+ b_limitation = oqaq->qaq_bunit_sz * (ost_num + 1) *
shrink_qunit_limit;
}
do_div(oqaq->qaq_bunit_sz , cqs_factor);
oqaq->qaq_bunit_sz = QUSG(oqaq->qaq_bunit_sz, 1) <<
QUOTABLOCK_BITS;
- b_limitation = oqaq->qaq_bunit_sz * ost_num *
+ b_limitation = oqaq->qaq_bunit_sz * (ost_num + 1) *
shrink_qunit_limit;
if (oqaq->qaq_bunit_sz < qctxt->lqc_cqs_least_bunit)
break;
/* XXX: for file limits only adjust local now */
struct obd_device_target *obt = &obd->u.obt;
struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt;
- unsigned int uid = 0, gid = 0;
+ unsigned int id[MAXQUOTAS] = { 0, 0 };
struct obd_quotactl *ioqc = NULL;
int flag;
int rc;
/* trigger local qunit pre-acquire */
if (oqctl->qc_type == USRQUOTA)
- uid = oqctl->qc_id;
+ id[USRQUOTA] = oqctl->qc_id;
else
- gid = oqctl->qc_id;
+ id[GRPQUOTA] = oqctl->qc_id;
- rc = qctxt_adjust_qunit(obd, &obd->u.obt.obt_qctxt, uid, gid, 0, 0,
- NULL);
+ rc = qctxt_adjust_qunit(obd, &obd->u.obt.obt_qctxt, id, 0, 0, NULL);
if (rc == -EDQUOT || rc == -EBUSY) {
CDEBUG(D_QUOTA, "rc: %d.\n", rc);
rc = 0;
struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt;
struct mds_obd *mds = &obd->u.mds;
struct obd_quotactl *ioqc;
- unsigned int uid = 0, gid = 0;
+ unsigned int id[MAXQUOTAS] = { 0, 0 };
int rc, rc1 = 0;
int flag;
ENTRY;
/* trigger local qunit pre-acquire */
if (oqctl->qc_type == USRQUOTA)
- uid = oqctl->qc_id;
+ id[USRQUOTA] = oqctl->qc_id;
else
- gid = oqctl->qc_id;
+ id[GRPQUOTA] = oqctl->qc_id;
/* initialize all slave's limit */
rc = obd_quotactl(mds->mds_osc_exp, ioqc);
- rc = qctxt_adjust_qunit(obd, &obd->u.obt.obt_qctxt, uid, gid, 1, 0,
- NULL);
+ rc = qctxt_adjust_qunit(obd, &obd->u.obt.obt_qctxt, id, 1, 0, NULL);
if (rc == -EDQUOT || rc == -EBUSY) {
CDEBUG(D_QUOTA, "rc: %d.\n", rc);
rc = 0;
int rc, rc2 = 0, flag = 0;
ENTRY;
+ if (oqctl->qc_type != USRQUOTA &&
+ oqctl->qc_type != GRPQUOTA)
+ RETURN(-EINVAL);
+
OBD_ALLOC_PTR(oqaq);
if (!oqaq)
RETURN(-ENOMEM);
/* get block usage from OSS */
soqc->qc_dqblk.dqb_curspace = 0;
rc = obd_quotactl(obd->u.mds.mds_osc_exp, soqc);
- if (!rc) {
+ if (!rc || rc == -EREMOTEIO) {
oqctl->qc_dqblk.dqb_curspace = soqc->qc_dqblk.dqb_curspace;
oqctl->qc_dqblk.dqb_valid |= QIF_SPACE;
}
int rc;
ENTRY;
+ if (oqctl->qc_type != USRQUOTA &&
+ oqctl->qc_type != GRPQUOTA)
+ RETURN(-EINVAL);
+
down(&mds->mds_qonoff_sem);
dqblk->dqb_valid = 0;
if (qinfo->qi_files[oqctl->qc_type] == NULL)
{
struct qmaster_recov_thread_data *data = arg;
struct obd_device *obd = data->obd;
+ struct mds_obd *mds = &obd->u.mds;
+ struct lustre_quota_info *qinfo = &mds->mds_quota_info;
int rc = 0;
unsigned short type;
ENTRY;
ptlrpc_daemonize("qmaster_recovd");
+ /* for mds */
+ class_incref(obd, "qmaster_recovd_mds", obd);
+ /* for lov */
+ class_incref(mds->mds_osc_obd, "qmaster_recovd_lov", mds->mds_osc_obd);
+
complete(&data->comp);
for (type = USRQUOTA; type < MAXQUOTAS; type++) {
- struct mds_obd *mds = &obd->u.mds;
- struct lustre_quota_info *qinfo = &mds->mds_quota_info;
struct list_head id_list;
struct dquot_id *dqid, *tmp;
kfree(dqid);
}
}
+ class_decref(mds->mds_osc_obd, "qmaster_recovd_lov", mds->mds_osc_obd);
+ class_decref(obd, "qmaster_recovd_mds", obd);
RETURN(rc);
}
int mds_quota_recovery(struct obd_device *obd)
{
struct mds_obd *mds = &obd->u.mds;
- struct lov_obd *lov = &mds->mds_osc_obd->u.lov;
struct qmaster_recov_thread_data data;
int rc = 0;
ENTRY;
- if (unlikely(!mds->mds_quota))
+ if (unlikely(!mds->mds_quota || obd->obd_stopping))
RETURN(rc);
- mutex_down(&lov->lov_lock);
- if (lov->desc.ld_tgt_count != lov->desc.ld_active_tgt_count) {
- CWARN("Not all osts are active, abort quota recovery\n");
- mutex_up(&lov->lov_lock);
+ mutex_down(&obd->obd_dev_sem);
+ if (mds->mds_lov_desc.ld_active_tgt_count != mds->mds_lov_objid_count) {
+ CWARN("Only %u/%u OSTs are active, abort quota recovery\n",
+ mds->mds_lov_desc.ld_active_tgt_count,
+ mds->mds_lov_objid_count);
+ mutex_up(&obd->obd_dev_sem);
RETURN(rc);
}
- mutex_up(&lov->lov_lock);
+ mutex_up(&obd->obd_dev_sem);
data.obd = obd;
init_completion(&data.comp);