From 2c237557ab6b23dffe7253a9b2d9d5a24024e11b Mon Sep 17 00:00:00 2001 From: fanyong Date: Tue, 3 Feb 2009 02:34:54 +0000 Subject: [PATCH] Branch b1_6 b=18135 i=tianzy i=andrew.perepechko Wake up all wait threads on the "lq_waitq" when "lqc_import" is invalid. --- lustre/obdfilter/filter.c | 2 ++ lustre/quota/quota_context.c | 37 ++++++++++++++++++++++++++++++++++--- lustre/quota/quota_interface.c | 8 ++++---- lustre/quota/quota_internal.h | 1 + 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index 4d923a6..e325b6a 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -2453,6 +2453,8 @@ static int filter_disconnect(struct obd_export *exp) filter_grant_sanity_check(obd, __FUNCTION__); filter_grant_discard(exp); + lquota_clearinfo(filter_quota_interface_ref, exp, exp->exp_obd); + /* Disconnect early so that clients can't keep using export */ rc = class_disconnect(exp); if (exp->exp_obd->obd_namespace != NULL) diff --git a/lustre/quota/quota_context.c b/lustre/quota/quota_context.c index a7bb435..677d8f1 100644 --- a/lustre/quota/quota_context.c +++ b/lustre/quota/quota_context.c @@ -816,25 +816,56 @@ int check_qm(struct lustre_quota_ctxt *qctxt) RETURN(rc); } +/* wake up all waiting threads when lqc_import is NULL */ +void dqacq_interrupt(struct lustre_quota_ctxt *qctxt) +{ + struct lustre_qunit *qunit, *tmp; + int i; + ENTRY; + + spin_lock(&qunit_hash_lock); + for (i = 0; i < NR_DQHASH; i++) { + list_for_each_entry_safe(qunit, tmp, &qunit_hash[i], lq_hash) { + if (qunit->lq_ctxt != qctxt) + continue; + + /* Wake up all waiters. Do not change lq_state. + * The waiters will check lq_rc which is kept as 0 + * if no others change it, then the waiters will return + * -EAGAIN to caller who can perform related quota + * acq/rel if necessary. */ + wake_up_all(&qunit->lq_waitq); + } + } + spin_unlock(&qunit_hash_lock); + EXIT; +} + static int got_qunit(struct lustre_qunit *qunit) { - int rc; + struct lustre_quota_ctxt *qctxt = qunit->lq_ctxt; + int rc = 0; ENTRY; spin_lock(&qunit->lq_lock); switch (qunit->lq_state) { case QUNIT_IN_HASH: case QUNIT_RM_FROM_HASH: - rc = 0; break; case QUNIT_FINISHED: rc = 1; break; default: - rc = 0; CERROR("invalid qunit state %d\n", qunit->lq_state); } spin_unlock(&qunit->lq_lock); + + if (!rc) { + spin_lock(&qctxt->lqc_lock); + rc = !qctxt->lqc_import || !qctxt->lqc_valid; + spin_unlock(&qctxt->lqc_lock); + } + RETURN(rc); } diff --git a/lustre/quota/quota_interface.c b/lustre/quota/quota_interface.c index 7aa638c..0cc9814 100644 --- a/lustre/quota/quota_interface.c +++ b/lustre/quota/quota_interface.c @@ -130,18 +130,18 @@ static int filter_quota_clearinfo(struct obd_export *exp, struct obd_device *obd /* lquota may be not set up before destroying export, b=14896 */ if (!obd->obd_set_up) - return 0; + RETURN(0); /* when exp->exp_imp_reverse is destroyed, the corresponding lqc_import * should be invalid b=12374 */ - if (qctxt->lqc_import == exp->exp_imp_reverse) { + if (qctxt->lqc_import && qctxt->lqc_import == exp->exp_imp_reverse) { spin_lock(&qctxt->lqc_lock); qctxt->lqc_import = NULL; + spin_unlock(&qctxt->lqc_lock); + dqacq_interrupt(qctxt); CDEBUG(D_QUOTA, "%s: lqc_import of obd(%p) is invalid now.\n", obd->obd_name, obd); - spin_unlock(&qctxt->lqc_lock); } - RETURN(0); } diff --git a/lustre/quota/quota_internal.h b/lustre/quota/quota_internal.h index b4a7acc..65e89b0 100644 --- a/lustre/quota/quota_internal.h +++ b/lustre/quota/quota_internal.h @@ -114,6 +114,7 @@ int compute_remquota(struct obd_device *obd, struct lustre_quota_ctxt *qctxt, struct qunit_data *qdata, int isblk); int check_qm(struct lustre_quota_ctxt *qctxt); +void dqacq_interrupt(struct lustre_quota_ctxt *qctxt); /* quota_master.c */ int lustre_dquot_init(void); void lustre_dquot_exit(void); -- 1.8.3.1