1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002 Cluster File Systems, Inc.
6 * This file is part of Lustre, http://www.lustre.org.
8 * Lustre is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
12 * Lustre is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Lustre; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <linux/config.h>
26 #include <linux/module.h>
27 #include <linux/kernel.h>
29 #define DEBUG_SUBSYSTEM S_RPC
31 #include <linux/obd_support.h>
32 #include <linux/obd_class.h>
33 #include <linux/lustre_net.h>
35 int ptlrpc_enqueue(struct ptlrpc_client *peer,
36 struct ptlrpc_request *req)
38 struct ptlrpc_request *srv_req;
45 OBD_ALLOC(srv_req, sizeof(*srv_req));
51 CDEBUG(0, "peer obd minor %d, incoming req %p, srv_req %p\n",
52 peer->cli_obd->obd_minor, req, srv_req);
54 memset(srv_req, 0, sizeof(*req));
56 /* move the request buffer */
57 srv_req->rq_reqbuf = req->rq_reqbuf;
58 srv_req->rq_reqlen = req->rq_reqlen;
59 srv_req->rq_obd = peer->cli_obd;
61 /* remember where it came from */
62 srv_req->rq_reply_handle = req;
64 list_add(&srv_req->rq_list, &peer->cli_obd->obd_req_list);
65 wake_up(&peer->cli_obd->obd_req_waitq);
69 int ptlrpc_connect_client(int dev, char *uuid,
70 struct ptlrpc_client *cl)
74 memset(cl, 0, sizeof(*cl));
78 /* non networked client */
79 if (dev >= 0 && dev < MAX_OBD_DEVICES) {
80 struct obd_device *obd = &obd_dev[dev];
82 if ((!obd->obd_flags & OBD_ATTACHED) ||
83 (!obd->obd_flags & OBD_SET_UP)) {
84 CERROR("target device %d not att or setup\n", dev);
88 cl->cli_obd = &obd_dev[dev];
93 err = kportal_uuid_to_peer(uuid, &cl->cli_server);
95 CERROR("cannot find peer!");
101 struct ptlrpc_request *ptlrpc_prep_req(struct ptlrpc_client *cl,
102 int opcode, int namelen, char *name,
103 int tgtlen, char *tgt)
105 struct ptlrpc_request *request;
109 OBD_ALLOC(request, sizeof(*request));
111 CERROR("request allocation out of memory\n");
115 memset(request, 0, sizeof(*request));
116 request->rq_xid = cl->cli_xid++;
118 rc = cl->cli_req_pack(name, namelen, tgt, tgtlen,
119 &request->rq_reqhdr, &request->rq_req,
120 &request->rq_reqlen, &request->rq_reqbuf);
122 CERROR("cannot pack request %d\n", rc);
125 request->rq_reqhdr->opc = opcode;
126 request->rq_reqhdr->seqno = request->rq_xid;
132 void ptlrpc_free_req(struct ptlrpc_request *request)
134 OBD_FREE(request, sizeof(*request));
137 int ptlrpc_queue_wait(struct ptlrpc_client *cl, struct ptlrpc_request *req)
141 DECLARE_WAITQUEUE(wait, current);
143 init_waitqueue_head(&req->rq_wait_for_rep);
148 rc = ptlrpc_enqueue(cl, req);
150 /* Remote delivery via portals. */
151 req->rq_req_portal = cl->cli_request_portal;
152 req->rq_reply_portal = cl->cli_reply_portal;
153 rc = ptl_send_rpc(req, &cl->cli_server);
156 CERROR("error %d, opcode %d\n", rc,
157 req->rq_reqhdr->opc);
161 CDEBUG(0, "-- sleeping\n");
162 add_wait_queue(&req->rq_wait_for_rep, &wait);
163 while (req->rq_repbuf == NULL) {
164 set_current_state(TASK_INTERRUPTIBLE);
166 /* if this process really wants to die, let it go */
167 if (sigismember(&(current->pending.signal), SIGKILL) ||
168 sigismember(&(current->pending.signal), SIGINT))
173 remove_wait_queue(&req->rq_wait_for_rep, &wait);
174 set_current_state(TASK_RUNNING);
175 CDEBUG(0, "-- done\n");
177 if (req->rq_repbuf == NULL) {
178 /* We broke out because of a signal */
183 rc = cl->cli_rep_unpack(req->rq_repbuf, req->rq_replen, &req->rq_rephdr, &req->rq_rep);
185 CERROR("unpack_rep failed: %d\n", rc);
188 CERROR("got rep %lld\n", req->rq_rephdr->seqno);
189 if ( req->rq_rephdr->status == 0 )
190 CDEBUG(0, "--> buf %p len %d status %d\n",
191 req->rq_repbuf, req->rq_replen,
192 req->rq_rephdr->status);