atomic_t *oaua_count;
wait_queue_head_t *oaua_waitq;
bool oaua_flow_control;
+ const struct lu_env *oaua_update_env;
};
/**
struct osp_update_request *osp_update_request_create(struct dt_device *dt)
{
struct osp_update_request *our;
+ int rc;
OBD_ALLOC_PTR(our);
if (our == NULL)
INIT_LIST_HEAD(&our->our_list);
spin_lock_init(&our->our_list_lock);
- osp_object_update_request_create(our, OUT_UPDATE_INIT_BUFFER_SIZE);
+ rc = osp_object_update_request_create(our, OUT_UPDATE_INIT_BUFFER_SIZE);
+ if (rc != 0) {
+ OBD_FREE_PTR(our);
+ return ERR_PTR(rc);
+ }
return our;
}
list_for_each_entry_safe(ours, tmp, &our->our_req_list, ours_list) {
list_del(&ours->ours_list);
if (ours->ours_req != NULL)
- OBD_FREE(ours->ours_req, ours->ours_req_size);
+ OBD_FREE_LARGE(ours->ours_req, ours->ours_req_size);
OBD_FREE_PTR(ours);
}
OBD_FREE_PTR(our);
struct object_update_request *our_req = ours->ours_req;
unsigned int i;
struct lu_object *obj;
- struct osp_object *osp_obj;
for (i = 0; i < our_req->ourq_count; i++) {
struct object_update *update;
if (IS_ERR(obj))
break;
- osp_obj = lu2osp_obj(obj);
- if (osp_obj->opo_ooa != NULL) {
- spin_lock(&osp_obj->opo_lock);
- osp_obj->opo_ooa->ooa_attr.la_valid = 0;
- osp_obj->opo_stale = 1;
- spin_unlock(&osp_obj->opo_lock);
- }
+ osp_invalidate(env, lu2dt_obj(obj));
lu_object_put(env, obj);
}
}
if (our == NULL)
RETURN(0);
+ /* Sigh env might be NULL in some cases, see
+ * this calling path.
+ * osp_send_update_thread()
+ * ptlrpc_set_wait() ----> null env.
+ * ptlrpc_check_set()
+ * osp_update_interpret()
+ * Let's use env in oaua for this case.
+ */
+ if (env == NULL)
+ env = oaua->oaua_update_env;
+
oaua->oaua_update = NULL;
oth = our->our_th;
if (oaua->oaua_flow_control) {
}
/* Unpack the results from the reply message. */
- if (req->rq_repmsg != NULL) {
+ if (req->rq_repmsg != NULL && req->rq_replied) {
reply = req_capsule_server_sized_get(&req->rq_pill,
&RMF_OUT_UPDATE_REPLY,
OUT_UPDATE_REPLY_SIZE);
args->oaua_update = our;
args->oaua_count = NULL;
args->oaua_waitq = NULL;
+ /* Note: this is asynchronous call for the request, so the
+ * interrupte cb and current function will be different
+ * thread, so we need use different env */
+ args->oaua_update_env = NULL;
args->oaua_flow_control = false;
req->rq_interpret_reply = osp_update_interpret;
ptlrpcd_add_req(req);
args = ptlrpc_req_async_args(req);
args->oaua_update = our;
+ /* set env to NULL, in case the interrupt cb and current function
+ * are in different thread */
+ args->oaua_update_env = NULL;
osp_thandle_get(oth); /* hold for update interpret */
req->rq_interpret_reply = osp_update_interpret;
if (!oth->ot_super.th_wait_submit && !oth->ot_super.th_sync) {
if (top_device->ld_obd->obd_recovering)
req->rq_allow_replay = 1;
+ /* Because this req will be synchronus, i.e. it will be called
+ * in the same thread, so it will be safe to use current
+ * env */
+ args->oaua_update_env = env;
if (osp->opd_connect_mdt)
osp_get_rpc_lock(osp);
rc = ptlrpc_queue_wait(req);