Whamcloud - gitweb
LU-7728 osp: soft lockup in osp_precreate_reserve()
[fs/lustre-release.git] / lustre / osp / osp_precreate.c
index b9f6760..fe63a55 100644 (file)
@@ -1239,6 +1239,7 @@ static int osp_precreate_ready_condition(const struct lu_env *env,
        if (d->opd_pre_status != 0 &&
            d->opd_pre_status != -EAGAIN &&
            d->opd_pre_status != -ENODEV &&
+           d->opd_pre_status != -ENOTCONN &&
            d->opd_pre_status != -ENOSPC) {
                /* DEBUG LU-3230 */
                if (d->opd_pre_status != -EIO)
@@ -1482,6 +1483,13 @@ int osp_object_truncate(const struct lu_env *env, struct dt_object *dt,
         * XXX: decide how do we do here with resend
         * if we don't resend, then client may see wrong file size
         * if we do resend, then MDS thread can get stuck for quite long
+        * and if we don't resend, then client will also get -EWOULDBLOCK !!
+        * (see LU-7975 and sanity/test_27F use cases)
+        * but let's decide not to resend/delay this truncate request to OST
+        * and allow Client to decide to resend, in a less agressive way from
+        * after_reply(), by returning -EINPROGRESS instead of
+        * -EAGAIN/-EWOULDBLOCK upon return from ptlrpc_queue_wait() at the
+        * end of this routine
         */
        req->rq_no_resend = req->rq_no_delay = 1;
 
@@ -1509,8 +1517,23 @@ int osp_object_truncate(const struct lu_env *env, struct dt_object *dt,
        ptlrpc_request_set_replen(req);
 
        rc = ptlrpc_queue_wait(req);
-       if (rc)
-               CERROR("can't punch object: %d\n", rc);
+       if (rc) {
+               /* -EWOULDBLOCK/-EAGAIN means OST is unreachable at the moment
+                * since we have decided not to resend/delay, but this could
+                * lead to wrong size to be seen at Client side and even process
+                * trying to open to exit/fail if not itself handling -EAGAIN.
+                * So it should be better to return -EINPROGRESS instead and
+                * leave the decision to resend at Client side in after_reply()
+                */
+               if (rc == -EWOULDBLOCK) {
+                       rc = -EINPROGRESS;
+                       CDEBUG(D_HA, "returning -EINPROGRESS instead of "
+                              "-EWOULDBLOCK/-EAGAIN to allow Client to "
+                              "resend\n");
+               } else {
+                       CERROR("can't punch object: %d\n", rc);
+               }
+       }
 out:
        ptlrpc_req_finished(req);
        if (oa)