@@ -344,8 +344,11 @@ struct client_obd {
/* 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 rhashtable cl_quota_hash[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;
};
@@ -136,7 +136,7 @@ static inline char *cli_name(struct client_obd *cli)
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[],
u32 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,
@@ -109,7 +109,7 @@ static inline u32 fl_quota_flag(int qtype)
}
}
-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[],
u32 valid, u32 flags)
{
int type;
@@ -118,6 +118,11 @@ int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[],
if ((valid & (OBD_MD_FLALLQUOTA)) == 0)
return 0;
+ mutex_lock(&cli->cl_quota_mutex);
+ if (cli->cl_quota_last_xid > xid)
+ goto out_unlock;
+
+ cli->cl_quota_last_xid = xid;
for (type = 0; type < MAXQUOTAS; type++) {
struct osc_quota_info *oqi;
@@ -175,6 +180,8 @@ int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[],
}
}
+out_unlock:
+ mutex_unlock(&cli->cl_quota_mutex);
return rc;
}
@@ -191,6 +198,8 @@ int osc_quota_setup(struct obd_device *obd)
struct client_obd *cli = &obd->u.cli;
int i, type;
+ mutex_init(&cli->cl_quota_mutex);
+
for (type = 0; type < MAXQUOTAS; type++) {
if (rhashtable_init(&cli->cl_quota_hash[type],
"a_hash_params) != 0)
@@ -1753,7 +1753,8 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc)
"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, body->oa.o_flags);
+ osc_quota_setdq(cli, req->rq_xid, qid, body->oa.o_valid,
+ body->oa.o_flags);
}
osc_update_grant(cli, body);