From eb515b3e286dd68df8ce5431cb09f9454145f1ba Mon Sep 17 00:00:00 2001 From: fanyong Date: Tue, 3 Feb 2009 02:10:04 +0000 Subject: [PATCH] Branch HEAD 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 | 1 + lustre/quota/quota_internal.h | 1 + 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index 0b7ad33..1341e2b 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -3059,6 +3059,8 @@ static int filter_disconnect(struct obd_export *exp) /* Flush any remaining cancel messages out to the target */ filter_sync_llogs(obd, 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 bb0bbd2..917a162 100644 --- a/lustre/quota/quota_context.c +++ b/lustre/quota/quota_context.c @@ -774,25 +774,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 71bed54..87ee09a 100644 --- a/lustre/quota/quota_interface.c +++ b/lustre/quota/quota_interface.c @@ -137,6 +137,7 @@ static int filter_quota_clearinfo(struct obd_export *exp, struct obd_device *obd 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); } diff --git a/lustre/quota/quota_internal.h b/lustre/quota/quota_internal.h index e9073be..457da1a 100644 --- a/lustre/quota/quota_internal.h +++ b/lustre/quota/quota_internal.h @@ -113,6 +113,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