int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[],
		    u64 valid, u32 flags)
{
	int type;
	int rc = 0;

        ENTRY;

	if ((valid & (OBD_MD_FLALLQUOTA)) == 0)
		RETURN(0);

	for (type = 0; type < LL_MAXQUOTAS; type++) {
		struct osc_quota_info *oqi;

		if ((valid & md_quota_flag(type)) == 0)
			continue;

		/* lookup the ID in the per-type hash table */
		oqi = cfs_hash_lookup(cli->cl_quota_hash[type], &qid[type]);
		if ((flags & fl_quota_flag(type)) != 0) {
			/* This ID is getting close to its quota limit, let's
			 * switch to sync I/O */
			if (oqi != NULL)
				continue;

			oqi = osc_oqi_alloc(qid[type]);
			if (oqi == NULL) {
				rc = -ENOMEM;
				break;
			}

			rc = cfs_hash_add_unique(cli->cl_quota_hash[type],
						 &qid[type], &oqi->oqi_hash);
			/* race with others? */
			if (rc == -EALREADY) {
				rc = 0;
				OBD_SLAB_FREE_PTR(oqi, osc_quota_kmem);
			}

			CDEBUG(D_QUOTA, "%s: setdq to insert for %s %d (%d)\n",
			       cli_name(cli), qtype_name(type), qid[type], rc);
		} else {
			/* This ID is now off the hook, let's remove it from
			 * the hash table */
			if (oqi == NULL)
				continue;

			oqi = cfs_hash_del_key(cli->cl_quota_hash[type],
					       &qid[type]);
			if (oqi)
				OBD_SLAB_FREE_PTR(oqi, osc_quota_kmem);

			CDEBUG(D_QUOTA, "%s: setdq to remove for %s %d (%p)\n",
			       cli_name(cli), qtype_name(type), qid[type], oqi);
		}
	}

	RETURN(rc);
}
Example #2
0
static struct lustre_qunit_size *
quota_create_lqs(unsigned long long lqs_key, struct lustre_quota_ctxt *qctxt)
{
        struct lustre_qunit_size *lqs = NULL;
        cfs_hash_t *hs = NULL;
        int rc = 0;

        OBD_ALLOC_PTR(lqs);
        if (!lqs)
                GOTO(out, rc = -ENOMEM);

        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;
        lqs->lqs_blk_rec = 0;
        lqs->lqs_id = LQS_KEY_ID(lqs->lqs_key);
        lqs->lqs_flags = LQS_KEY_GRP(lqs->lqs_key) ? LQUOTA_FLAGS_GRP : 0;
        lqs->lqs_bunit_sz = qctxt->lqc_bunit_sz;
        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);

        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;
        }

 out:
        if (rc && lqs)
                OBD_FREE_PTR(lqs);

        if (rc)
                return ERR_PTR(rc);
        else
                return lqs;
}