Whamcloud - gitweb
LU-6888 osp: check return value in osp_update_request_create()
[fs/lustre-release.git] / lustre / osp / osp_trans.c
index 368bec5..91964e7 100644 (file)
@@ -77,6 +77,7 @@ struct osp_update_args {
        atomic_t                 *oaua_count;
        wait_queue_head_t        *oaua_waitq;
        bool                      oaua_flow_control;
+       const struct lu_env      *oaua_update_env;
 };
 
 /**
@@ -186,6 +187,7 @@ osp_current_object_update_request(struct osp_update_request *our)
 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)
@@ -196,7 +198,11 @@ struct osp_update_request *osp_update_request_create(struct dt_device *dt)
        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;
 }
 
@@ -211,7 +217,7 @@ void osp_update_request_destroy(struct osp_update_request *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);
@@ -490,7 +496,6 @@ static void osp_thandle_invalidate_object(const struct lu_env *env,
                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;
@@ -511,13 +516,7 @@ static void osp_thandle_invalidate_object(const struct lu_env *env,
                        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);
                }
        }
@@ -619,6 +618,17 @@ static int osp_update_interpret(const struct lu_env *env,
        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) {
@@ -630,7 +640,7 @@ static int osp_update_interpret(const struct lu_env *env,
        }
 
        /* 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);
@@ -728,6 +738,10 @@ int osp_unplug_async_request(const struct lu_env *env,
                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);
@@ -1106,6 +1120,9 @@ static int osp_send_update_req(const struct lu_env *env,
 
        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) {
@@ -1149,6 +1166,10 @@ static int osp_send_update_req(const struct lu_env *env,
                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);