unsigned long default_iunit_sz = 5000; /* 5000 inodes */
unsigned long default_itune_ratio = 50; /* 50 percentage */
-kmem_cache_t *qunit_cachep = NULL;
+cfs_mem_cache_t *qunit_cachep = NULL;
struct list_head qunit_hash[NR_DQHASH];
spinlock_t qunit_hash_lock = SPIN_LOCK_UNLOCKED;
ENTRY;
LASSERT(imp);
- if (imp->imp_connect_data.ocd_connect_flags & OBD_CONNECT_QUOTA64)
+ if ((imp->imp_connect_data.ocd_connect_flags & OBD_CONNECT_QUOTA64) &&
+ !OBD_FAIL_CHECK(OBD_FAIL_QUOTA_QD_COUNT_32BIT))
RETURN(0);
else
RETURN(1);
spin_unlock(&qunit_hash_lock);
if (qunit_cachep) {
-#ifdef HAVE_KMEM_CACHE_DESTROY_INT
int rc;
- rc = kmem_cache_destroy(qunit_cachep);
+ rc = cfs_mem_cache_destroy(qunit_cachep);
LASSERTF(rc == 0, "couldn't destory qunit_cache slab\n");
-#else
- kmem_cache_destroy(qunit_cachep);
-#endif
qunit_cachep = NULL;
}
EXIT;
ENTRY;
LASSERT(qunit_cachep == NULL);
- qunit_cachep = kmem_cache_create("ll_qunit_cache",
+ qunit_cachep = cfs_mem_cache_create("ll_qunit_cache",
sizeof(struct lustre_qunit),
- 0, 0, NULL, NULL);
+ 0, 0);
if (!qunit_cachep)
RETURN(-ENOMEM);
return tmp;
}
+/* compute the remaining quota for certain gid or uid b=11693 */
+int compute_remquota(struct obd_device *obd,
+ struct lustre_quota_ctxt *qctxt, struct qunit_data *qdata)
+{
+ struct super_block *sb = qctxt->lqc_sb;
+ __u64 usage, limit;
+ struct obd_quotactl *qctl;
+ int ret = QUOTA_RET_OK;
+ __u32 qdata_type = qdata->qd_flags & QUOTA_IS_GRP;
+ ENTRY;
+
+ if (!sb_any_quota_enabled(sb))
+ RETURN(QUOTA_RET_NOQUOTA);
+
+ /* ignore root user */
+ if (qdata->qd_id == 0 && qdata_type == USRQUOTA)
+ RETURN(QUOTA_RET_NOLIMIT);
+
+ OBD_ALLOC_PTR(qctl);
+ if (qctl == NULL)
+ RETURN(-ENOMEM);
+
+ /* get fs quota usage & limit */
+ qctl->qc_cmd = Q_GETQUOTA;
+ qctl->qc_id = qdata->qd_id;
+ qctl->qc_type = qdata_type;
+ ret = fsfilt_quotactl(obd, sb, qctl);
+ if (ret) {
+ if (ret == -ESRCH) /* no limit */
+ ret = QUOTA_RET_NOLIMIT;
+ else
+ CDEBUG(D_QUOTA, "can't get fs quota usage! (rc:%d)",
+ ret);
+ GOTO(out, ret);
+ }
+
+ usage = qctl->qc_dqblk.dqb_curspace;
+ limit = qctl->qc_dqblk.dqb_bhardlimit << QUOTABLOCK_BITS;
+ if (!limit){ /* no limit */
+ ret = QUOTA_RET_NOLIMIT;
+ GOTO(out, ret);
+ }
+
+ if (limit >= usage)
+ qdata->qd_count = limit - usage;
+ else
+ qdata->qd_count = 0;
+ EXIT;
+out:
+ OBD_FREE_PTR(qctl);
+ return ret;
+}
+
/* caller must hold qunit_hash_lock */
static inline struct lustre_qunit *find_qunit(unsigned int hashent,
struct lustre_quota_ctxt *qctxt,
struct lustre_qunit *qunit = NULL;
ENTRY;
- OBD_SLAB_ALLOC(qunit, qunit_cachep, SLAB_NOFS, sizeof(*qunit));
+ OBD_SLAB_ALLOC(qunit, qunit_cachep, CFS_ALLOC_IO, sizeof(*qunit));
if (qunit == NULL)
RETURN(NULL);
/* FIXME check if this mds is the master of specified id */
-static int
-is_master(struct obd_device *obd, struct lustre_quota_ctxt *qctxt,
+static int
+is_master(struct obd_device *obd, struct lustre_quota_ctxt *qctxt,
unsigned int id, int type)
{
return qctxt->lqc_handler ? 1 : 0;
}
-static int
+static int
schedule_dqacq(struct obd_device *obd, struct lustre_quota_ctxt *qctxt,
struct qunit_data *qdata, int opc, int wait);
qdata = lustre_quota_old_to_new(qdata_old);
}
if (qdata == NULL) {
- DEBUG_REQ(D_ERROR, req, "error unpacking qunit_data\n");
+ DEBUG_REQ(D_ERROR, req, "error unpacking qunit_data");
RETURN(-EPROTO);
}
if ((empty = alloc_qunit(qctxt, qdata, opc)) == NULL)
RETURN(-ENOMEM);
-
+
spin_lock(&qunit_hash_lock);
qunit = dqacq_in_flight(qctxt, qdata);
if (qunit) {
- if (wait)
+ if (wait)
list_add_tail(&qw.qw_entry, &qunit->lq_waiters);
spin_unlock(&qunit_hash_lock);
-
+
free_qunit(empty);
goto wait_completion;
- }
+ }
qunit = empty;
insert_qunit_nolock(qctxt, qunit);
if (wait)
LASSERT(!should_translate_quota(qctxt->lqc_import) ||
qdata->qd_count <= MAX_QUOTA_COUNT32);
- if (should_translate_quota(qctxt->lqc_import) ||
- OBD_FAIL_CHECK(OBD_FAIL_QUOTA_QD_COUNT_32BIT))
+ if (should_translate_quota(qctxt->lqc_import))
{
struct qunit_data_old *reqdata_old, *tmp;
req->rq_interpret_reply = dqacq_interpret;
ptlrpcd_add_req(req);
- QDATA_DEBUG(qdata, "%s scheduled.\n",
+ QDATA_DEBUG(qdata, "%s scheduled.\n",
opc == QUOTA_DQACQ ? "DQACQ" : "DQREL");
wait_completion:
if (wait && qunit) {
RETURN(rc);
}
-int
+int
qctxt_wait_pending_dqacq(struct lustre_quota_ctxt *qctxt, unsigned int id,
unsigned short type, int isblk)
{
remove_qunit_nolock(qunit);
/* wake up all waiters */
- list_for_each_entry_safe(qw, tmp2, &qunit->lq_waiters,
+ list_for_each_entry_safe(qw, tmp2, &qunit->lq_waiters,
qw_entry) {
list_del_init(&qw->qw_entry);
qw->qw_rc = 0;
struct qslave_recov_thread_data *data = arg;
struct obd_device *obd = data->obd;
struct lustre_quota_ctxt *qctxt = data->qctxt;
- unsigned int type;
+ unsigned int type;
int rc = 0;
ENTRY;
rc = 0;
if (rc)
- CDEBUG(rc == -EBUSY ? D_QUOTA : D_ERROR,
+ CDEBUG(rc == -EBUSY ? D_QUOTA : D_ERROR,
"qslave recovery failed! (id:%d type:%d "
" rc:%d)\n", dqid->di_id, type, rc);
free:
RETURN(rc);
}
-void
+void
qslave_start_recovery(struct obd_device *obd, struct lustre_quota_ctxt *qctxt)
{
struct qslave_recov_thread_data data;