4 * Lustre Object Server Module (OST)
6 * Copyright (C) 2001 Cluster File Systems, Inc.
8 * This code is issued under the GNU General Public License.
9 * See the file COPYING in this distribution
11 * by Peter Braam <braam@clusterfs.com>
13 * This server is single threaded at present (but can easily be multi threaded).
14 * For testing and management it is treated as an obd_device, although it does
15 * not export a full OBD method table (the requests are coming in over the wire,
16 * so object target modules do not have a full method table.)
23 #include <linux/version.h>
24 #include <linux/module.h>
26 #include <linux/stat.h>
27 #include <linux/locks.h>
28 #include <linux/ext2_fs.h>
29 #include <linux/quotaops.h>
30 #include <asm/unistd.h>
31 #include <linux/obd_support.h>
32 #include <linux/obd.h>
33 #include <linux/obd_class.h>
34 #include <linux/lustre_lib.h>
35 #include <linux/lustre_idl.h>
36 #include <linux/lustre_mds.h>
37 #include <linux/obd_class.h>
40 static int ost_queue_req(struct obd_device *obddev, struct ost_request *req)
42 struct ost_request *srv_req;
43 struct ost_obd *ost = &obddev->u.ost;
45 printk("---> OST at %d %p\n", __LINE__, ost);
51 srv_req = kmalloc(sizeof(*srv_req), GFP_KERNEL);
56 memcpy(srv_req, req, sizeof(*req));
57 srv_req->rq_reply_handle = req;
58 srv_req->rq_obd = ost;
59 list_add(&srv_req->rq_list, &ost->ost_reqs);
61 wake_up(&ost->ost_waitq);
66 /* XXX replace with networking code */
67 int ost_reply(struct obd_device *obddev, struct ost_request *req)
69 struct ost_request *clnt_req = req->rq_reply_handle;
73 /* free the request buffer */
74 kfree(req->rq_reqbuf);
75 req->rq_reqbuf = NULL;
77 /* move the reply to the client */
78 clnt_req->rq_replen = req->rq_replen;
79 clnt_req->rq_repbuf = req->rq_repbuf;
80 req->rq_repbuf = NULL;
83 /* free the server request */
85 /* wake up the client */
86 wake_up_interruptible(&clnt_req->rq_wait_for_rep);
91 int ost_error(struct obd_device *obddev, struct ost_request *req)
93 struct ost_rep_hdr *hdr;
96 hdr = kmalloc(sizeof(*hdr), GFP_KERNEL);
102 memset(hdr, 0, sizeof(*hdr));
104 hdr->seqno = req->rq_reqhdr->seqno;
105 hdr->status = req->rq_status;
106 hdr->type = OST_TYPE_ERR;
107 req->rq_repbuf = (char *)hdr;
110 return ost_reply(obddev, req);
113 static int ost_destroy(struct ost_obd *ost, struct ost_request *req)
115 struct obd_conn conn;
120 conn.oc_id = req->rq_req->connid;
121 conn.oc_dev = ost->ost_tgt;
123 rc = ost_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep,
124 &req->rq_replen, &req->rq_repbuf);
126 printk("ost_destroy: cannot pack reply\n");
130 req->rq_rep->result =ost->ost_tgt->obd_type->typ_ops->o_destroy
131 (&conn, &req->rq_req->oa);
137 static int ost_getattr(struct ost_obd *ost, struct ost_request *req)
139 struct obd_conn conn;
144 conn.oc_id = req->rq_req->connid;
145 conn.oc_dev = ost->ost_tgt;
147 rc = ost_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep,
148 &req->rq_replen, &req->rq_repbuf);
150 printk("ost_getattr: cannot pack reply\n");
153 req->rq_rep->oa.o_id = req->rq_req->oa.o_id;
155 req->rq_rep->result =ost->ost_tgt->obd_type->typ_ops->o_getattr
156 (&conn, &req->rq_rep->oa);
162 static int ost_create(struct ost_obd *ost, struct ost_request *req)
164 struct obd_conn conn;
169 conn.oc_id = req->rq_req->connid;
170 conn.oc_dev = ost->ost_tgt;
172 rc = ost_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep,
173 &req->rq_replen, &req->rq_repbuf);
175 printk("ost_create: cannot pack reply\n");
179 memcpy(&req->rq_rep->oa, &req->rq_req->oa, sizeof(req->rq_req->oa));
181 req->rq_rep->result =ost->ost_tgt->obd_type->typ_ops->o_create
182 (&conn, &req->rq_rep->oa);
189 static int ost_setattr(struct ost_obd *ost, struct ost_request *req)
191 struct obd_conn conn;
196 conn.oc_id = req->rq_req->connid;
197 conn.oc_dev = ost->ost_tgt;
199 rc = ost_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep,
200 &req->rq_replen, &req->rq_repbuf);
202 printk("ost_setattr: cannot pack reply\n");
206 memcpy(&req->rq_rep->oa, &req->rq_req->oa, sizeof(req->rq_req->oa));
208 req->rq_rep->result =ost->ost_tgt->obd_type->typ_ops->o_setattr
209 (&conn, &req->rq_rep->oa);
215 static int ost_connect(struct ost_obd *ost, struct ost_request *req)
217 struct obd_conn conn;
222 conn.oc_dev = ost->ost_tgt;
224 rc = ost_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep,
225 &req->rq_replen, &req->rq_repbuf);
227 printk("ost_setattr: cannot pack reply\n");
231 req->rq_rep->result =ost->ost_tgt->obd_type->typ_ops->o_connect(&conn);
232 req->rq_rep->connid = conn.oc_id;
239 static int ost_disconnect(struct ost_obd *ost, struct ost_request *req)
241 struct obd_conn conn;
246 conn.oc_dev = ost->ost_tgt;
247 conn.oc_id = req->rq_req->connid;
249 rc = ost_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep,
250 &req->rq_replen, &req->rq_repbuf);
252 printk("ost_setattr: cannot pack reply\n");
256 req->rq_rep->result =ost->ost_tgt->obd_type->typ_ops->o_disconnect(&conn);
262 static int ost_get_info(struct ost_obd *ost, struct ost_request *req)
264 struct obd_conn conn;
271 conn.oc_id = req->rq_req->connid;
272 conn.oc_dev = ost->ost_tgt;
274 req->rq_rep->result =ost->ost_tgt->obd_type->typ_ops->o_get_info
275 (&conn, req->rq_req->buflen1, req->rq_req->buf1, &vallen, &val);
278 rc = ost_pack_rep(val, vallen, NULL, 0, &req->rq_rephdr, &req->rq_rep,
279 &req->rq_replen, &req->rq_repbuf);
281 printk("ost_setattr: cannot pack reply\n");
291 //int ost_handle(struct ost_conn *conn, int len, char *buf)
292 int ost_handle(struct obd_device *obddev, struct ost_request *req)
295 struct ost_obd *ost = &obddev->u.ost;
296 struct ost_req_hdr *hdr;
300 hdr = (struct ost_req_hdr *)req->rq_reqbuf;
302 if (NTOH__u32(hdr->type) != OST_TYPE_REQ) {
303 printk("lustre_ost: wrong packet type sent %d\n",
304 NTOH__u32(hdr->type));
309 rc = ost_unpack_req(req->rq_reqbuf, req->rq_reqlen,
310 &req->rq_reqhdr, &req->rq_req);
312 printk("lustre_ost: Invalid request\n");
317 switch (req->rq_reqhdr->opc) {
320 CDEBUG(D_INODE, "connect\n");
321 rc = ost_connect(ost, req);
324 CDEBUG(D_INODE, "disconnect\n");
325 rc = ost_disconnect(ost, req);
328 CDEBUG(D_INODE, "get_info\n");
329 rc = ost_get_info(ost, req);
332 CDEBUG(D_INODE, "create\n");
333 rc = ost_create(ost, req);
336 CDEBUG(D_INODE, "destroy\n");
337 rc = ost_destroy(ost, req);
340 CDEBUG(D_INODE, "getattr\n");
341 rc = ost_getattr(ost, req);
344 CDEBUG(D_INODE, "setattr\n");
345 rc = ost_setattr(ost, req);
349 return ost_error(obddev, req);
354 printk("ost: processing error %d\n", rc);
355 ost_error(obddev, req);
357 CDEBUG(D_INODE, "sending reply\n");
358 ost_reply(obddev, req);
364 int ost_main(void *arg)
366 struct obd_device *obddev = (struct obd_device *) arg;
367 struct ost_obd *ost = &obddev->u.ost;
369 printk("---> %d\n", __LINE__);
373 printk("---> %d\n", __LINE__);
375 printk("---> %d\n", __LINE__);
376 spin_lock_irq(¤t->sigmask_lock);
377 printk("---> %d\n", __LINE__);
378 sigfillset(¤t->blocked);
379 printk("---> %d\n", __LINE__);
380 recalc_sigpending(current);
381 printk("---> %d\n", __LINE__);
382 spin_unlock_irq(¤t->sigmask_lock);
383 printk("---> %d\n", __LINE__);
385 printk("---> %d\n", __LINE__);
386 sprintf(current->comm, "lustre_ost");
387 printk("---> %d\n", __LINE__);
389 /* Record that the thread is running */
390 ost->ost_thread = current;
391 printk("---> %d\n", __LINE__);
392 wake_up(&ost->ost_done_waitq);
393 printk("---> %d\n", __LINE__);
395 /* XXX maintain a list of all managed devices: insert here */
397 /* And now, wait forever for commit wakeup events. */
399 struct ost_request *request;
402 if (ost->ost_flags & OST_EXIT)
406 wake_up(&ost->ost_done_waitq);
407 interruptible_sleep_on(&ost->ost_waitq);
409 CDEBUG(D_INODE, "lustre_ost wakes\n");
410 CDEBUG(D_INODE, "pick up req here and continue\n");
412 if (list_empty(&ost->ost_reqs)) {
413 CDEBUG(D_INODE, "woke because of timer\n");
415 printk("---> %d\n", __LINE__);
416 request = list_entry(ost->ost_reqs.next,
417 struct ost_request, rq_list);
418 printk("---> %d\n", __LINE__);
419 list_del(&request->rq_list);
420 rc = ost_handle(obddev, request);
424 /* XXX maintain a list of all managed devices: cleanup here */
425 printk("---> %d\n", __LINE__);
426 ost->ost_thread = NULL;
427 printk("---> %d\n", __LINE__);
428 wake_up(&ost->ost_done_waitq);
429 printk("lustre_ost: exiting\n");
433 static void ost_stop_srv_thread(struct ost_obd *ost)
435 ost->ost_flags |= OST_EXIT;
437 while (ost->ost_thread) {
438 wake_up(&ost->ost_waitq);
439 sleep_on(&ost->ost_done_waitq);
443 static void ost_start_srv_thread(struct obd_device *obd)
445 struct ost_obd *ost = &obd->u.ost;
448 init_waitqueue_head(&ost->ost_waitq);
449 printk("---> %d\n", __LINE__);
450 init_waitqueue_head(&ost->ost_done_waitq);
451 printk("---> %d\n", __LINE__);
452 kernel_thread(ost_main, (void *)obd,
453 CLONE_VM | CLONE_FS | CLONE_FILES);
454 printk("---> %d\n", __LINE__);
455 while (!ost->ost_thread)
456 sleep_on(&ost->ost_done_waitq);
457 printk("---> %d\n", __LINE__);
461 /* mount the file system (secretly) */
462 static int ost_setup(struct obd_device *obddev, obd_count len,
466 struct obd_ioctl_data* data = buf;
467 struct ost_obd *ost = &obddev->u.ost;
468 struct obd_device *tgt;
472 if (data->ioc_dev < 0 || data->ioc_dev > MAX_OBD_DEVICES) {
477 tgt = &obd_dev[data->ioc_dev];
479 if ( ! (tgt->obd_flags & OBD_ATTACHED) ||
480 ! (tgt->obd_flags & OBD_SET_UP) ){
481 printk("device not attached or not set up (%d)\n",
487 ost->ost_conn.oc_dev = tgt;
488 err = tgt->obd_type->typ_ops->o_connect(&ost->ost_conn);
490 printk("lustre ost: fail to connect to device %d\n",
495 printk("---> OST at %d %p\n", __LINE__, ost);
496 INIT_LIST_HEAD(&ost->ost_reqs);
497 ost->ost_thread = NULL;
500 printk("---> %d\n", __LINE__);
501 spin_lock_init(&obddev->u.ost.fo_lock);
503 printk("---> %d\n", __LINE__);
504 ost_start_srv_thread(obddev);
505 printk("---> %d\n", __LINE__);
512 static int ost_cleanup(struct obd_device * obddev)
514 struct ost_obd *ost = &obddev->u.ost;
515 struct obd_device *tgt;
520 if ( !(obddev->obd_flags & OBD_SET_UP) ) {
525 if ( !list_empty(&obddev->obd_gen_clients) ) {
526 printk(KERN_WARNING __FUNCTION__ ": still has clients!\n");
531 ost_stop_srv_thread(ost);
533 if (!list_empty(&ost->ost_reqs)) {
534 // XXX reply with errors and clean up
535 CDEBUG(D_INODE, "Request list not empty!\n");
539 err = tgt->obd_type->typ_ops->o_disconnect(&ost->ost_conn);
541 printk("lustre ost: fail to disconnect device\n");
551 /* use obd ops to offer management infrastructure */
552 static struct obd_ops ost_obd_ops = {
554 o_cleanup: ost_cleanup,
557 static int __init ost_init(void)
559 obd_register_type(&ost_obd_ops, LUSTRE_OST_NAME);
563 static void __exit ost_exit(void)
565 obd_unregister_type(LUSTRE_OST_NAME);
568 MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
569 MODULE_DESCRIPTION("Lustre Object Storage Target (OST) v0.01");
570 MODULE_LICENSE("GPL");
572 // for testing (maybe this stays)
573 EXPORT_SYMBOL(ost_queue_req);
575 module_init(ost_init);
576 module_exit(ost_exit);