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