Whamcloud - gitweb
- Don't shutdown the LDLM if other modules still have namespaces
[fs/lustre-release.git] / lustre / obdclass / class_obd.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  *
6  * This code is issued under the GNU General Public License.
7  * See the file COPYING in this distribution
8  *
9  * These are the only exported functions, they provide some generic
10  * infrastructure for managing object devices
11  *
12  * Object Devices Class Driver
13  */
14
15 #define EXPORT_SYMTAB
16 #include <linux/config.h> /* for CONFIG_PROC_FS */
17 #include <linux/module.h>
18 #include <linux/errno.h>
19 #include <linux/kernel.h>
20 #include <linux/major.h>
21 #include <linux/sched.h>
22 #include <linux/lp.h>
23 #include <linux/slab.h>
24 #include <linux/ioport.h>
25 #include <linux/fcntl.h>
26 #include <linux/delay.h>
27 #include <linux/skbuff.h>
28 #include <linux/proc_fs.h>
29 #include <linux/fs.h>
30 #include <linux/poll.h>
31 #include <linux/init.h>
32 #include <linux/list.h>
33 #include <asm/io.h>
34 #include <asm/system.h>
35 #include <asm/poll.h>
36 #include <asm/uaccess.h>
37 #include <linux/miscdevice.h>
38
39 #define DEBUG_SUBSYSTEM S_CLASS
40
41 #include <linux/obd_support.h>
42 #include <linux/obd_class.h>
43 #include <linux/smp_lock.h>
44
45 struct semaphore obd_conf_sem;   /* serialize configuration commands */
46 struct obd_device obd_dev[MAX_OBD_DEVICES];
47 struct list_head obd_types;
48 unsigned long obd_memory = 0;
49 unsigned long obd_fail_loc = 0;
50
51 extern struct obd_type *class_nm_to_type(char *nm);
52
53 /*  opening /dev/obd */
54 static int obd_class_open(struct inode * inode, struct file * file)
55 {
56         ENTRY;
57
58         file->private_data = NULL;
59         MOD_INC_USE_COUNT;
60         RETURN(0);
61 }
62
63 /*  closing /dev/obd */
64 static int obd_class_release(struct inode * inode, struct file * file)
65 {
66         ENTRY;
67
68         if (file->private_data)
69                 file->private_data = NULL;
70
71         MOD_DEC_USE_COUNT;
72         RETURN(0);
73 }
74
75
76 inline void obd_data2conn(struct lustre_handle *conn, struct obd_ioctl_data *data)
77 {
78         conn->addr = data->ioc_addr;
79         conn->cookie = data->ioc_cookie;
80 }
81
82
83 inline void obd_conn2data(struct obd_ioctl_data *data, struct lustre_handle *conn)
84 {
85         data->ioc_addr = conn->addr;
86         data->ioc_cookie = conn->cookie;
87 }
88
89
90 /* to control /dev/obd */
91 static int obd_class_ioctl (struct inode * inode, struct file * filp,
92                             unsigned int cmd, unsigned long arg)
93 {
94         char *buf = NULL;
95         int len = 0;
96         struct obd_ioctl_data *data;
97         struct obd_device *obd = filp->private_data;
98         struct lustre_handle conn;
99         int rw = OBD_BRW_READ;
100         int err = 0;
101         ENTRY;
102
103         down(&obd_conf_sem);
104
105         if (!obd && cmd != OBD_IOC_DEVICE && cmd != TCGETS &&
106             cmd != OBD_IOC_LIST &&
107             cmd != OBD_IOC_NAME2DEV && cmd != OBD_IOC_NEWDEV) {
108                 CERROR("OBD ioctl: No device\n");
109                 GOTO(out, err=-EINVAL);
110         }
111         if (obd_ioctl_getdata(&buf, &len, (void *)arg)) {
112                 CERROR("OBD ioctl: data error\n");
113                 GOTO(out, err=-EINVAL);
114         }
115         data = (struct obd_ioctl_data *)buf;
116
117         switch (cmd) {
118         case TCGETS:
119                 GOTO(out, err=-EINVAL);
120         case OBD_IOC_DEVICE: {
121                 CDEBUG(D_IOCTL, "\n");
122                 if (data->ioc_dev >= MAX_OBD_DEVICES || data->ioc_dev < 0) {
123                         CERROR("OBD ioctl: DEVICE insufficient devices\n");
124                         GOTO(out, err=-EINVAL);
125                 }
126                 CDEBUG(D_IOCTL, "device %d\n", data->ioc_dev);
127
128                 filp->private_data = &obd_dev[data->ioc_dev];
129                 GOTO(out, err=0);
130         }
131
132         case OBD_IOC_LIST: {
133                 int i;
134                 char *buf2 = data->ioc_bulk;
135                 int remains = data->ioc_inllen1;
136
137                 if (!data->ioc_inlbuf1) {
138                         CERROR("No buffer passed!\n");
139                         GOTO(out, err=-EINVAL);
140                 }
141
142
143                 for (i = 0 ; i < MAX_OBD_DEVICES ; i++) {
144                         int l;
145                         char *status;
146                         struct obd_device *obd = &obd_dev[i];
147                         if (!obd->obd_type)
148                                 continue;
149                         if (obd->obd_flags & OBD_SET_UP)
150                                 status = "*";
151                         else
152                                 status = " ";
153                         l = snprintf(buf2, remains, "%2d %s %s %s %s\n",
154                                      i, status, obd->obd_type->typ_name,
155                                      obd->obd_name, obd->obd_uuid);
156                         buf2 +=l;
157                         remains -=l;
158                         if (remains <= 0) {
159                                 CERROR("not enough space for device listing\n");
160                                 break;
161                         }
162                 }
163
164                 err = copy_to_user((int *)arg, data, len);
165                 GOTO(out, err);
166         }
167
168
169         case OBD_IOC_NAME2DEV: {
170                 /* Resolve a device name.  This does not change the
171                  * currently selected device.
172                  */
173                 int dev;
174
175                 if (!data->ioc_inllen1 || !data->ioc_inlbuf1 ) {
176                         CERROR("No name passed,!\n");
177                         GOTO(out, err=-EINVAL);
178                 }
179                 if (data->ioc_inlbuf1[data->ioc_inllen1-1] !=0) {
180                         CERROR("Name not nul terminated!\n");
181                         GOTO(out, err=-EINVAL);
182                 }
183
184                 CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
185                 dev = class_name2dev(data->ioc_inlbuf1);
186                 data->ioc_dev = dev;
187                 if (dev == -1) {
188                         CDEBUG(D_IOCTL, "No device for name %s!\n",
189                                data->ioc_inlbuf1);
190                         GOTO(out, err=-EINVAL);
191                 }
192
193                 CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
194                        dev);
195                 err = copy_to_user((int *)arg, data, sizeof(*data));
196                 GOTO(out, err);
197         }
198
199         case OBD_IOC_UUID2DEV: {
200                 /* Resolve a device uuid.  This does not change the
201                  * currently selected device.
202                  */
203                 int dev;
204
205                 if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
206                         CERROR("No UUID passed!\n");
207                         GOTO(out, err=-EINVAL);
208                 }
209                 if (data->ioc_inlbuf1[data->ioc_inllen1-1] !=0) {
210                         CERROR("Name not nul terminated!\n");
211                         GOTO(out, err=-EINVAL);
212                 }
213
214                 CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
215                 dev = class_uuid2dev(data->ioc_inlbuf1);
216                 data->ioc_dev = dev;
217                 if (dev == -1) {
218                         CDEBUG(D_IOCTL, "No device for name %s!\n",
219                                data->ioc_inlbuf1);
220                         GOTO(out, err=-EINVAL);
221                 }
222
223                 CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
224                        dev);
225                 err = copy_to_user((int *)arg, data, sizeof(*data));
226                 GOTO(out, err);
227         }
228
229         case OBD_IOC_NEWDEV: {
230                 int dev = -1;
231                 int i;
232
233                 filp->private_data = NULL;
234                 for (i = 0 ; i < MAX_OBD_DEVICES ; i++) {
235                         struct obd_device *obd = &obd_dev[i];
236                         if (!obd->obd_type) {
237                                 filp->private_data = obd;
238                                 dev = i;
239                                 break;
240                         }
241                 }
242
243
244                 data->ioc_dev = dev;
245                 if (dev == -1)
246                         GOTO(out, err=-EINVAL);
247
248                 err = copy_to_user((int *)arg, data, sizeof(*data));
249                 GOTO(out, err);
250         }
251
252         case OBD_IOC_ATTACH: {
253                 struct obd_type *type;
254
255                 /* have we attached a type to this device */
256                 if (obd->obd_flags & OBD_ATTACHED) {
257                         CERROR("OBD: Device %d already typed as %s.\n",
258                                obd->obd_minor, MKSTR(obd->obd_type->typ_name));
259                         GOTO(out, err=-EBUSY);
260                 }
261
262                 if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
263                         CERROR("No type passed!\n");
264                         GOTO(out, err=-EINVAL);
265                 }
266                 if (data->ioc_inlbuf1[data->ioc_inllen1-1] !=0) {
267                         CERROR("Type not nul terminated!\n");
268                         GOTO(out, err=-EINVAL);
269                 }
270
271                 CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
272                        MKSTR(data->ioc_inlbuf1),
273                        MKSTR(data->ioc_inlbuf2), MKSTR(data->ioc_inlbuf3));
274
275                 /* find the type */
276                 type = class_nm_to_type(data->ioc_inlbuf1);
277                 if (!type) {
278                         CERROR("OBD: unknown type dev %d\n", obd->obd_minor);
279                         GOTO(out, err=-EINVAL);
280                 }
281
282                 obd->obd_type = type;
283                 INIT_LIST_HEAD(&obd->obd_exports);
284
285                 /* do the attach */
286                 if (OBT(obd) && OBP(obd, attach))
287                         err = OBP(obd,attach)(obd, sizeof(*data), data);
288                 if (err) {
289                         obd->obd_type = NULL;
290                 } else {
291                         obd->obd_flags |= OBD_ATTACHED;
292                         type->typ_refcnt++;
293                         CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n",
294                                obd->obd_minor, data->ioc_inlbuf1);
295                         if (data->ioc_inlbuf2) {
296                                 int len = strlen(data->ioc_inlbuf2) + 1;
297                                 OBD_ALLOC(obd->obd_name, len);
298                                 if (!obd->obd_name) {
299                                         CERROR("no memory\n");
300                                         LBUG();
301                                 }
302                                 memcpy(obd->obd_name, data->ioc_inlbuf2, len);
303                                 obd->obd_proc_entry =
304                                         proc_lustre_register_obd_device(obd);
305                         } else {
306                                 CERROR("WARNING: unnamed obd device\n");
307                                 obd->obd_proc_entry = NULL;
308                         }
309
310                         if (data->ioc_inlbuf3) {
311                                 int len = strlen(data->ioc_inlbuf3);
312                                 if (len > 37) {
313                                         CERROR("uuid should be shorter than 37 bytes\n");
314                                         if (obd->obd_name)
315                                                 OBD_FREE(obd->obd_name,
316                                                          strlen(obd->obd_name) + 1);
317                                         GOTO(out, err=-EINVAL);
318                                 }
319                                 memcpy(obd->obd_uuid, data->ioc_inlbuf3,
320                                        sizeof(obd->obd_uuid));
321                         }
322
323                         MOD_INC_USE_COUNT;
324                 }
325
326                 GOTO(out, err);
327         }
328
329         case OBD_IOC_DETACH: {
330                 ENTRY;
331                 if (obd->obd_flags & OBD_SET_UP) {
332                         CERROR("OBD device %d still set up\n", obd->obd_minor);
333                         GOTO(out, err=-EBUSY);
334                 }
335                 if (! (obd->obd_flags & OBD_ATTACHED) ) {
336                         CERROR("OBD device %d not attached\n", obd->obd_minor);
337                         GOTO(out, err=-ENODEV);
338                 }
339                 if ( !list_empty(&obd->obd_exports) ) {
340                         CERROR("OBD device %d has exports\n",
341                                obd->obd_minor);
342                         GOTO(out, err=-EBUSY);
343                 }
344
345                 if (obd->obd_name) {
346                         OBD_FREE(obd->obd_name, strlen(obd->obd_name)+1);
347                         obd->obd_name = NULL;
348                 }
349
350                 if (obd->obd_proc_entry)
351                         proc_lustre_release_obd_device(obd);
352
353                 obd->obd_flags &= ~OBD_ATTACHED;
354                 obd->obd_type->typ_refcnt--;
355                 obd->obd_type = NULL;
356                 MOD_DEC_USE_COUNT;
357                 GOTO(out, err=0);
358         }
359
360         case OBD_IOC_SETUP: {
361                 /* have we attached a type to this device? */
362                 if (!(obd->obd_flags & OBD_ATTACHED)) {
363                         CERROR("Device %d not attached\n", obd->obd_minor);
364                         GOTO(out, err=-ENODEV);
365                 }
366
367                 /* has this been done already? */
368                 if ( obd->obd_flags & OBD_SET_UP ) {
369                         CERROR("Device %d already setup (type %s)\n",
370                                obd->obd_minor, obd->obd_type->typ_name);
371                         GOTO(out, err=-EBUSY);
372                 }
373
374                 if ( OBT(obd) && OBP(obd, setup) )
375                         err = obd_setup(obd, sizeof(*data), data);
376
377                 if (!err) {
378                         obd->obd_type->typ_refcnt++;
379                         obd->obd_flags |= OBD_SET_UP;
380                 }
381
382                 GOTO(out, err);
383         }
384         case OBD_IOC_CLEANUP: {
385                 /* have we attached a type to this device? */
386                 if (!(obd->obd_flags & OBD_ATTACHED)) {
387                         CERROR("Device %d not attached\n", obd->obd_minor);
388                         GOTO(out, err=-ENODEV);
389                 }
390
391                 if ( OBT(obd) && OBP(obd, cleanup) )
392                         err = obd_cleanup(obd);
393
394                 if (!err) {
395                         obd->obd_flags &= ~OBD_SET_UP;
396                         obd->obd_type->typ_refcnt--;
397                 }
398                 GOTO(out, err);
399         }
400
401         case OBD_IOC_CONNECT: {
402                 obd_data2conn(&conn, data);
403
404                 err = obd_connect(&conn, obd, NULL);
405
406                 CDEBUG(D_IOCTL, "assigned export %Lx\n", conn.addr);
407                 obd_conn2data(data, &conn);
408                 if (err)
409                         GOTO(out, err);
410
411                 err = copy_to_user((int *)arg, data, sizeof(*data));
412                 GOTO(out, err);
413         }
414
415         case OBD_IOC_DISCONNECT: {
416                 obd_data2conn(&conn, data);
417                 err = obd_disconnect(&conn);
418                 GOTO(out, err);
419         }
420
421         case OBD_IOC_DEC_USE_COUNT: {
422                 MOD_DEC_USE_COUNT;
423                 GOTO(out, err=0);
424         }
425
426         case OBD_IOC_CREATE: {
427                 struct lov_stripe_md *ea;
428                 obd_data2conn(&conn, data);
429
430
431                 err = obd_create(&conn, &data->ioc_obdo1, &ea);
432                 if (err)
433                         GOTO(out, err);
434
435                 err = copy_to_user((int *)arg, data, sizeof(*data));
436                 GOTO(out, err);
437         }
438
439         case OBD_IOC_GETATTR: {
440
441                 obd_data2conn(&conn, data);
442                 err = obd_getattr(&conn, &data->ioc_obdo1, NULL);
443                 if (err)
444                         GOTO(out, err);
445
446                 err = copy_to_user((int *)arg, data, sizeof(*data));
447                 GOTO(out, err);
448         }
449
450         case OBD_IOC_SETATTR: {
451                 obd_data2conn(&conn, data);
452                 err = obd_setattr(&conn, &data->ioc_obdo1, NULL);
453                 if (err)
454                         GOTO(out, err);
455
456                 err = copy_to_user((int *)arg, data, sizeof(*data));
457                 GOTO(out, err);
458         }
459
460         case OBD_IOC_DESTROY: {
461                 //void *ea;
462                 obd_data2conn(&conn, data);
463
464                 err = obd_destroy(&conn, &data->ioc_obdo1, NULL);
465                 if (err)
466                         GOTO(out, err);
467
468                 err = copy_to_user((int *)arg, data, sizeof(*data));
469                 GOTO(out, err);
470         }
471
472         case OBD_IOC_BRW_WRITE:
473                 rw = OBD_BRW_WRITE;
474         case OBD_IOC_BRW_READ: {
475                 struct lov_stripe_md smd;
476                 obd_count       pages = 0;
477                 struct page     **bufs = NULL;
478                 obd_size        *counts = NULL;
479                 obd_off         *offsets = NULL;
480                 obd_flag        *flags = NULL;
481                 int             j;
482                 unsigned long off;
483                 void *from;
484
485                 obd_data2conn(&conn, data);
486
487                 pages = data->ioc_plen1 / PAGE_SIZE;
488
489                 CDEBUG(D_INODE, "BRW %s with %d pages\n",
490                        rw == OBD_BRW_READ ? "read" : "write", pages);
491                 OBD_ALLOC(bufs, pages * sizeof(*bufs));
492                 OBD_ALLOC(counts, pages * sizeof(*counts));
493                 OBD_ALLOC(offsets, pages * sizeof(*offsets));
494                 OBD_ALLOC(flags, pages * sizeof(*flags));
495                 if (!bufs || !counts || !offsets || !flags) {
496                         CERROR("no memory for %d BRW per-page data\n", pages);
497                         GOTO(brw_free, err = -ENOMEM);
498                 }
499
500                 memset(&smd, 0, sizeof(smd));
501                 smd.lmd_object_id = data->ioc_obdo1.o_id;
502
503                 from = (&data->ioc_pbuf1)[0];
504                 off = data->ioc_offset;
505
506                 for (j = 0; j < pages;
507                      j++, off += PAGE_SIZE, from += PAGE_SIZE) {
508                         unsigned long to;
509
510                         to = __get_free_pages(GFP_KERNEL, 0);
511                         if (!to) {
512                                 /*      ||
513                                         copy_from_user((void
514                                         *)to,from,PAGE_SIZE))
515                                         free_pages(to, 0);
516                                 */
517                                 CERROR("no memory for brw pages\n");
518                                 GOTO(brw_cleanup, err = -ENOMEM);
519                         }
520                         bufs[j] = virt_to_page(to);
521                         counts[j] = PAGE_SIZE;
522                         offsets[j] = off;
523                         flags[j] = 0;
524                 }
525
526                 err = obd_brw(rw, &conn, &smd, j, bufs, counts, offsets, flags,
527                               NULL, NULL);
528
529                 EXIT;
530         brw_cleanup:
531                 for (j = 0; j < pages; j++)
532                         if (bufs[j] != NULL)
533                                 __free_pages(bufs[j], 0);
534         brw_free:
535                 OBD_FREE(bufs, pages * sizeof(*bufs));
536                 OBD_FREE(counts, pages * sizeof(*counts));
537                 OBD_FREE(offsets, pages * sizeof(*offsets));
538                 OBD_FREE(flags, pages * sizeof(*flags));
539                 GOTO(out, err);
540         }
541         default:
542                 obd_data2conn(&conn, data);
543
544                 err = obd_iocontrol(cmd, &conn, len, data, NULL);
545                 if (err)
546                         GOTO(out, err);
547
548                 err = copy_to_user((int *)arg, data, len);
549                 GOTO(out, err);
550         }
551
552  out:
553         if (buf)
554                 OBD_FREE(buf, len);
555         up(&obd_conf_sem);
556         RETURN(err);
557 } /* obd_class_ioctl */
558
559
560
561 /* declare character device */
562 static struct file_operations obd_psdev_fops = {
563         ioctl: obd_class_ioctl,       /* ioctl */
564         open: obd_class_open,        /* open */
565         release: obd_class_release,     /* release */
566 };
567
568 /* modules setup */
569 #define OBD_MINOR 241
570 static struct miscdevice obd_psdev = {
571         OBD_MINOR,
572         "obd_psdev",
573         &obd_psdev_fops
574 };
575
576
577 EXPORT_SYMBOL(obd_dev);
578 EXPORT_SYMBOL(obdo_cachep);
579 EXPORT_SYMBOL(obd_memory);
580 EXPORT_SYMBOL(obd_fail_loc);
581
582 EXPORT_SYMBOL(class_register_type);
583 EXPORT_SYMBOL(class_unregister_type);
584 EXPORT_SYMBOL(class_name2dev);
585 EXPORT_SYMBOL(class_uuid2dev);
586 EXPORT_SYMBOL(class_uuid2obd);
587 EXPORT_SYMBOL(class_new_export);
588 EXPORT_SYMBOL(class_connect);
589 EXPORT_SYMBOL(class_conn2export);
590 EXPORT_SYMBOL(class_rconn2export);
591 EXPORT_SYMBOL(class_conn2obd);
592 EXPORT_SYMBOL(class_disconnect);
593 EXPORT_SYMBOL(class_disconnect_all);
594 //EXPORT_SYMBOL(class_multi_setup);
595 //EXPORT_SYMBOL(class_multi_cleanup);
596
597 static int __init init_obdclass(void)
598 {
599         int err;
600         int i;
601
602         printk(KERN_INFO "OBD class driver  v0.9, info@clusterfs.com\n");
603
604         sema_init(&obd_conf_sem, 1);
605         INIT_LIST_HEAD(&obd_types);
606
607         if ((err = misc_register(&obd_psdev))) {
608                 CERROR("cannot register %d err %d\n", OBD_MINOR, err);
609                 return err;
610         }
611
612         for (i = 0; i < MAX_OBD_DEVICES; i++) {
613                 memset(&(obd_dev[i]), 0, sizeof(obd_dev[i]));
614                 obd_dev[i].obd_minor = i;
615                 INIT_LIST_HEAD(&obd_dev[i].obd_exports);
616         }
617
618         err = obd_init_caches();
619         if (err)
620                 return err;
621         obd_sysctl_init();
622         return 0;
623 }
624
625 static void __exit cleanup_obdclass(void)
626 {
627         int i;
628         ENTRY;
629
630         misc_deregister(&obd_psdev);
631         for (i = 0; i < MAX_OBD_DEVICES; i++) {
632                 struct obd_device *obd = &obd_dev[i];
633                 if (obd->obd_type && (obd->obd_flags & OBD_SET_UP) &&
634                     OBT(obd) && OBP(obd, detach)) {
635                         /* XXX should this call generic detach otherwise? */
636                         OBP(obd, detach)(obd);
637                 }
638         }
639
640         obd_cleanup_caches();
641         obd_sysctl_clean();
642         CERROR("obd memory leaked: %ld bytes\n", obd_memory);
643         EXIT;
644 }
645
646 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
647 MODULE_DESCRIPTION("Lustre Class Driver v1.0");
648 MODULE_LICENSE("GPL");
649
650 module_init(init_obdclass);
651 module_exit(cleanup_obdclass);