Whamcloud - gitweb
- new xml format, generated by lmc
[fs/lustre-release.git] / lustre / ptlrpc / client.c
index 2f8c1f4..983b071 100644 (file)
@@ -23,6 +23,7 @@
 #define DEBUG_SUBSYSTEM S_RPC
 
 #include <linux/obd_support.h>
+#include <linux/obd_class.h>
 #include <linux/lustre_lib.h>
 #include <linux/lustre_ha.h>
 
@@ -89,17 +90,19 @@ void ptlrpc_readdress_connection(struct ptlrpc_connection *conn, char *uuid)
 
 struct ptlrpc_bulk_desc *ptlrpc_prep_bulk(struct ptlrpc_connection *conn)
 {
-        struct ptlrpc_bulk_desc *bulk;
+        struct ptlrpc_bulk_desc *desc;
 
-        OBD_ALLOC(bulk, sizeof(*bulk));
-        if (bulk != NULL) {
-                bulk->b_connection = ptlrpc_connection_addref(conn);
-                atomic_set(&bulk->b_pages_remaining, 0);
-                init_waitqueue_head(&bulk->b_waitq);
-                INIT_LIST_HEAD(&bulk->b_page_list);
+        OBD_ALLOC(desc, sizeof(*desc));
+        if (desc != NULL) {
+                desc->b_connection = ptlrpc_connection_addref(conn);
+                atomic_set(&desc->b_refcount, 1);
+                init_waitqueue_head(&desc->b_waitq);
+                INIT_LIST_HEAD(&desc->b_page_list);
+                ptl_set_inv_handle(&desc->b_md_h);
+                ptl_set_inv_handle(&desc->b_me_h);
         }
 
-        return bulk;
+        return desc;
 }
 
 struct ptlrpc_bulk_page *ptlrpc_prep_bulk_page(struct ptlrpc_bulk_desc *desc)
@@ -109,11 +112,8 @@ struct ptlrpc_bulk_page *ptlrpc_prep_bulk_page(struct ptlrpc_bulk_desc *desc)
         OBD_ALLOC(bulk, sizeof(*bulk));
         if (bulk != NULL) {
                 bulk->b_desc = desc;
-                ptl_set_inv_handle(&bulk->b_md_h);
-                ptl_set_inv_handle(&bulk->b_me_h);
                 list_add_tail(&bulk->b_link, &desc->b_page_list);
                 desc->b_page_count++;
-                atomic_inc(&desc->b_pages_remaining);
         }
         return bulk;
 }
@@ -197,15 +197,25 @@ struct ptlrpc_request *ptlrpc_prep_req(struct ptlrpc_client *cl,
 
         RETURN(request);
 }
-struct ptlrpc_request *ptlrpc_prep_req2(struct ptlrpc_client *cl,
-                                        struct ptlrpc_connection *conn,
-                                        struct lustre_handle *handle, 
+struct ptlrpc_request *ptlrpc_prep_req2(struct lustre_handle *conn, 
                                        int opcode, int count, int *lengths,
                                        char **bufs)
 {
+        struct client_obd *clobd; 
         struct ptlrpc_request *req;
-        req = ptlrpc_prep_req(cl, conn, opcode, count, lengths, bufs);
-        ptlrpc_hdl2req(req, handle);
+        struct obd_export *export;
+
+        export = class_conn2export(conn);
+        if (!export) { 
+                LBUG();
+                CERROR("NOT connected\n"); 
+                return NULL;
+        }
+
+        clobd = &export->exp_obd->u.cli;
+        req = ptlrpc_prep_req(clobd->cl_client, clobd->cl_conn, 
+                              opcode, count, lengths, bufs);
+        ptlrpc_hdl2req(req, &clobd->cl_exporth);
         return req;
 }
 
@@ -260,6 +270,11 @@ static int ptlrpc_check_reply(struct ptlrpc_request *req)
         }
 
         if (req->rq_flags & PTL_RPC_FL_RESEND) { 
+                if (l_killable_pending(current)) {
+                        CERROR("-- INTR --\n");
+                        req->rq_flags |= PTL_RPC_FL_INTR;
+                        GOTO(out, rc = 1);
+                }
                 CERROR("-- RESEND --\n");
                 GOTO(out, rc = 1);
         }
@@ -269,8 +284,13 @@ static int ptlrpc_check_reply(struct ptlrpc_request *req)
                 GOTO(out, rc = 1);
         }
 
+        if (req->rq_flags & PTL_RPC_FL_TIMEOUT && l_killable_pending(current)) {
+                req->rq_flags |= PTL_RPC_FL_INTR;
+                GOTO(out, rc = 1);
+        }
 
-        if (CURRENT_TIME - req->rq_time >= req->rq_timeout) {
+        if (req->rq_timeout &&
+            (CURRENT_TIME - req->rq_time >= req->rq_timeout)) {
                 CERROR("-- REQ TIMEOUT ON CONNID %d XID %Ld --\n",
                        req->rq_connid, (unsigned long long)req->rq_xid);
                 /* clear the timeout */
@@ -279,22 +299,17 @@ static int ptlrpc_check_reply(struct ptlrpc_request *req)
                 req->rq_flags |= PTL_RPC_FL_TIMEOUT;
                 if (req->rq_client && req->rq_client->cli_recovd)
                         recovd_cli_fail(req->rq_client);
-                if (req->rq_level < LUSTRE_CONN_FULL)
+                if (req->rq_level < LUSTRE_CONN_FULL) {
                         rc = 1;
-                else
+                } else if (l_killable_pending(current)) {
+                        req->rq_flags |= PTL_RPC_FL_INTR;
+                        rc = 1;
+                } else {
                         rc = 0;
+                }
                 GOTO(out, rc);
         }
 
-        if (req->rq_timeout) { 
-                schedule_timeout(req->rq_timeout * HZ);
-        }
-
-        if (l_killable_pending(current)) {
-                req->rq_flags |= PTL_RPC_FL_INTR;
-                GOTO(out, rc = 1);
-        }
-
  out:
         CDEBUG(D_NET, "req = %p, rc = %d\n", req, rc);
         return rc;
@@ -458,7 +473,7 @@ void ptlrpc_restart_req(struct ptlrpc_request *req)
 
 int ptlrpc_queue_wait(struct ptlrpc_request *req)
 {
-        int rc = 0;
+        int rc = 0, timeout;
         struct ptlrpc_client *cli = req->rq_client;
         ENTRY;
 
@@ -502,7 +517,13 @@ int ptlrpc_queue_wait(struct ptlrpc_request *req)
         spin_unlock(&cli->cli_lock);
 
         CDEBUG(D_OTHER, "-- sleeping\n");
-        l_wait_event_killable(req->rq_wait_for_rep, ptlrpc_check_reply(req));
+        /*
+         * req->rq_timeout gets reset in the timeout case, and
+         * l_wait_event_timeout is a macro, so save the timeout value here.
+         */
+        timeout = req->rq_timeout * HZ;
+        l_wait_event_timeout(req->rq_wait_for_rep, ptlrpc_check_reply(req),
+                             timeout);
         CDEBUG(D_OTHER, "-- done\n");
 
         if (req->rq_flags & PTL_RPC_FL_RESEND) {
@@ -511,15 +532,15 @@ int ptlrpc_queue_wait(struct ptlrpc_request *req)
         }
 
         up(&cli->cli_rpc_sem);
-        if (req->rq_flags & PTL_RPC_FL_TIMEOUT)
-                GOTO(out, rc = -ETIMEDOUT);
-
         if (req->rq_flags & PTL_RPC_FL_INTR) {
                 /* Clean up the dangling reply buffers */
                 ptlrpc_abort(req);
                 GOTO(out, rc = -EINTR);
         }
 
+        if (req->rq_flags & PTL_RPC_FL_TIMEOUT)
+                GOTO(out, rc = -ETIMEDOUT);
+
         if (!(req->rq_flags & PTL_RPC_FL_REPLIED))
                 GOTO(out, rc = req->rq_status);