Whamcloud - gitweb
- The same changes made to the OST are now working in the MDS
[fs/lustre-release.git] / lustre / ost / ost_handler.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (C) 2001, 2002 Cluster File Systems, Inc.
5  *   Author: Peter J. Braam <braam@clusterfs.com>
6  *   Author: Phil Schwan <phil@clusterfs.com>
7  *
8  *   This file is part of Lustre, http://www.lustre.org.
9  *
10  *   Lustre is free software; you can redistribute it and/or
11  *   modify it under the terms of version 2 of the GNU General Public
12  *   License as published by the Free Software Foundation.
13  *
14  *   Lustre is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *   GNU General Public License for more details.
18  *
19  *   You should have received a copy of the GNU General Public License
20  *   along with Lustre; if not, write to the Free Software
21  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  *  Storage Target Handling functions
24  *  Lustre Object Server Module (OST)
25  *
26  *  This server is single threaded at present (but can easily be multi
27  *  threaded). For testing and management it is treated as an
28  *  obd_device, although it does not export a full OBD method table
29  *  (the requests are coming in over the wire, so object target
30  *  modules do not have a full method table.)
31  */
32
33 #define EXPORT_SYMTAB
34 #define DEBUG_SUBSYSTEM S_OST
35
36 #include <linux/module.h>
37 #include <linux/obd_ost.h>
38 #include <linux/lustre_net.h>
39 #include <linux/lustre_dlm.h>
40
41 static int ost_destroy(struct ptlrpc_request *req)
42 {
43         struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
44         struct ost_body *body;
45         int rc, size = sizeof(*body);
46         ENTRY;
47
48         body = lustre_msg_buf(req->rq_reqmsg, 0);
49
50         rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
51         if (rc)
52                 RETURN(rc);
53
54         req->rq_status = obd_destroy(conn, &body->oa);
55         RETURN(0);
56 }
57
58 static int ost_getattr(struct ptlrpc_request *req)
59 {
60         struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
61         struct ost_body *body, *repbody;
62         int rc, size = sizeof(*body);
63         ENTRY;
64
65         body = lustre_msg_buf(req->rq_reqmsg, 0);
66
67         rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
68         if (rc)
69                 RETURN(rc);
70
71         repbody = lustre_msg_buf(req->rq_repmsg, 0);
72         memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
73         req->rq_status = obd_getattr(conn, &repbody->oa);
74         RETURN(0);
75 }
76
77 static int ost_open(struct ptlrpc_request *req)
78 {
79         struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
80         struct ost_body *body, *repbody;
81         int rc, size = sizeof(*body);
82         ENTRY;
83
84         body = lustre_msg_buf(req->rq_reqmsg, 0);
85
86         rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
87         if (rc)
88                 RETURN(rc);
89
90         repbody = lustre_msg_buf(req->rq_repmsg, 0);
91         memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
92         req->rq_status = obd_open(conn, &repbody->oa);
93         RETURN(0);
94 }
95
96 static int ost_close(struct ptlrpc_request *req)
97 {
98         struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
99         struct ost_body *body, *repbody;
100         int rc, size = sizeof(*body);
101         ENTRY;
102
103         body = lustre_msg_buf(req->rq_reqmsg, 0);
104
105         rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
106         if (rc)
107                 RETURN(rc);
108
109         repbody = lustre_msg_buf(req->rq_repmsg, 0);
110         memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
111         req->rq_status = obd_close(conn, &repbody->oa);
112         RETURN(0);
113 }
114
115 static int ost_create(struct ptlrpc_request *req)
116 {
117         struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
118         struct ost_body *body, *repbody;
119         int rc, size = sizeof(*body);
120         ENTRY;
121
122         body = lustre_msg_buf(req->rq_reqmsg, 0);
123
124         rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
125         if (rc)
126                 RETURN(rc);
127
128         repbody = lustre_msg_buf(req->rq_repmsg, 0);
129         memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
130         req->rq_status = obd_create(conn, &repbody->oa);
131         RETURN(0);
132 }
133
134 static int ost_punch(struct ptlrpc_request *req)
135 {
136         struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
137         struct ost_body *body, *repbody;
138         int rc, size = sizeof(*body);
139         ENTRY;
140
141         body = lustre_msg_buf(req->rq_reqmsg, 0);
142
143         rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
144         if (rc)
145                 RETURN(rc);
146
147         repbody = lustre_msg_buf(req->rq_repmsg, 0);
148         memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
149         req->rq_status = obd_punch(conn, &repbody->oa,
150                                    repbody->oa.o_blocks, repbody->oa.o_size);
151         RETURN(0);
152 }
153
154 static int ost_setattr(struct ptlrpc_request *req)
155 {
156         struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
157         struct ost_body *body, *repbody;
158         int rc, size = sizeof(*body);
159         ENTRY;
160
161         body = lustre_msg_buf(req->rq_reqmsg, 0);
162
163         rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
164         if (rc)
165                 RETURN(rc);
166
167         repbody = lustre_msg_buf(req->rq_repmsg, 0);
168         memcpy(&repbody->oa, &body->oa, sizeof(body->oa));
169         req->rq_status = obd_setattr(conn, &repbody->oa);
170         RETURN(0);
171 }
172
173 static int ost_get_info(struct ptlrpc_request *req)
174 {
175         struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
176         struct ost_body *body;
177         int rc, size[2] = {sizeof(*body)};
178         char *bufs[2] = {NULL, NULL}, *ptr;
179         ENTRY;
180
181         body = lustre_msg_buf(req->rq_reqmsg, 0);
182
183         ptr = lustre_msg_buf(req->rq_reqmsg, 1);
184         if (!ptr)
185                 RETURN(-EINVAL);
186
187         req->rq_status = obd_get_info(conn, req->rq_reqmsg->buflens[1], ptr,
188                                       &(size[1]), (void **)&(bufs[1]));
189
190         rc = lustre_pack_msg(2, size, bufs, &req->rq_replen, &req->rq_repmsg);
191         if (rc)
192                 CERROR("cannot pack reply\n");
193
194         RETURN(rc);
195 }
196
197 static int ost_brw_read(struct ptlrpc_request *req)
198 {
199         struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
200         struct ptlrpc_bulk_desc *desc;
201         void *tmp1, *tmp2, *end2;
202         struct niobuf_remote *remote_nb;
203         struct niobuf_local *local_nb = NULL;
204         struct obd_ioobj *ioo;
205         struct ost_body *body;
206         int rc, cmd, i, j, objcount, niocount, size = sizeof(*body);
207         ENTRY;
208
209         body = lustre_msg_buf(req->rq_reqmsg, 0);
210         tmp1 = lustre_msg_buf(req->rq_reqmsg, 1);
211         tmp2 = lustre_msg_buf(req->rq_reqmsg, 2);
212         end2 = (char *)tmp2 + req->rq_reqmsg->buflens[2];
213         objcount = req->rq_reqmsg->buflens[1] / sizeof(*ioo);
214         niocount = req->rq_reqmsg->buflens[2] / sizeof(*remote_nb);
215         cmd = body->data;
216
217         for (i = 0; i < objcount; i++) {
218                 ost_unpack_ioo(&tmp1, &ioo);
219                 if (tmp2 + ioo->ioo_bufcnt > end2) {
220                         LBUG();
221                         GOTO(out, rc = -EFAULT);
222                 }
223                 for (j = 0; j < ioo->ioo_bufcnt; j++)
224                         ost_unpack_niobuf(&tmp2, &remote_nb);
225         }
226
227         rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
228         if (rc)
229                 RETURN(rc);
230         OBD_ALLOC(local_nb, sizeof(*local_nb) * niocount);
231         if (local_nb == NULL)
232                 RETURN(-ENOMEM);
233
234         /* The unpackers move tmp1 and tmp2, so reset them before using */
235         tmp1 = lustre_msg_buf(req->rq_reqmsg, 1);
236         tmp2 = lustre_msg_buf(req->rq_reqmsg, 2);
237         req->rq_status = obd_preprw(cmd, conn, objcount,
238                                     tmp1, niocount, tmp2, local_nb, NULL);
239
240         if (req->rq_status)
241                 GOTO(out_local, 0);
242
243         desc = ptlrpc_prep_bulk(req->rq_connection);
244         if (desc == NULL)
245                 GOTO(out_local, rc = -ENOMEM);
246         desc->b_portal = OST_BULK_PORTAL;
247
248         for (i = 0; i < niocount; i++) {
249                 struct ptlrpc_bulk_page *bulk;
250                 bulk = ptlrpc_prep_bulk_page(desc);
251                 if (bulk == NULL)
252                         GOTO(out_bulk, rc = -ENOMEM);
253                 remote_nb = &(((struct niobuf_remote *)tmp2)[i]);
254                 bulk->b_xid = remote_nb->xid;
255                 bulk->b_buf = (void *)(unsigned long)local_nb[i].addr;
256                 bulk->b_buflen = PAGE_SIZE;
257         }
258
259         rc = ptlrpc_send_bulk(desc);
260         if (rc)
261                 GOTO(out_bulk, rc);
262
263         wait_event_interruptible(desc->b_waitq, ptlrpc_check_bulk_sent(desc));
264         if (desc->b_flags & PTL_RPC_FL_INTR)
265                 rc = -EINTR;
266
267         /* The unpackers move tmp1 and tmp2, so reset them before using */
268         tmp1 = lustre_msg_buf(req->rq_reqmsg, 1);
269         tmp2 = lustre_msg_buf(req->rq_reqmsg, 2);
270         req->rq_status = obd_commitrw(cmd, conn, objcount,
271                                       tmp1, niocount, local_nb, NULL);
272
273 out_bulk:
274         ptlrpc_free_bulk(desc);
275 out_local:
276         OBD_FREE(local_nb, sizeof(*local_nb) * niocount);
277 out:
278         if (rc)
279                 ptlrpc_error(req->rq_svc, req);
280         else
281                 ptlrpc_reply(req->rq_svc, req);
282         RETURN(rc);
283 }
284
285 static int ost_brw_write(struct ptlrpc_request *req)
286 {
287         struct obd_conn *conn = (struct obd_conn *)req->rq_reqmsg;
288         struct ptlrpc_bulk_desc *desc;
289         struct niobuf_remote *remote_nb;
290         struct niobuf_local *local_nb, *lnb;
291         struct obd_ioobj *ioo;
292         struct ost_body *body;
293         int cmd, rc, i, j, objcount, niocount, size[2] = {sizeof(*body)};
294         void *tmp1, *tmp2, *end2;
295         void *desc_priv = NULL;
296         int reply_sent = 0;
297         ENTRY;
298
299         body = lustre_msg_buf(req->rq_reqmsg, 0);
300         tmp1 = lustre_msg_buf(req->rq_reqmsg, 1);
301         tmp2 = lustre_msg_buf(req->rq_reqmsg, 2);
302         end2 = (char *)tmp2 + req->rq_reqmsg->buflens[2];
303         objcount = req->rq_reqmsg->buflens[1] / sizeof(*ioo);
304         niocount = req->rq_reqmsg->buflens[2] / sizeof(*remote_nb);
305         cmd = body->data;
306
307         for (i = 0; i < objcount; i++) {
308                 ost_unpack_ioo((void *)&tmp1, &ioo);
309                 if (tmp2 + ioo->ioo_bufcnt > end2) {
310                         rc = -EFAULT;
311                         break;
312                 }
313                 for (j = 0; j < ioo->ioo_bufcnt; j++)
314                         ost_unpack_niobuf((void *)&tmp2, &remote_nb);
315         }
316
317         size[1] = niocount * sizeof(*remote_nb);
318         rc = lustre_pack_msg(2, size, NULL, &req->rq_replen, &req->rq_repmsg);
319         if (rc)
320                 GOTO(out, rc);
321         remote_nb = lustre_msg_buf(req->rq_repmsg, 1);
322
323         OBD_ALLOC(local_nb, niocount * sizeof(*local_nb));
324         if (local_nb == NULL)
325                 GOTO(out, rc = -ENOMEM);
326
327         /* The unpackers move tmp1 and tmp2, so reset them before using */
328         tmp1 = lustre_msg_buf(req->rq_reqmsg, 1);
329         tmp2 = lustre_msg_buf(req->rq_reqmsg, 2);
330         req->rq_status = obd_preprw(cmd, conn, objcount,
331                                     tmp1, niocount, tmp2, local_nb, &desc_priv);
332         if (req->rq_status)
333                 GOTO(out_free, rc = 0); /* XXX is this correct? */
334
335         desc = ptlrpc_prep_bulk(req->rq_connection);
336         if (desc == NULL)
337                 GOTO(fail_preprw, rc = -ENOMEM);
338         desc->b_cb = NULL;
339         desc->b_portal = OSC_BULK_PORTAL;
340         desc->b_desc_private = desc_priv;
341         memcpy(&(desc->b_conn), &conn, sizeof(conn));
342
343         for (i = 0, lnb = local_nb; i < niocount; i++, lnb++) {
344                 struct ptlrpc_service *srv = req->rq_obd->u.ost.ost_service;
345                 struct ptlrpc_bulk_page *bulk;
346
347                 bulk = ptlrpc_prep_bulk_page(desc);
348                 if (bulk == NULL)
349                         GOTO(fail_bulk, rc = -ENOMEM);
350
351                 spin_lock(&srv->srv_lock);
352                 bulk->b_xid = srv->srv_xid++;
353                 spin_unlock(&srv->srv_lock);
354
355                 bulk->b_buf = lnb->addr;
356                 bulk->b_page = lnb->page;
357                 bulk->b_flags = lnb->flags;
358                 bulk->b_dentry = lnb->dentry;
359                 bulk->b_buflen = PAGE_SIZE;
360                 bulk->b_cb = NULL;
361
362                 /* this advances remote_nb */
363                 ost_pack_niobuf((void **)&remote_nb, lnb->offset, lnb->len, 0,
364                                 bulk->b_xid);
365         }
366
367         rc = ptlrpc_register_bulk(desc);
368         if (rc)
369                 GOTO(fail_bulk, rc);
370
371         reply_sent = 1;
372         ptlrpc_reply(req->rq_svc, req);
373
374         wait_event_interruptible(desc->b_waitq,
375                                  desc->b_flags & PTL_BULK_FL_RCVD);
376
377         rc = obd_commitrw(cmd, conn, objcount, tmp1, niocount, local_nb,
378                           desc->b_desc_private);
379         ptlrpc_free_bulk(desc);
380         EXIT;
381 out_free:
382         OBD_FREE(local_nb, niocount * sizeof(*local_nb));
383 out:
384         if (!reply_sent) {
385                 if (rc)
386                         ptlrpc_error(req->rq_svc, req);
387                 else
388                         ptlrpc_reply(req->rq_svc, req);
389         }
390         return rc;
391
392 fail_bulk:
393         ptlrpc_free_bulk(desc);
394 fail_preprw:
395         /* FIXME: how do we undo the preprw? */
396         goto out_free;
397 }
398
399 static int ost_brw(struct ptlrpc_request *req)
400 {
401         struct ost_body *body = lustre_msg_buf(req->rq_reqmsg, 0);
402
403         if (body->data & OBD_BRW_WRITE)
404                 return ost_brw_write(req);
405         else
406                 return ost_brw_read(req);
407 }
408
409
410 static int ost_handle(struct ptlrpc_request *req)
411 {
412         int rc;
413         ENTRY;
414
415         rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen);
416         if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_HANDLE_UNPACK)) {
417                 CERROR("lustre_mds: Invalid request\n");
418                 GOTO(out, rc);
419         }
420
421         if (req->rq_reqmsg->type != PTL_RPC_MSG_REQUEST) {
422                 CERROR("lustre_mds: wrong packet type sent %d\n",
423                        req->rq_reqmsg->type);
424                 GOTO(out, rc = -EINVAL);
425         }
426
427         if (req->rq_reqmsg->opc != OST_CONNECT &&
428             req->rq_export == NULL)
429                 GOTO(out, rc = -ENOTCONN);
430
431         if (strcmp(req->rq_obd->obd_type->typ_name, "ost") != 0)
432                 GOTO(out, rc = -EINVAL);
433
434         switch (req->rq_reqmsg->opc) {
435         case OST_CONNECT:
436                 CDEBUG(D_INODE, "connect\n");
437                 OBD_FAIL_RETURN(OBD_FAIL_OST_CONNECT_NET, 0);
438                 rc = target_handle_connect(req);
439                 break;
440         case OST_DISCONNECT:
441                 CDEBUG(D_INODE, "disconnect\n");
442                 OBD_FAIL_RETURN(OBD_FAIL_OST_DISCONNECT_NET, 0);
443                 rc = target_handle_disconnect(req);
444                 break;
445         case OST_GET_INFO:
446                 CDEBUG(D_INODE, "get_info\n");
447                 OBD_FAIL_RETURN(OBD_FAIL_OST_GET_INFO_NET, 0);
448                 rc = ost_get_info(req);
449                 break;
450         case OST_CREATE:
451                 CDEBUG(D_INODE, "create\n");
452                 OBD_FAIL_RETURN(OBD_FAIL_OST_CREATE_NET, 0);
453                 rc = ost_create(req);
454                 break;
455         case OST_DESTROY:
456                 CDEBUG(D_INODE, "destroy\n");
457                 OBD_FAIL_RETURN(OBD_FAIL_OST_DESTROY_NET, 0);
458                 rc = ost_destroy(req);
459                 break;
460         case OST_GETATTR:
461                 CDEBUG(D_INODE, "getattr\n");
462                 OBD_FAIL_RETURN(OBD_FAIL_OST_GETATTR_NET, 0);
463                 rc = ost_getattr(req);
464                 break;
465         case OST_SETATTR:
466                 CDEBUG(D_INODE, "setattr\n");
467                 OBD_FAIL_RETURN(OBD_FAIL_OST_SETATTR_NET, 0);
468                 rc = ost_setattr(req);
469                 break;
470         case OST_OPEN:
471                 CDEBUG(D_INODE, "setattr\n");
472                 OBD_FAIL_RETURN(OBD_FAIL_OST_OPEN_NET, 0);
473                 rc = ost_open(req);
474                 break;
475         case OST_CLOSE:
476                 CDEBUG(D_INODE, "setattr\n");
477                 OBD_FAIL_RETURN(OBD_FAIL_OST_CLOSE_NET, 0);
478                 rc = ost_close(req);
479                 break;
480         case OST_BRW:
481                 CDEBUG(D_INODE, "brw\n");
482                 OBD_FAIL_RETURN(OBD_FAIL_OST_BRW_NET, 0);
483                 rc = ost_brw(req);
484                 /* ost_brw sends its own replies */
485                 RETURN(rc);
486         case OST_PUNCH:
487                 CDEBUG(D_INODE, "punch\n");
488                 OBD_FAIL_RETURN(OBD_FAIL_OST_PUNCH_NET, 0);
489                 rc = ost_punch(req);
490                 break;
491 #if 0
492         case OST_STATFS:
493                 CDEBUG(D_INODE, "statfs\n");
494                 OBD_FAIL_RETURN(OBD_FAIL_OST_STATFS_NET, 0);
495                 rc = ost_statfs(req);
496                 break;
497 #endif
498         default:
499                 req->rq_status = -ENOTSUPP;
500                 rc = ptlrpc_error(req->rq_svc, req);
501                 RETURN(rc);
502         }
503
504         EXIT;
505 out:
506         //req->rq_status = rc;
507         if (rc) {
508                 CERROR("ost: processing error %d\n", rc);
509                 ptlrpc_error(req->rq_svc, req);
510         } else {
511                 CDEBUG(D_INODE, "sending reply\n");
512                 ptlrpc_reply(req->rq_svc, req);
513         }
514
515         return 0;
516 }
517
518 #define OST_NUM_THREADS 6
519
520 /* mount the file system (secretly) */
521 static int ost_setup(struct obd_device *obddev, obd_count len, void *buf)
522 {
523         struct obd_ioctl_data* data = buf;
524         struct ost_obd *ost = &obddev->u.ost;
525         struct obd_device *tgt;
526         int err;
527         int i;
528         ENTRY;
529
530         if (data->ioc_dev < 0 || data->ioc_dev > MAX_OBD_DEVICES)
531                 RETURN(-ENODEV);
532
533         MOD_INC_USE_COUNT;
534         tgt = &obd_dev[data->ioc_dev];
535         if (!(tgt->obd_flags & OBD_ATTACHED) ||
536             !(tgt->obd_flags & OBD_SET_UP)) {
537                 CERROR("device not attached or not set up (%d)\n",
538                        data->ioc_dev);
539                 GOTO(error_dec, err = -EINVAL);
540         }
541
542         err = obd_connect(&ost->ost_conn, tgt);
543         if (err) {
544                 CERROR("fail to connect to device %d\n", data->ioc_dev);
545                 GOTO(error_dec, err = -EINVAL);
546         }
547
548         obddev->obd_namespace =
549                 ldlm_namespace_new("ost", LDLM_NAMESPACE_SERVER);
550         if (obddev->obd_namespace == NULL)
551                 LBUG();
552
553         ost->ost_service = ptlrpc_init_svc(64 * 1024, OST_REQUEST_PORTAL,
554                                            OSC_REPLY_PORTAL, "self",ost_handle);
555         if (!ost->ost_service) {
556                 CERROR("failed to start service\n");
557                 GOTO(error_disc, err = -EINVAL);
558         }
559
560         for (i = 0; i < OST_NUM_THREADS; i++) {
561                 err = ptlrpc_start_thread(obddev, ost->ost_service,
562                                           "lustre_ost");
563                 if (err) {
564                         CERROR("error starting thread #%d: rc %d\n", i, err);
565                         GOTO(error_disc, err = -EINVAL);
566                 }
567         }
568
569         RETURN(0);
570
571 error_disc:
572         obd_disconnect(&ost->ost_conn);
573 error_dec:
574         MOD_DEC_USE_COUNT;
575         RETURN(err);
576 }
577
578 static int ost_cleanup(struct obd_device * obddev)
579 {
580         struct ost_obd *ost = &obddev->u.ost;
581         int err;
582
583         ENTRY;
584
585         if ( !list_empty(&obddev->obd_exports) ) {
586                 CERROR("still has clients!\n");
587                 RETURN(-EBUSY);
588         }
589
590         ptlrpc_stop_all_threads(ost->ost_service);
591         ptlrpc_unregister_service(ost->ost_service);
592
593         err = obd_disconnect(&ost->ost_conn);
594         if (err) {
595                 CERROR("lustre ost: fail to disconnect device\n");
596                 RETURN(-EINVAL);
597         }
598
599         ldlm_namespace_free(obddev->obd_namespace);
600
601         MOD_DEC_USE_COUNT;
602         RETURN(0);
603 }
604
605 /* use obd ops to offer management infrastructure */
606 static struct obd_ops ost_obd_ops = {
607         o_setup:       ost_setup,
608         o_cleanup:     ost_cleanup,
609 };
610
611 static int __init ost_init(void)
612 {
613         obd_register_type(&ost_obd_ops, LUSTRE_OST_NAME);
614         return 0;
615 }
616
617 static void __exit ost_exit(void)
618 {
619         obd_unregister_type(LUSTRE_OST_NAME);
620 }
621
622 MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
623 MODULE_DESCRIPTION("Lustre Object Storage Target (OST) v0.01");
624 MODULE_LICENSE("GPL");
625
626 module_init(ost_init);
627 module_exit(ost_exit);