2 * Copryright (C) 2001 Cluster File Systems, Inc.
4 * This code is issued under the GNU General Public License.
5 * See the file COPYING in this distribution
7 * Author Peter Braam <braam@clusterfs.com>
9 * This server is single threaded at present (but can easily be multi
10 * threaded). For testing and management it is treated as an
11 * obd_device, although it does not export a full OBD method table
12 * (the requests are coming in over the wire, so object target
13 * modules do not have a full method table.)
19 #include <linux/config.h>
20 #include <linux/module.h>
21 #include <linux/kernel.h>
23 #include <linux/string.h>
24 #include <linux/stat.h>
25 #include <linux/errno.h>
26 #include <linux/locks.h>
27 #include <linux/unistd.h>
29 #include <asm/system.h>
30 #include <asm/uaccess.h>
33 #include <linux/stat.h>
34 #include <asm/uaccess.h>
35 #include <asm/segment.h>
36 #include <linux/miscdevice.h>
38 #define DEBUG_SUBSYSTEM S_OSC
40 #include <linux/obd_support.h>
41 #include <linux/obd_class.h>
42 #include <linux/lustre_lib.h>
43 #include <linux/lustre_idl.h>
45 extern int ost_queue_req(struct obd_device *, struct ptlrpc_request *);
47 /* FIXME: this belongs in some sort of service struct */
48 static int osc_xid = 1;
50 struct ptlrpc_request *ost_prep_req(int opcode, int buflen1, char *buf1,
51 int buflen2, char *buf2)
53 struct ptlrpc_request *request;
57 OBD_ALLOC(request, sizeof(*request));
59 printk("osc_prep_req: request allocation out of memory\n");
63 memset(request, 0, sizeof(*request));
64 request->rq_xid = osc_xid++;
66 rc = ost_pack_req(buf1, buflen1, buf2, buflen2,
67 &request->rq_reqhdr, &request->rq_req.ost,
68 &request->rq_reqlen, &request->rq_reqbuf);
70 printk("llight request: cannot pack request %d\n", rc);
73 request->rq_reqhdr->opc = opcode;
79 /* XXX: unify with mdc_queue_wait */
80 extern int osc_queue_wait(struct obd_conn *conn, struct ptlrpc_request *req)
82 struct obd_device *client = conn->oc_dev;
83 struct lustre_peer *peer = &conn->oc_dev->u.osc.osc_peer;
88 /* set the connection id */
89 req->rq_req.ost->connid = conn->oc_id;
91 /* XXX fix the race here (wait_for_event?)*/
94 CDEBUG(D_INODE, "\n");
95 rc = ost_queue_req(client, req);
97 /* Remote delivery via portals. */
98 req->rq_req_portal = OST_REQUEST_PORTAL;
99 req->rq_reply_portal = OST_REPLY_PORTAL;
100 rc = ptl_send_rpc(req, peer);
103 printk(__FUNCTION__ ": error %d, opcode %d\n", rc,
104 req->rq_reqhdr->opc);
108 CDEBUG(D_INODE, "tgt at %p, conn id %d, opcode %d request at: %p\n",
109 &conn->oc_dev->u.osc.osc_tgt->u.ost,
110 conn->oc_id, req->rq_reqhdr->opc, req);
112 /* wait for the reply */
113 init_waitqueue_head(&req->rq_wait_for_rep);
114 CDEBUG(D_INODE, "-- sleeping\n");
115 interruptible_sleep_on(&req->rq_wait_for_rep);
116 CDEBUG(D_INODE, "-- done\n");
118 rc = ost_unpack_rep(req->rq_repbuf, req->rq_replen, &req->rq_rephdr,
121 printk(__FUNCTION__ ": mds_unpack_rep failed: %d\n", rc);
125 if ( req->rq_rephdr->status == 0 )
126 CDEBUG(D_INODE, "buf %p len %d status %d\n",
127 req->rq_repbuf, req->rq_replen,
128 req->rq_rephdr->status);
134 static void osc_free_req(struct ptlrpc_request *request)
136 OBD_FREE(request, sizeof(*request));
139 static int osc_connect(struct obd_conn *conn)
141 struct ptlrpc_request *request;
145 request = ost_prep_req(OST_CONNECT, 0, NULL, 0, NULL);
147 printk(__FUNCTION__ ": cannot pack req!\n");
152 sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
154 rc = osc_queue_wait(conn, request);
160 CDEBUG(D_INODE, "received connid %d\n", request->rq_rep.ost->connid);
162 conn->oc_id = request->rq_rep.ost->connid;
164 osc_free_req(request);
169 static int osc_disconnect(struct obd_conn *conn)
171 struct ptlrpc_request *request;
175 request = ost_prep_req(OST_DISCONNECT, 0, NULL, 0, NULL);
177 printk(__FUNCTION__ ": cannot pack req!\n");
182 sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
184 rc = osc_queue_wait(conn, request);
190 osc_free_req(request);
196 static int osc_getattr(struct obd_conn *conn, struct obdo *oa)
198 struct ptlrpc_request *request;
201 request = ost_prep_req(OST_GETATTR, 0, NULL, 0, NULL);
203 printk(__FUNCTION__ ": cannot pack req!\n");
207 memcpy(&request->rq_req.ost->oa, oa, sizeof(*oa));
208 request->rq_req.ost->oa.o_valid = ~0;
210 sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
212 rc = osc_queue_wait(conn, request);
218 CDEBUG(D_INODE, "mode: %o\n", request->rq_rep.ost->oa.o_mode);
220 memcpy(oa, &request->rq_rep.ost->oa, sizeof(*oa));
224 osc_free_req(request);
228 static int osc_setattr(struct obd_conn *conn, struct obdo *oa)
230 struct ptlrpc_request *request;
233 request = ost_prep_req(OST_SETATTR, 0, NULL, 0, NULL);
235 printk(__FUNCTION__ ": cannot pack req!\n");
239 memcpy(&request->rq_req.ost->oa, oa, sizeof(*oa));
241 sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
243 rc = osc_queue_wait(conn, request);
250 osc_free_req(request);
254 static int osc_create(struct obd_conn *conn, struct obdo *oa)
256 struct ptlrpc_request *request;
260 printk(__FUNCTION__ ": oa NULL\n");
262 request = ost_prep_req(OST_CREATE, 0, NULL, 0, NULL);
264 printk("osc_connect: cannot pack req!\n");
268 memcpy(&request->rq_req.ost->oa, oa, sizeof(*oa));
269 request->rq_req.ost->oa.o_valid = ~0;
271 sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
273 rc = osc_queue_wait(conn, request);
278 memcpy(oa, &request->rq_rep.ost->oa, sizeof(*oa));
281 osc_free_req(request);
285 static int osc_destroy(struct obd_conn *conn, struct obdo *oa)
287 struct ptlrpc_request *request;
291 printk(__FUNCTION__ ": oa NULL\n");
293 request = ost_prep_req(OST_DESTROY, 0, NULL, 0, NULL);
295 printk("osc_connect: cannot pack req!\n");
299 memcpy(&request->rq_req.ost->oa, oa, sizeof(*oa));
300 request->rq_req.ost->oa.o_valid = ~0;
302 sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
304 rc = osc_queue_wait(conn, request);
309 memcpy(oa, &request->rq_rep.ost->oa, sizeof(*oa));
312 osc_free_req(request);
317 /* mount the file system (secretly) */
318 static int osc_setup(struct obd_device *obddev, obd_count len,
322 struct obd_ioctl_data* data = buf;
323 struct osc_obd *osc = &obddev->u.osc;
326 if (data->ioc_dev >= 0 && data->ioc_dev < MAX_OBD_DEVICES) {
327 /* This is a local connection */
328 osc->osc_tgt = &obd_dev[data->ioc_dev];
330 printk("OSC: tgt %d ost at %p\n", data->ioc_dev,
331 &osc->osc_tgt->u.ost);
332 if ( ! (osc->osc_tgt->obd_flags & OBD_ATTACHED) ||
333 ! (osc->osc_tgt->obd_flags & OBD_SET_UP) ){
334 printk("device not attached or not set up (%d)\n",
341 /* This is a remote connection using Portals */
343 /* XXX: this should become something like ioc_inlbuf1 */
344 err = kportal_uuid_to_peer("ost", &osc->osc_peer);
346 printk("Cannot find 'ost' peer.\n");
357 void osc_sendpage(struct niobuf *dst, struct niobuf *src)
359 memcpy((char *)(unsigned long)dst->addr,
360 (char *)(unsigned long)src->addr,
366 int osc_brw(int rw, struct obd_conn *conn, obd_count num_oa,
367 struct obdo **oa, obd_count *oa_bufs, struct page **buf,
368 obd_size *count, obd_off *offset, obd_flag *flags)
370 struct ptlrpc_request *request;
372 struct obd_ioobj ioo;
374 int size1, size2 = 0;
378 size1 = num_oa * sizeof(ioo);
379 for (i = 0; i < num_oa; i++) {
380 size2 += oa_bufs[i] * sizeof(src);
383 request = ost_prep_req(OST_BRW, size1, NULL, size2, NULL);
385 printk("osc_connect: cannot pack req!\n");
390 request->rq_req.ost->cmd = rw;
391 ptr1 = ost_req_buf1(request->rq_req.ost);
392 ptr2 = ost_req_buf2(request->rq_req.ost);
393 for (i=0; i < num_oa; i++) {
394 ost_pack_ioo(&ptr1, oa[i], oa_bufs[i]);
395 for (j = 0 ; j < oa_bufs[i] ; j++) {
396 ost_pack_niobuf(&ptr2, kmap(buf[n]), offset[n],
403 sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep) + size2;
405 rc = osc_queue_wait(conn, request);
412 ptr2 = ost_rep_buf2(request->rq_rep.ost);
413 if (request->rq_rep.ost->buflen2 != n * sizeof(struct niobuf)) {
414 printk(__FUNCTION__ ": buffer length wrong\n");
418 if (rw == OBD_BRW_READ)
421 for (i=0; i < num_oa; i++) {
422 for (j = 0 ; j < oa_bufs[i] ; j++) {
424 src.addr = (__u64)(unsigned long)buf[n];
426 ost_unpack_niobuf(&ptr2, &dst);
427 osc_sendpage(dst, &src);
434 if (request->rq_rephdr)
435 OBD_FREE(request->rq_rephdr, request->rq_replen);
437 for (i=0; i < num_oa; i++) {
438 for (j = 0 ; j < oa_bufs[i] ; j++) {
444 osc_free_req(request);
448 static int osc_cleanup(struct obd_device * obddev)
454 struct obd_ops osc_obd_ops = {
456 o_cleanup: osc_cleanup,
457 o_create: osc_create,
458 o_destroy: osc_destroy,
459 o_getattr: osc_getattr,
460 o_setattr: osc_setattr,
461 o_connect: osc_connect,
462 o_disconnect: osc_disconnect,
466 static int __init osc_init(void)
468 obd_register_type(&osc_obd_ops, LUSTRE_OSC_NAME);
472 static void __exit osc_exit(void)
474 obd_unregister_type(LUSTRE_OSC_NAME);
477 MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
478 MODULE_DESCRIPTION("Lustre Object Storage Client (OSC) v1.0");
479 MODULE_LICENSE("GPL");
481 module_init(osc_init);
482 module_exit(osc_exit);