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).
20 #include <linux/version.h>
21 #include <linux/module.h>
23 #include <linux/stat.h>
24 #include <linux/locks.h>
25 #include <linux/ext2_fs.h>
26 #include <linux/quotaops.h>
27 #include <asm/unistd.h>
28 #include <linux/obd_support.h>
29 #include <linux/obd.h>
30 #include <linux/obd_class.h>
31 #include <linux/lustre_lib.h>
32 #include <linux/lustre_idl.h>
33 #include <linux/lustre_mds.h>
34 #include <linux/obd_class.h>
38 static struct ost_obd *OST;
41 static int ost_queue_req(struct ost_request *req)
49 list_add(&req->rq_list, &OST->ost_reqs);
50 init_waitqueue_head(&req->rq_wait_for_ost_rep);
52 wake_up(&OST->ost_waitq);
53 printk("-- sleeping\n");
54 interruptible_sleep_on(&req->rq_wait_for_ost_rep);
59 int ost_reply(struct ost_request *req)
62 kfree(req->rq_reqbuf);
63 req->rq_reqbuf = NULL;
64 wake_up_interruptible(&req->rq_wait_for_ost_rep);
69 int ost_error(struct ost_request *req)
71 struct ost_rep_hdr *hdr;
74 hdr = kmalloc(sizeof(*hdr), GFP_KERNEL);
80 memset(hdr, 0, sizeof(*hdr));
82 hdr->seqno = req->rq_reqhdr->seqno;
83 hdr->status = req->rq_status;
84 hdr->type = OST_TYPE_ERR;
85 req->rq_repbuf = (char *)hdr;
88 return ost_reply(req);
91 static int ost_destroy(struct ost_obd *ost, struct ost_request *req)
98 conn.oc_id = req->rq_req->connid;
99 conn.oc_dev = ost->ost_tgt;
101 rc = ost_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep,
102 &req->rq_reqlen, &req->rq_reqbuf);
104 printk("ost_destroy: cannot pack reply\n");
108 req->rq_rep->result =ost->ost_tgt->obd_type->typ_ops->o_destroy
109 (&conn, &req->rq_req->oa);
115 static int ost_getattr(struct ost_obd *ost, struct ost_request *req)
117 struct obd_conn conn;
122 conn.oc_id = req->rq_req->connid;
123 conn.oc_dev = ost->ost_tgt;
125 rc = ost_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep,
126 &req->rq_reqlen, &req->rq_reqbuf);
128 printk("ost_getattr: cannot pack reply\n");
131 req->rq_rep->oa.o_id = req->rq_req->oa.o_id;
133 req->rq_rep->result =ost->ost_tgt->obd_type->typ_ops->o_getattr
134 (&conn, &req->rq_rep->oa);
140 static int ost_create(struct ost_obd *ost, struct ost_request *req)
142 struct obd_conn conn;
147 conn.oc_id = req->rq_req->connid;
148 conn.oc_dev = ost->ost_tgt;
150 rc = ost_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep,
151 &req->rq_reqlen, &req->rq_reqbuf);
153 printk("ost_create: cannot pack reply\n");
157 memcpy(&req->rq_rep->oa, &req->rq_req->oa, sizeof(req->rq_req->oa));
159 req->rq_rep->result =ost->ost_tgt->obd_type->typ_ops->o_create
160 (&conn, &req->rq_rep->oa);
167 static int ost_setattr(struct ost_obd *ost, struct ost_request *req)
169 struct obd_conn conn;
174 conn.oc_id = req->rq_req->connid;
175 conn.oc_dev = ost->ost_tgt;
177 rc = ost_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep,
178 &req->rq_reqlen, &req->rq_reqbuf);
180 printk("ost_setattr: cannot pack reply\n");
184 memcpy(&req->rq_rep->oa, &req->rq_req->oa, sizeof(req->rq_req->oa));
186 req->rq_rep->result =ost->ost_tgt->obd_type->typ_ops->o_setattr
187 (&conn, &req->rq_rep->oa);
194 //int ost_handle(struct ost_conn *conn, int len, char *buf)
195 int ost_handle(struct ost_obd *ost, struct ost_request *req)
198 struct ost_req_hdr *hdr;
202 hdr = (struct ost_req_hdr *)req->rq_reqbuf;
204 if (NTOH__u32(hdr->type) != OST_TYPE_REQ) {
205 printk("lustre_ost: wrong packet type sent %d\n",
206 NTOH__u32(hdr->type));
211 rc = ost_unpack_req(req->rq_reqbuf, req->rq_reqlen,
212 &req->rq_reqhdr, &req->rq_req);
214 printk("lustre_ost: Invalid request\n");
219 switch (req->rq_reqhdr->opc) {
222 CDEBUG(D_INODE, "create\n");
223 rc = ost_create(ost, req);
226 CDEBUG(D_INODE, "destroy\n");
227 rc = ost_destroy(ost, req);
230 CDEBUG(D_INODE, "getattr\n");
231 rc = ost_getattr(ost, req);
234 CDEBUG(D_INODE, "setattr\n");
235 rc = ost_setattr(ost, req);
239 return ost_error(req);
244 printk("ost: processing error %d\n", rc);
247 CDEBUG(D_INODE, "sending reply\n");
254 int ost_main(void *arg)
256 struct ost_obd *ost = (struct ost_obd *) arg;
260 spin_lock_irq(¤t->sigmask_lock);
261 sigfillset(¤t->blocked);
262 recalc_sigpending(current);
263 spin_unlock_irq(¤t->sigmask_lock);
265 sprintf(current->comm, "lustre_ost");
267 /* Record that the thread is running */
268 ost->ost_thread = current;
269 wake_up(&ost->ost_done_waitq);
271 /* XXX maintain a list of all managed devices: insert here */
273 /* And now, wait forever for commit wakeup events. */
275 struct ost_request *request;
278 if (ost->ost_flags & OST_EXIT)
282 wake_up(&ost->ost_done_waitq);
283 interruptible_sleep_on(&ost->ost_waitq);
285 CDEBUG(D_INODE, "lustre_ost wakes\n");
286 CDEBUG(D_INODE, "pick up req here and continue\n");
288 if (list_empty(&ost->ost_reqs)) {
289 CDEBUG(D_INODE, "woke because of timer\n");
291 request = list_entry(ost->ost_reqs.next,
292 struct ost_request, rq_list);
293 list_del(&request->rq_list);
294 rc = ost_handle(ost, request);
298 /* XXX maintain a list of all managed devices: cleanup here */
300 ost->ost_thread = NULL;
301 wake_up(&ost->ost_done_waitq);
302 printk("lustre_ost: exiting\n");
306 static void ost_stop_srv_thread(struct ost_obd *ost)
308 ost->ost_flags |= OST_EXIT;
310 while (ost->ost_thread) {
311 wake_up(&ost->ost_waitq);
312 sleep_on(&ost->ost_done_waitq);
316 static void ost_start_srv_thread(struct ost_obd *ost)
318 init_waitqueue_head(&ost->ost_waitq);
319 init_waitqueue_head(&ost->ost_done_waitq);
320 kernel_thread(ost_main, (void *)ost,
321 CLONE_VM | CLONE_FS | CLONE_FILES);
322 while (!ost->ost_thread)
323 sleep_on(&ost->ost_done_waitq);
326 /* mount the file system (secretly) */
327 static int ost_setup(struct obd_device *obddev, obd_count len,
331 struct obd_ioctl_data* data = buf;
332 struct ost_obd *ost = &obddev->u.ost;
333 struct obd_device *tgt;
337 if (data->ioc_dev < 0 || data->ioc_dev > MAX_OBD_DEVICES) {
342 tgt = &obd_dev[data->ioc_dev];
344 if ( ! (tgt->obd_flags & OBD_ATTACHED) ||
345 ! (tgt->obd_flags & OBD_SET_UP) ){
346 printk("device not attached or not set up (%d)\n",
352 err = tgt->obd_type->typ_ops->o_connect(&ost->ost_conn);
354 printk("lustre ost: fail to connect to device %d\n",
359 INIT_LIST_HEAD(&ost->ost_reqs);
360 ost->ost_thread = NULL;
364 spin_lock_init(&obddev->u.ost.fo_lock);
366 ost_start_srv_thread(ost);
373 static int ost_cleanup(struct obd_device * obddev)
375 struct ost_obd *ost = &obddev->u.ost;
376 struct obd_device *tgt;
381 if ( !(obddev->obd_flags & OBD_SET_UP) ) {
386 if ( !list_empty(&obddev->obd_gen_clients) ) {
387 printk(KERN_WARNING __FUNCTION__ ": still has clients!\n");
393 ost_stop_srv_thread(ost);
395 if (!list_empty(&ost->ost_reqs)) {
396 // XXX reply with errors and clean up
397 CDEBUG(D_INODE, "Request list not empty!\n");
401 err = tgt->obd_type->typ_ops->o_disconnect(&ost->ost_conn);
403 printk("lustre ost: fail to disconnect device\n");
413 /* use obd ops to offer management infrastructure */
414 static struct obd_ops ost_obd_ops = {
416 o_cleanup: ost_cleanup,
419 static int __init ost_init(void)
421 obd_register_type(&ost_obd_ops, LUSTRE_OST_NAME);
425 static void __exit ost_exit(void)
427 obd_unregister_type(LUSTRE_OST_NAME);
430 MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
431 MODULE_DESCRIPTION("Lustre Object Storage Target (OST) v0.01");
432 MODULE_LICENSE("GPL");
435 // for testing (maybe this stays)
436 EXPORT_SYMBOL(ost_queue_req);
438 module_init(ost_init);
439 module_exit(ost_exit);