X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fquota%2Fquota_adjust_qunit.c;h=52eca38ff082e03c6a3a276fd743eeee5dbbf78d;hb=369f9a5c41e35f63787c2c0f077df5f44048c87f;hp=78399729437508024789bd6a09e9eb486ba6f848;hpb=f95393b0d0a59cf3dc2f29cffc35dcc4cc9d7728;p=fs%2Flustre-release.git diff --git a/lustre/quota/quota_adjust_qunit.c b/lustre/quota/quota_adjust_qunit.c index 7839972..52eca38 100644 --- a/lustre/quota/quota_adjust_qunit.c +++ b/lustre/quota/quota_adjust_qunit.c @@ -28,6 +28,8 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2012, Whamcloud, Inc. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -90,20 +92,45 @@ void quota_compute_lqs(struct qunit_data *qdata, struct lustre_qunit_size *lqs, } -static struct lustre_qunit_size * -quota_create_lqs(unsigned long long lqs_key, struct lustre_quota_ctxt *qctxt) +struct lustre_qunit_size *quota_search_lqs(unsigned long long lqs_key, + struct lustre_quota_ctxt *qctxt, + int create) { - struct lustre_qunit_size *lqs = NULL; + struct lustre_qunit_size *lqs; + struct lustre_qunit_size *lqs2; cfs_hash_t *hs = NULL; int rc = 0; + cfs_spin_lock(&qctxt->lqc_lock); + if (qctxt->lqc_valid) { + LASSERT(qctxt->lqc_lqs_hash != NULL); + hs = cfs_hash_getref(qctxt->lqc_lqs_hash); + } + cfs_spin_unlock(&qctxt->lqc_lock); + + if (hs == NULL) { + rc = -EBUSY; + goto out; + } + + /* cfs_hash_lookup will +1 refcount for caller */ + lqs = cfs_hash_lookup(qctxt->lqc_lqs_hash, &lqs_key); + if (lqs != NULL) /* found */ + goto out_put; + + if (!create) + goto out_put; + OBD_ALLOC_PTR(lqs); - if (!lqs) - GOTO(out, rc = -ENOMEM); + if (!lqs) { + rc = -ENOMEM; + goto out_put; + } lqs->lqs_key = lqs_key; cfs_spin_lock_init(&lqs->lqs_lock); + lqs->lqs_bwrite_pending = 0; lqs->lqs_iwrite_pending = 0; lqs->lqs_ino_rec = 0; @@ -114,77 +141,38 @@ quota_create_lqs(unsigned long long lqs_key, struct lustre_quota_ctxt *qctxt) lqs->lqs_iunit_sz = qctxt->lqc_iunit_sz; lqs->lqs_btune_sz = qctxt->lqc_btune_sz; lqs->lqs_itune_sz = qctxt->lqc_itune_sz; - lqs->lqs_ctxt = qctxt; if (qctxt->lqc_handler) { lqs->lqs_last_bshrink = 0; lqs->lqs_last_ishrink = 0; } - lqs_initref(lqs); - cfs_spin_lock(&qctxt->lqc_lock); - if (qctxt->lqc_valid) - hs = cfs_hash_getref(qctxt->lqc_lqs_hash); - cfs_spin_unlock(&qctxt->lqc_lock); + lqs->lqs_ctxt = qctxt; /* must be called before lqs_initref */ + cfs_atomic_set(&lqs->lqs_refcount, 1); /* 1 for caller */ + cfs_atomic_inc(&lqs->lqs_ctxt->lqc_lqs); - if (hs) { - lqs_getref(lqs); - rc = cfs_hash_add_unique(qctxt->lqc_lqs_hash, - &lqs->lqs_key, &lqs->lqs_hash); - if (rc) - lqs_putref(lqs); - cfs_hash_putref(hs); - } else { - rc = -EBUSY; - } + /* lqc_lqs_hash will take +1 refcount on lqs on adding */ + lqs2 = cfs_hash_findadd_unique(qctxt->lqc_lqs_hash, + &lqs->lqs_key, &lqs->lqs_hash); + if (lqs2 == lqs) /* added to hash */ + goto out_put; - out: - if (rc && lqs) - OBD_FREE_PTR(lqs); + create = 0; + lqs_putref(lqs); + lqs = lqs2; - if (rc) + out_put: + cfs_hash_putref(hs); + out: + if (rc != 0) { /* error */ + CERROR("get lqs error(rc: %d)\n", rc); return ERR_PTR(rc); - else - return lqs; -} - -struct lustre_qunit_size *quota_search_lqs(unsigned long long lqs_key, - struct lustre_quota_ctxt *qctxt, - int create) -{ - struct lustre_qunit_size *lqs; - int rc = 0; - - search_lqs: - lqs = cfs_hash_lookup(qctxt->lqc_lqs_hash, &lqs_key); - if (IS_ERR(lqs)) - GOTO(out, rc = PTR_ERR(lqs)); - - if (create && lqs == NULL) { - /* if quota_create_lqs is successful, it will get a - * ref to the lqs. The ref will be released when - * qctxt_cleanup() or quota is nullified */ - lqs = quota_create_lqs(lqs_key, qctxt); - if (IS_ERR(lqs)) - rc = PTR_ERR(lqs); - if (rc == -EALREADY) - GOTO(search_lqs, rc = 0); - /* get a reference for the caller when creating lqs - * successfully */ - if (rc == 0) - lqs_getref(lqs); } - if (lqs && rc == 0) + if (lqs != NULL) { LQS_DEBUG(lqs, "%s\n", (create == 1 ? "create lqs" : "search lqs")); - - out: - if (rc == 0) { - return lqs; - } else { - CERROR("get lqs error(rc: %d)\n", rc); - return ERR_PTR(rc); } + return lqs; } int quota_adjust_slave_lqs(struct quota_adjust_qunit *oqaq, @@ -265,7 +253,8 @@ int quota_adjust_slave_lqs(struct quota_adjust_qunit *oqaq, int filter_quota_adjust_qunit(struct obd_export *exp, struct quota_adjust_qunit *oqaq, - struct lustre_quota_ctxt *qctxt) + struct lustre_quota_ctxt *qctxt, + struct ptlrpc_request_set *rqset) { struct obd_device *obd = exp->exp_obd; unsigned int id[MAXQUOTAS] = { 0, 0 }; @@ -298,74 +287,3 @@ int filter_quota_adjust_qunit(struct obd_export *exp, } #endif /* __KERNEL__ */ #endif - -int client_quota_adjust_qunit(struct obd_export *exp, - struct quota_adjust_qunit *oqaq, - struct lustre_quota_ctxt *qctxt) -{ - struct ptlrpc_request *req; - struct quota_adjust_qunit *oqa; - int rc = 0; - ENTRY; - - /* client don't support this kind of operation, abort it */ - if (!(exp->exp_connect_flags & OBD_CONNECT_CHANGE_QS)) { - CDEBUG(D_QUOTA, "osc: %s don't support change qunit size\n", - exp->exp_obd->obd_name); - RETURN(rc); - } - if (strcmp(exp->exp_obd->obd_type->typ_name, LUSTRE_OSC_NAME)) - RETURN(-EINVAL); - - req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp), - &RQF_OST_QUOTA_ADJUST_QUNIT, - LUSTRE_OST_VERSION, - OST_QUOTA_ADJUST_QUNIT); - if (req == NULL) - RETURN(-ENOMEM); - - oqa = req_capsule_client_get(&req->rq_pill, &RMF_QUOTA_ADJUST_QUNIT); - *oqa = *oqaq; - - ptlrpc_request_set_replen(req); - - rc = ptlrpc_queue_wait(req); - if (rc) - CERROR("%s: %s failed: rc = %d\n", exp->exp_obd->obd_name, - __FUNCTION__, rc); - ptlrpc_req_finished(req); - RETURN (rc); -} - -int lov_quota_adjust_qunit(struct obd_export *exp, - struct quota_adjust_qunit *oqaq, - struct lustre_quota_ctxt *qctxt) -{ - struct obd_device *obd = class_exp2obd(exp); - struct lov_obd *lov = &obd->u.lov; - int i, rc = 0; - ENTRY; - - if (!QAQ_IS_ADJBLK(oqaq)) { - CERROR("bad qaq_flags %x for lov obd.\n", oqaq->qaq_flags); - RETURN(-EFAULT); - } - - for (i = 0; i < lov->desc.ld_tgt_count; i++) { - int err; - - if (!lov->lov_tgts[i]->ltd_active) { - CDEBUG(D_HA, "ost %d is inactive\n", i); - continue; - } - - err = obd_quota_adjust_qunit(lov->lov_tgts[i]->ltd_exp, oqaq, - NULL); - if (err) { - if (lov->lov_tgts[i]->ltd_active && !rc) - rc = err; - continue; - } - } - RETURN(rc); -}