Whamcloud - gitweb
- and the new files
[fs/lustre-release.git] / lustre / ptlrpc / rpc.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (C) 2002 Cluster File Systems, Inc.
5  *
6  *   This file is part of Lustre, http://www.lustre.org.
7  *
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.
11  *
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.
16  *
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.
20  *
21  */
22
23 #define EXPORT_SYMTAB
24
25 #include <linux/config.h>
26 #include <linux/module.h>
27 #include <linux/kernel.h>
28
29 #include <linux/obd_support.h>
30 #include <linux/lustre_net.h>
31
32 ptl_handle_ni_t LUSTRE_NI;
33 static ptl_handle_eq_t req_eq;
34 static int req_initialized = 0;
35
36 /* This seems silly now, but some day we'll have more than one NI */
37 int req_get_peer(__u32 nid, struct lustre_peer *peer)
38 {
39         peer->peer_ni = req_ni;
40         peer->peer_nid = nid;
41
42         return 0;
43 }
44 static int request_callback(ptl_event_t *ev, void *data)
45 {
46         struct ptlrpc_request *rpc = ev->mem_desc.user_ptr;
47
48         ENTRY;
49
50         if (ev->type == PTL_EVENT_SENT) {
51                 kfree(rpc->rq_reqbuf);
52         } else if (ev->type == PTL_EVENT_PUT) {
53                 struct ptlrpc_request *clnt_rpc = rpc->rq_reply_handle;
54
55                 rpc->rq_repbuf = ev->mem_desc.start + ev->offset;
56
57                 wake_up_interruptible(&clnt_rpc->rq_wait_for_rep);
58         }
59
60         EXIT;
61         return 1;
62 }
63
64 int ptl_send_buf(struct ptlrpc_request *request, struct lustre_peer *peer,
65                  int portal)
66 {
67         int rc;
68         ptl_process_id_t remote_id;
69         ptl_handle_md_t md_h;
70
71         request->rq_req_md.start = request->rq_reqbuf;
72         request->rq_req_md.length = request->rq_reqlen;
73         request->rq_req_md.threshold = PTL_MD_THRESH_INF;
74         request->rq_req_md.options = PTL_MD_OP_PUT;
75         request->rq_req_md.user_ptr = request;
76         request->rq_req_md.eventq = PTL_EQ_NONE;
77
78         rc = PtlMDBind(peer->peer_ni, request->rq_req_md, &md_h);
79         if (rc != 0) {
80                 printk(__FUNCTION__ ": PtlMDBind failed: %d\n", rc);
81                 return rc;
82         }
83
84         remote_id.addr_kind = PTL_ADDR_NID;
85         remote_id.nid = peer->peer_nid;
86         remote_id.pid = 0;
87
88         rc = PtlPut(md_h, PTL_NOACK_REQ, remote_id, portal, 0, 0, 0, 0);
89         if (rc != PTL_OK) {
90                 printk(__FUNCTION__ ": PtlPut failed: %d\n", rc);
91                 /* FIXME: tear down md */
92         }
93
94         return rc;
95 }
96
97 int ptl_send_rpc(struct ptlrpc_request *request, struct lustre_peer *peer)
98 {
99         ptl_handle_md_t reply_md_h;
100         ptl_handle_me_t me_h;
101         ptl_process_id_t local_id;
102         int rc;
103
104         ENTRY;
105
106         request->rq_repbuf = kmalloc(request->rq_replen, GFP_KERNEL); 
107         if (!request->rq_repbuf) { 
108                 EXIT;
109                 return -ENOMEM;
110         }
111
112         local_id.addr_kind = PTL_ADDR_GID;
113         local_id.gid = PTL_ID_ANY;
114         local_id.rid = PTL_ID_ANY;
115
116         rc = PtlMEAttach(peer->peer_ni, request->rq_reply_portal, local_id,
117                          0, ~0, PTL_RETAIN, &me_h);
118         if (rc != PTL_OK) {
119                 EXIT;
120                 /* FIXME: tear down EQ, free reqbuf */
121                 return rc;
122         }
123
124         request->rq_reply_md.start = request->rq_repbuf;
125         request->rq_reply_md.length = request->rq_replen;
126         request->rq_reply_md.threshold = PTL_MD_THRESH_INF;
127         request->rq_reply_md.options = PTL_MD_OP_PUT;
128         request->rq_reply_md.user_ptr = request;
129         request->rq_reply_md.eventq = req_eq;
130
131         rc = PtlMDAttach(me_h, request->rq_reply_md, PTL_RETAIN, &reply_md_h);
132         if (rc != PTL_OK) {
133                 EXIT;
134                 return rc;
135         }
136
137         return ptl_send_buf(request, peer, request->rq_req_portal);
138 }
139
140
141 //int req_init_event_queue(struct lustre_peer *peer);
142
143 static int req_init_portals(void)
144 {
145         int rc;
146         rc = PtlEQAlloc(req_ni, 128, request_callback, NULL, &req_eq);
147         if (rc != PTL_OK) {
148                 EXIT;
149                 return rc; /* FIXME: does this portals rc make sense? */
150         }
151
152         return rc;
153 }
154
155 static int __init req_init(void)
156 {
157         return req_init_portals();
158 }
159
160 static void __exit req_exit(void)
161 {
162         if (req_initialized) {
163                 PtlNIFini(req_ni);
164                 inter_module_put(LUSTRE_NAL "_init");
165         }
166 }
167
168 MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
169 MODULE_DESCRIPTION("Lustre Request Processor v1.0");
170 MODULE_LICENSE("GPL"); 
171
172 module_init(req_init);
173 module_exit(req_exit);