/* ptlrpc work for writeback in ptlrpcd context */
void *cl_writeback_work;
void *cl_lru_work;
+ struct mutex cl_quota_mutex;
/* hash tables for osc_quota_info */
struct cfs_hash *cl_quota_hash[LL_MAXQUOTAS];
+ /* the xid of the request updating the hash tables */
+ __u64 cl_quota_last_xid;
/* Links to the global list of registered changelog devices */
struct list_head cl_chg_dev_linkage;
};
int osc_quota_setup(struct obd_device *obd);
int osc_quota_cleanup(struct obd_device *obd);
-int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[],
+int osc_quota_setdq(struct client_obd *cli, __u64 xid, const unsigned int qid[],
u64 valid, u32 flags);
int osc_quota_chkdq(struct client_obd *cli, const unsigned int qid[]);
int osc_quotactl(struct obd_device *unused, struct obd_export *exp,
}
}
-int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[],
+int osc_quota_setdq(struct client_obd *cli, __u64 xid, const unsigned int qid[],
u64 valid, u32 flags)
{
int type;
if ((valid & (OBD_MD_FLALLQUOTA)) == 0)
RETURN(0);
+ mutex_lock(&cli->cl_quota_mutex);
+ if (cli->cl_quota_last_xid > xid)
+ GOTO(out_unlock, rc);
+
+ cli->cl_quota_last_xid = xid;
for (type = 0; type < LL_MAXQUOTAS; type++) {
struct osc_quota_info *oqi;
}
}
+out_unlock:
+ mutex_unlock(&cli->cl_quota_mutex);
RETURN(rc);
}
int i, type;
ENTRY;
+ mutex_init(&cli->cl_quota_mutex);
+
for (type = 0; type < LL_MAXQUOTAS; type++) {
cli->cl_quota_hash[type] = cfs_hash_create("QUOTA_HASH",
HASH_QUOTA_CUR_BITS,
CDEBUG(D_QUOTA, "setdq for [%u %u %u] with valid %#llx, flags %x\n",
body->oa.o_uid, body->oa.o_gid, body->oa.o_projid,
body->oa.o_valid, body->oa.o_flags);
- osc_quota_setdq(cli, qid, body->oa.o_valid,
+ osc_quota_setdq(cli, req->rq_xid, qid, body->oa.o_valid,
body->oa.o_flags);
}