aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/drivers/ubd_kern.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/drivers/ubd_kern.c')
-rw-r--r--arch/um/drivers/ubd_kern.c319
1 files changed, 175 insertions, 144 deletions
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index bc458f57921b..49c047b75cc5 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -106,10 +106,15 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data)
106 106
107#define DRIVER_NAME "uml-blkdev" 107#define DRIVER_NAME "uml-blkdev"
108 108
109/* Can be taken in interrupt context, and is passed to the block layer to lock
110 * the request queue. Kernel side code knows that. */
109static DEFINE_SPINLOCK(ubd_io_lock); 111static DEFINE_SPINLOCK(ubd_io_lock);
110static DEFINE_SPINLOCK(ubd_lock);
111 112
112static void (*do_ubd)(void); 113static DEFINE_MUTEX(ubd_lock);
114
115/* XXX - this made sense in 2.4 days, now it's only used as a boolean, and
116 * probably it doesn't make sense even for that. */
117static int do_ubd;
113 118
114static int ubd_open(struct inode * inode, struct file * filp); 119static int ubd_open(struct inode * inode, struct file * filp);
115static int ubd_release(struct inode * inode, struct file * file); 120static int ubd_release(struct inode * inode, struct file * file);
@@ -117,7 +122,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
117 unsigned int cmd, unsigned long arg); 122 unsigned int cmd, unsigned long arg);
118static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo); 123static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
119 124
120#define MAX_DEV (8) 125#define MAX_DEV (16)
121 126
122static struct block_device_operations ubd_blops = { 127static struct block_device_operations ubd_blops = {
123 .owner = THIS_MODULE, 128 .owner = THIS_MODULE,
@@ -150,8 +155,9 @@ static struct gendisk *fake_gendisk[MAX_DEV];
150static struct openflags global_openflags = OPEN_FLAGS; 155static struct openflags global_openflags = OPEN_FLAGS;
151 156
152struct cow { 157struct cow {
153 /* This is the backing file, actually */ 158 /* backing file name */
154 char *file; 159 char *file;
160 /* backing file fd */
155 int fd; 161 int fd;
156 unsigned long *bitmap; 162 unsigned long *bitmap;
157 unsigned long bitmap_len; 163 unsigned long bitmap_len;
@@ -160,14 +166,16 @@ struct cow {
160}; 166};
161 167
162struct ubd { 168struct ubd {
169 /* name (and fd, below) of the file opened for writing, either the
170 * backing or the cow file. */
163 char *file; 171 char *file;
164 int count; 172 int count;
165 int fd; 173 int fd;
166 __u64 size; 174 __u64 size;
167 struct openflags boot_openflags; 175 struct openflags boot_openflags;
168 struct openflags openflags; 176 struct openflags openflags;
169 int shared; 177 unsigned shared:1;
170 int no_cow; 178 unsigned no_cow:1;
171 struct cow cow; 179 struct cow cow;
172 struct platform_device pdev; 180 struct platform_device pdev;
173}; 181};
@@ -192,18 +200,7 @@ struct ubd {
192 .cow = DEFAULT_COW, \ 200 .cow = DEFAULT_COW, \
193} 201}
194 202
195struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD }; 203struct ubd ubd_devs[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
196
197static int ubd0_init(void)
198{
199 struct ubd *dev = &ubd_dev[0];
200
201 if(dev->file == NULL)
202 dev->file = "root_fs";
203 return(0);
204}
205
206__initcall(ubd0_init);
207 204
208/* Only changed by fake_ide_setup which is a setup */ 205/* Only changed by fake_ide_setup which is a setup */
209static int fake_ide = 0; 206static int fake_ide = 0;
@@ -277,7 +274,7 @@ static int parse_unit(char **ptr)
277 return(-1); 274 return(-1);
278 *ptr = end; 275 *ptr = end;
279 } 276 }
280 else if (('a' <= *str) && (*str <= 'h')) { 277 else if (('a' <= *str) && (*str <= 'z')) {
281 n = *str - 'a'; 278 n = *str - 'a';
282 str++; 279 str++;
283 *ptr = str; 280 *ptr = str;
@@ -285,9 +282,13 @@ static int parse_unit(char **ptr)
285 return(n); 282 return(n);
286} 283}
287 284
285/* If *index_out == -1 at exit, the passed option was a general one;
286 * otherwise, the str pointer is used (and owned) inside ubd_devs array, so it
287 * should not be freed on exit.
288 */
288static int ubd_setup_common(char *str, int *index_out) 289static int ubd_setup_common(char *str, int *index_out)
289{ 290{
290 struct ubd *dev; 291 struct ubd *ubd_dev;
291 struct openflags flags = global_openflags; 292 struct openflags flags = global_openflags;
292 char *backing_file; 293 char *backing_file;
293 int n, err, i; 294 int n, err, i;
@@ -311,7 +312,7 @@ static int ubd_setup_common(char *str, int *index_out)
311 } 312 }
312 313
313 err = 1; 314 err = 1;
314 spin_lock(&ubd_lock); 315 mutex_lock(&ubd_lock);
315 if(fake_major != MAJOR_NR){ 316 if(fake_major != MAJOR_NR){
316 printk(KERN_ERR "Can't assign a fake major twice\n"); 317 printk(KERN_ERR "Can't assign a fake major twice\n");
317 goto out1; 318 goto out1;
@@ -323,7 +324,7 @@ static int ubd_setup_common(char *str, int *index_out)
323 major); 324 major);
324 err = 0; 325 err = 0;
325 out1: 326 out1:
326 spin_unlock(&ubd_lock); 327 mutex_unlock(&ubd_lock);
327 return(err); 328 return(err);
328 } 329 }
329 330
@@ -340,10 +341,10 @@ static int ubd_setup_common(char *str, int *index_out)
340 } 341 }
341 342
342 err = 1; 343 err = 1;
343 spin_lock(&ubd_lock); 344 mutex_lock(&ubd_lock);
344 345
345 dev = &ubd_dev[n]; 346 ubd_dev = &ubd_devs[n];
346 if(dev->file != NULL){ 347 if(ubd_dev->file != NULL){
347 printk(KERN_ERR "ubd_setup : device already configured\n"); 348 printk(KERN_ERR "ubd_setup : device already configured\n");
348 goto out; 349 goto out;
349 } 350 }
@@ -360,10 +361,10 @@ static int ubd_setup_common(char *str, int *index_out)
360 flags.s = 1; 361 flags.s = 1;
361 break; 362 break;
362 case 'd': 363 case 'd':
363 dev->no_cow = 1; 364 ubd_dev->no_cow = 1;
364 break; 365 break;
365 case 'c': 366 case 'c':
366 dev->shared = 1; 367 ubd_dev->shared = 1;
367 break; 368 break;
368 case '=': 369 case '=':
369 str++; 370 str++;
@@ -390,7 +391,7 @@ break_loop:
390 } 391 }
391 392
392 if(backing_file){ 393 if(backing_file){
393 if(dev->no_cow) 394 if(ubd_dev->no_cow)
394 printk(KERN_ERR "Can't specify both 'd' and a " 395 printk(KERN_ERR "Can't specify both 'd' and a "
395 "cow file\n"); 396 "cow file\n");
396 else { 397 else {
@@ -398,11 +399,11 @@ break_loop:
398 backing_file++; 399 backing_file++;
399 } 400 }
400 } 401 }
401 dev->file = str; 402 ubd_dev->file = str;
402 dev->cow.file = backing_file; 403 ubd_dev->cow.file = backing_file;
403 dev->boot_openflags = flags; 404 ubd_dev->boot_openflags = flags;
404out: 405out:
405 spin_unlock(&ubd_lock); 406 mutex_unlock(&ubd_lock);
406 return(err); 407 return(err);
407} 408}
408 409
@@ -472,8 +473,9 @@ int thread_fd = -1;
472 473
473/* Changed by ubd_handler, which is serialized because interrupts only 474/* Changed by ubd_handler, which is serialized because interrupts only
474 * happen on CPU 0. 475 * happen on CPU 0.
476 * XXX: currently unused.
475 */ 477 */
476int intr_count = 0; 478static int intr_count = 0;
477 479
478/* call ubd_finish if you need to serialize */ 480/* call ubd_finish if you need to serialize */
479static void __ubd_finish(struct request *req, int error) 481static void __ubd_finish(struct request *req, int error)
@@ -493,6 +495,8 @@ static void __ubd_finish(struct request *req, int error)
493 end_request(req, 1); 495 end_request(req, 1);
494} 496}
495 497
498/* Callable only from interrupt context - otherwise you need to do
499 * spin_lock_irq()/spin_lock_irqsave() */
496static inline void ubd_finish(struct request *req, int error) 500static inline void ubd_finish(struct request *req, int error)
497{ 501{
498 spin_lock(&ubd_io_lock); 502 spin_lock(&ubd_io_lock);
@@ -500,14 +504,15 @@ static inline void ubd_finish(struct request *req, int error)
500 spin_unlock(&ubd_io_lock); 504 spin_unlock(&ubd_io_lock);
501} 505}
502 506
503/* Called without ubd_io_lock held */ 507/* XXX - move this inside ubd_intr. */
508/* Called without ubd_io_lock held, and only in interrupt context. */
504static void ubd_handler(void) 509static void ubd_handler(void)
505{ 510{
506 struct io_thread_req req; 511 struct io_thread_req req;
507 struct request *rq = elv_next_request(ubd_queue); 512 struct request *rq = elv_next_request(ubd_queue);
508 int n; 513 int n;
509 514
510 do_ubd = NULL; 515 do_ubd = 0;
511 intr_count++; 516 intr_count++;
512 n = os_read_file(thread_fd, &req, sizeof(req)); 517 n = os_read_file(thread_fd, &req, sizeof(req));
513 if(n != sizeof(req)){ 518 if(n != sizeof(req)){
@@ -521,7 +526,9 @@ static void ubd_handler(void)
521 526
522 ubd_finish(rq, req.error); 527 ubd_finish(rq, req.error);
523 reactivate_fd(thread_fd, UBD_IRQ); 528 reactivate_fd(thread_fd, UBD_IRQ);
529 spin_lock(&ubd_io_lock);
524 do_ubd_request(ubd_queue); 530 do_ubd_request(ubd_queue);
531 spin_unlock(&ubd_io_lock);
525} 532}
526 533
527static irqreturn_t ubd_intr(int irq, void *dev) 534static irqreturn_t ubd_intr(int irq, void *dev)
@@ -541,87 +548,90 @@ void kill_io_thread(void)
541 548
542__uml_exitcall(kill_io_thread); 549__uml_exitcall(kill_io_thread);
543 550
544static int ubd_file_size(struct ubd *dev, __u64 *size_out) 551static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
545{ 552{
546 char *file; 553 char *file;
547 554
548 file = dev->cow.file ? dev->cow.file : dev->file; 555 file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file;
549 return(os_file_size(file, size_out)); 556 return(os_file_size(file, size_out));
550} 557}
551 558
552static void ubd_close(struct ubd *dev) 559static void ubd_close_dev(struct ubd *ubd_dev)
553{ 560{
554 os_close_file(dev->fd); 561 os_close_file(ubd_dev->fd);
555 if(dev->cow.file == NULL) 562 if(ubd_dev->cow.file == NULL)
556 return; 563 return;
557 564
558 os_close_file(dev->cow.fd); 565 os_close_file(ubd_dev->cow.fd);
559 vfree(dev->cow.bitmap); 566 vfree(ubd_dev->cow.bitmap);
560 dev->cow.bitmap = NULL; 567 ubd_dev->cow.bitmap = NULL;
561} 568}
562 569
563static int ubd_open_dev(struct ubd *dev) 570static int ubd_open_dev(struct ubd *ubd_dev)
564{ 571{
565 struct openflags flags; 572 struct openflags flags;
566 char **back_ptr; 573 char **back_ptr;
567 int err, create_cow, *create_ptr; 574 int err, create_cow, *create_ptr;
575 int fd;
568 576
569 dev->openflags = dev->boot_openflags; 577 ubd_dev->openflags = ubd_dev->boot_openflags;
570 create_cow = 0; 578 create_cow = 0;
571 create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL; 579 create_ptr = (ubd_dev->cow.file != NULL) ? &create_cow : NULL;
572 back_ptr = dev->no_cow ? NULL : &dev->cow.file; 580 back_ptr = ubd_dev->no_cow ? NULL : &ubd_dev->cow.file;
573 dev->fd = open_ubd_file(dev->file, &dev->openflags, dev->shared, 581
574 back_ptr, &dev->cow.bitmap_offset, 582 fd = open_ubd_file(ubd_dev->file, &ubd_dev->openflags, ubd_dev->shared,
575 &dev->cow.bitmap_len, &dev->cow.data_offset, 583 back_ptr, &ubd_dev->cow.bitmap_offset,
584 &ubd_dev->cow.bitmap_len, &ubd_dev->cow.data_offset,
576 create_ptr); 585 create_ptr);
577 586
578 if((dev->fd == -ENOENT) && create_cow){ 587 if((fd == -ENOENT) && create_cow){
579 dev->fd = create_cow_file(dev->file, dev->cow.file, 588 fd = create_cow_file(ubd_dev->file, ubd_dev->cow.file,
580 dev->openflags, 1 << 9, PAGE_SIZE, 589 ubd_dev->openflags, 1 << 9, PAGE_SIZE,
581 &dev->cow.bitmap_offset, 590 &ubd_dev->cow.bitmap_offset,
582 &dev->cow.bitmap_len, 591 &ubd_dev->cow.bitmap_len,
583 &dev->cow.data_offset); 592 &ubd_dev->cow.data_offset);
584 if(dev->fd >= 0){ 593 if(fd >= 0){
585 printk(KERN_INFO "Creating \"%s\" as COW file for " 594 printk(KERN_INFO "Creating \"%s\" as COW file for "
586 "\"%s\"\n", dev->file, dev->cow.file); 595 "\"%s\"\n", ubd_dev->file, ubd_dev->cow.file);
587 } 596 }
588 } 597 }
589 598
590 if(dev->fd < 0){ 599 if(fd < 0){
591 printk("Failed to open '%s', errno = %d\n", dev->file, 600 printk("Failed to open '%s', errno = %d\n", ubd_dev->file,
592 -dev->fd); 601 -fd);
593 return(dev->fd); 602 return fd;
594 } 603 }
604 ubd_dev->fd = fd;
595 605
596 if(dev->cow.file != NULL){ 606 if(ubd_dev->cow.file != NULL){
597 err = -ENOMEM; 607 err = -ENOMEM;
598 dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len); 608 ubd_dev->cow.bitmap = (void *) vmalloc(ubd_dev->cow.bitmap_len);
599 if(dev->cow.bitmap == NULL){ 609 if(ubd_dev->cow.bitmap == NULL){
600 printk(KERN_ERR "Failed to vmalloc COW bitmap\n"); 610 printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
601 goto error; 611 goto error;
602 } 612 }
603 flush_tlb_kernel_vm(); 613 flush_tlb_kernel_vm();
604 614
605 err = read_cow_bitmap(dev->fd, dev->cow.bitmap, 615 err = read_cow_bitmap(ubd_dev->fd, ubd_dev->cow.bitmap,
606 dev->cow.bitmap_offset, 616 ubd_dev->cow.bitmap_offset,
607 dev->cow.bitmap_len); 617 ubd_dev->cow.bitmap_len);
608 if(err < 0) 618 if(err < 0)
609 goto error; 619 goto error;
610 620
611 flags = dev->openflags; 621 flags = ubd_dev->openflags;
612 flags.w = 0; 622 flags.w = 0;
613 err = open_ubd_file(dev->cow.file, &flags, dev->shared, NULL, 623 err = open_ubd_file(ubd_dev->cow.file, &flags, ubd_dev->shared, NULL,
614 NULL, NULL, NULL, NULL); 624 NULL, NULL, NULL, NULL);
615 if(err < 0) goto error; 625 if(err < 0) goto error;
616 dev->cow.fd = err; 626 ubd_dev->cow.fd = err;
617 } 627 }
618 return(0); 628 return(0);
619 error: 629 error:
620 os_close_file(dev->fd); 630 os_close_file(ubd_dev->fd);
621 return(err); 631 return(err);
622} 632}
623 633
624static int ubd_new_disk(int major, u64 size, int unit, 634static int ubd_disk_register(int major, u64 size, int unit,
625 struct gendisk **disk_out) 635 struct gendisk **disk_out)
626 636
627{ 637{
@@ -642,13 +652,13 @@ static int ubd_new_disk(int major, u64 size, int unit,
642 652
643 /* sysfs register (not for ide fake devices) */ 653 /* sysfs register (not for ide fake devices) */
644 if (major == MAJOR_NR) { 654 if (major == MAJOR_NR) {
645 ubd_dev[unit].pdev.id = unit; 655 ubd_devs[unit].pdev.id = unit;
646 ubd_dev[unit].pdev.name = DRIVER_NAME; 656 ubd_devs[unit].pdev.name = DRIVER_NAME;
647 platform_device_register(&ubd_dev[unit].pdev); 657 platform_device_register(&ubd_devs[unit].pdev);
648 disk->driverfs_dev = &ubd_dev[unit].pdev.dev; 658 disk->driverfs_dev = &ubd_devs[unit].pdev.dev;
649 } 659 }
650 660
651 disk->private_data = &ubd_dev[unit]; 661 disk->private_data = &ubd_devs[unit];
652 disk->queue = ubd_queue; 662 disk->queue = ubd_queue;
653 add_disk(disk); 663 add_disk(disk);
654 664
@@ -660,25 +670,25 @@ static int ubd_new_disk(int major, u64 size, int unit,
660 670
661static int ubd_add(int n) 671static int ubd_add(int n)
662{ 672{
663 struct ubd *dev = &ubd_dev[n]; 673 struct ubd *ubd_dev = &ubd_devs[n];
664 int err; 674 int err;
665 675
666 err = -ENODEV; 676 err = -ENODEV;
667 if(dev->file == NULL) 677 if(ubd_dev->file == NULL)
668 goto out; 678 goto out;
669 679
670 err = ubd_file_size(dev, &dev->size); 680 err = ubd_file_size(ubd_dev, &ubd_dev->size);
671 if(err < 0) 681 if(err < 0)
672 goto out; 682 goto out;
673 683
674 dev->size = ROUND_BLOCK(dev->size); 684 ubd_dev->size = ROUND_BLOCK(ubd_dev->size);
675 685
676 err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]); 686 err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]);
677 if(err) 687 if(err)
678 goto out; 688 goto out;
679 689
680 if(fake_major != MAJOR_NR) 690 if(fake_major != MAJOR_NR)
681 ubd_new_disk(fake_major, dev->size, n, 691 ubd_disk_register(fake_major, ubd_dev->size, n,
682 &fake_gendisk[n]); 692 &fake_gendisk[n]);
683 693
684 /* perhaps this should also be under the "if (fake_major)" above */ 694 /* perhaps this should also be under the "if (fake_major)" above */
@@ -693,32 +703,41 @@ out:
693 703
694static int ubd_config(char *str) 704static int ubd_config(char *str)
695{ 705{
696 int n, err; 706 int n, ret;
697 707
698 str = kstrdup(str, GFP_KERNEL); 708 str = kstrdup(str, GFP_KERNEL);
699 if(str == NULL){ 709 if (str == NULL) {
700 printk(KERN_ERR "ubd_config failed to strdup string\n"); 710 printk(KERN_ERR "ubd_config failed to strdup string\n");
701 return(1); 711 ret = 1;
712 goto out;
702 } 713 }
703 err = ubd_setup_common(str, &n); 714 ret = ubd_setup_common(str, &n);
704 if(err){ 715 if (ret) {
705 kfree(str); 716 ret = -1;
706 return(-1); 717 goto err_free;
718 }
719 if (n == -1) {
720 ret = 0;
721 goto err_free;
707 } 722 }
708 if(n == -1) return(0);
709 723
710 spin_lock(&ubd_lock); 724 mutex_lock(&ubd_lock);
711 err = ubd_add(n); 725 ret = ubd_add(n);
712 if(err) 726 if (ret)
713 ubd_dev[n].file = NULL; 727 ubd_devs[n].file = NULL;
714 spin_unlock(&ubd_lock); 728 mutex_unlock(&ubd_lock);
715 729
716 return(err); 730out:
731 return ret;
732
733err_free:
734 kfree(str);
735 goto out;
717} 736}
718 737
719static int ubd_get_config(char *name, char *str, int size, char **error_out) 738static int ubd_get_config(char *name, char *str, int size, char **error_out)
720{ 739{
721 struct ubd *dev; 740 struct ubd *ubd_dev;
722 int n, len = 0; 741 int n, len = 0;
723 742
724 n = parse_unit(&name); 743 n = parse_unit(&name);
@@ -727,24 +746,24 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out)
727 return(-1); 746 return(-1);
728 } 747 }
729 748
730 dev = &ubd_dev[n]; 749 ubd_dev = &ubd_devs[n];
731 spin_lock(&ubd_lock); 750 mutex_lock(&ubd_lock);
732 751
733 if(dev->file == NULL){ 752 if(ubd_dev->file == NULL){
734 CONFIG_CHUNK(str, size, len, "", 1); 753 CONFIG_CHUNK(str, size, len, "", 1);
735 goto out; 754 goto out;
736 } 755 }
737 756
738 CONFIG_CHUNK(str, size, len, dev->file, 0); 757 CONFIG_CHUNK(str, size, len, ubd_dev->file, 0);
739 758
740 if(dev->cow.file != NULL){ 759 if(ubd_dev->cow.file != NULL){
741 CONFIG_CHUNK(str, size, len, ",", 0); 760 CONFIG_CHUNK(str, size, len, ",", 0);
742 CONFIG_CHUNK(str, size, len, dev->cow.file, 1); 761 CONFIG_CHUNK(str, size, len, ubd_dev->cow.file, 1);
743 } 762 }
744 else CONFIG_CHUNK(str, size, len, "", 1); 763 else CONFIG_CHUNK(str, size, len, "", 1);
745 764
746 out: 765 out:
747 spin_unlock(&ubd_lock); 766 mutex_unlock(&ubd_lock);
748 return(len); 767 return(len);
749} 768}
750 769
@@ -760,22 +779,22 @@ static int ubd_id(char **str, int *start_out, int *end_out)
760 779
761static int ubd_remove(int n) 780static int ubd_remove(int n)
762{ 781{
763 struct ubd *dev; 782 struct ubd *ubd_dev;
764 int err = -ENODEV; 783 int err = -ENODEV;
765 784
766 spin_lock(&ubd_lock); 785 mutex_lock(&ubd_lock);
767 786
768 if(ubd_gendisk[n] == NULL) 787 if(ubd_gendisk[n] == NULL)
769 goto out; 788 goto out;
770 789
771 dev = &ubd_dev[n]; 790 ubd_dev = &ubd_devs[n];
772 791
773 if(dev->file == NULL) 792 if(ubd_dev->file == NULL)
774 goto out; 793 goto out;
775 794
776 /* you cannot remove a open disk */ 795 /* you cannot remove a open disk */
777 err = -EBUSY; 796 err = -EBUSY;
778 if(dev->count > 0) 797 if(ubd_dev->count > 0)
779 goto out; 798 goto out;
780 799
781 del_gendisk(ubd_gendisk[n]); 800 del_gendisk(ubd_gendisk[n]);
@@ -788,14 +807,15 @@ static int ubd_remove(int n)
788 fake_gendisk[n] = NULL; 807 fake_gendisk[n] = NULL;
789 } 808 }
790 809
791 platform_device_unregister(&dev->pdev); 810 platform_device_unregister(&ubd_dev->pdev);
792 *dev = ((struct ubd) DEFAULT_UBD); 811 *ubd_dev = ((struct ubd) DEFAULT_UBD);
793 err = 0; 812 err = 0;
794out: 813out:
795 spin_unlock(&ubd_lock); 814 mutex_unlock(&ubd_lock);
796 return err; 815 return err;
797} 816}
798 817
818/* All these are called by mconsole in process context and without ubd-specific locks. */
799static struct mc_device ubd_mc = { 819static struct mc_device ubd_mc = {
800 .name = "ubd", 820 .name = "ubd",
801 .config = ubd_config, 821 .config = ubd_config,
@@ -804,7 +824,7 @@ static struct mc_device ubd_mc = {
804 .remove = ubd_remove, 824 .remove = ubd_remove,
805}; 825};
806 826
807static int ubd_mc_init(void) 827static int __init ubd_mc_init(void)
808{ 828{
809 mconsole_register_dev(&ubd_mc); 829 mconsole_register_dev(&ubd_mc);
810 return 0; 830 return 0;
@@ -812,13 +832,24 @@ static int ubd_mc_init(void)
812 832
813__initcall(ubd_mc_init); 833__initcall(ubd_mc_init);
814 834
835static int __init ubd0_init(void)
836{
837 struct ubd *ubd_dev = &ubd_devs[0];
838
839 if(ubd_dev->file == NULL)
840 ubd_dev->file = "root_fs";
841 return(0);
842}
843
844__initcall(ubd0_init);
845
815static struct platform_driver ubd_driver = { 846static struct platform_driver ubd_driver = {
816 .driver = { 847 .driver = {
817 .name = DRIVER_NAME, 848 .name = DRIVER_NAME,
818 }, 849 },
819}; 850};
820 851
821int ubd_init(void) 852static int __init ubd_init(void)
822{ 853{
823 int i; 854 int i;
824 855
@@ -846,7 +877,7 @@ int ubd_init(void)
846 877
847late_initcall(ubd_init); 878late_initcall(ubd_init);
848 879
849int ubd_driver_init(void){ 880static int __init ubd_driver_init(void){
850 unsigned long stack; 881 unsigned long stack;
851 int err; 882 int err;
852 883
@@ -867,7 +898,7 @@ int ubd_driver_init(void){
867 return(0); 898 return(0);
868 } 899 }
869 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, 900 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
870 IRQF_DISABLED, "ubd", ubd_dev); 901 IRQF_DISABLED, "ubd", ubd_devs);
871 if(err != 0) 902 if(err != 0)
872 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err); 903 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
873 return 0; 904 return 0;
@@ -878,24 +909,24 @@ device_initcall(ubd_driver_init);
878static int ubd_open(struct inode *inode, struct file *filp) 909static int ubd_open(struct inode *inode, struct file *filp)
879{ 910{
880 struct gendisk *disk = inode->i_bdev->bd_disk; 911 struct gendisk *disk = inode->i_bdev->bd_disk;
881 struct ubd *dev = disk->private_data; 912 struct ubd *ubd_dev = disk->private_data;
882 int err = 0; 913 int err = 0;
883 914
884 if(dev->count == 0){ 915 if(ubd_dev->count == 0){
885 err = ubd_open_dev(dev); 916 err = ubd_open_dev(ubd_dev);
886 if(err){ 917 if(err){
887 printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n", 918 printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
888 disk->disk_name, dev->file, -err); 919 disk->disk_name, ubd_dev->file, -err);
889 goto out; 920 goto out;
890 } 921 }
891 } 922 }
892 dev->count++; 923 ubd_dev->count++;
893 set_disk_ro(disk, !dev->openflags.w); 924 set_disk_ro(disk, !ubd_dev->openflags.w);
894 925
895 /* This should no more be needed. And it didn't work anyway to exclude 926 /* This should no more be needed. And it didn't work anyway to exclude
896 * read-write remounting of filesystems.*/ 927 * read-write remounting of filesystems.*/
897 /*if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){ 928 /*if((filp->f_mode & FMODE_WRITE) && !ubd_dev->openflags.w){
898 if(--dev->count == 0) ubd_close(dev); 929 if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev);
899 err = -EROFS; 930 err = -EROFS;
900 }*/ 931 }*/
901 out: 932 out:
@@ -905,10 +936,10 @@ static int ubd_open(struct inode *inode, struct file *filp)
905static int ubd_release(struct inode * inode, struct file * file) 936static int ubd_release(struct inode * inode, struct file * file)
906{ 937{
907 struct gendisk *disk = inode->i_bdev->bd_disk; 938 struct gendisk *disk = inode->i_bdev->bd_disk;
908 struct ubd *dev = disk->private_data; 939 struct ubd *ubd_dev = disk->private_data;
909 940
910 if(--dev->count == 0) 941 if(--ubd_dev->count == 0)
911 ubd_close(dev); 942 ubd_close_dev(ubd_dev);
912 return(0); 943 return(0);
913} 944}
914 945
@@ -976,12 +1007,12 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
976static int prepare_request(struct request *req, struct io_thread_req *io_req) 1007static int prepare_request(struct request *req, struct io_thread_req *io_req)
977{ 1008{
978 struct gendisk *disk = req->rq_disk; 1009 struct gendisk *disk = req->rq_disk;
979 struct ubd *dev = disk->private_data; 1010 struct ubd *ubd_dev = disk->private_data;
980 __u64 offset; 1011 __u64 offset;
981 int len; 1012 int len;
982 1013
983 /* This should be impossible now */ 1014 /* This should be impossible now */
984 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){ 1015 if((rq_data_dir(req) == WRITE) && !ubd_dev->openflags.w){
985 printk("Write attempted on readonly ubd device %s\n", 1016 printk("Write attempted on readonly ubd device %s\n",
986 disk->disk_name); 1017 disk->disk_name);
987 end_request(req, 0); 1018 end_request(req, 0);
@@ -991,8 +1022,8 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
991 offset = ((__u64) req->sector) << 9; 1022 offset = ((__u64) req->sector) << 9;
992 len = req->current_nr_sectors << 9; 1023 len = req->current_nr_sectors << 9;
993 1024
994 io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd; 1025 io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd : ubd_dev->fd;
995 io_req->fds[1] = dev->fd; 1026 io_req->fds[1] = ubd_dev->fd;
996 io_req->cow_offset = -1; 1027 io_req->cow_offset = -1;
997 io_req->offset = offset; 1028 io_req->offset = offset;
998 io_req->length = len; 1029 io_req->length = len;
@@ -1001,13 +1032,13 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
1001 1032
1002 io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE; 1033 io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
1003 io_req->offsets[0] = 0; 1034 io_req->offsets[0] = 0;
1004 io_req->offsets[1] = dev->cow.data_offset; 1035 io_req->offsets[1] = ubd_dev->cow.data_offset;
1005 io_req->buffer = req->buffer; 1036 io_req->buffer = req->buffer;
1006 io_req->sectorsize = 1 << 9; 1037 io_req->sectorsize = 1 << 9;
1007 1038
1008 if(dev->cow.file != NULL) 1039 if(ubd_dev->cow.file != NULL)
1009 cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset, 1040 cowify_req(io_req, ubd_dev->cow.bitmap, ubd_dev->cow.bitmap_offset,
1010 dev->cow.bitmap_len); 1041 ubd_dev->cow.bitmap_len);
1011 1042
1012 return(0); 1043 return(0);
1013} 1044}
@@ -1033,7 +1064,7 @@ static void do_ubd_request(request_queue_t *q)
1033 return; 1064 return;
1034 err = prepare_request(req, &io_req); 1065 err = prepare_request(req, &io_req);
1035 if(!err){ 1066 if(!err){
1036 do_ubd = ubd_handler; 1067 do_ubd = 1;
1037 n = os_write_file(thread_fd, (char *) &io_req, 1068 n = os_write_file(thread_fd, (char *) &io_req,
1038 sizeof(io_req)); 1069 sizeof(io_req));
1039 if(n != sizeof(io_req)) 1070 if(n != sizeof(io_req))
@@ -1045,18 +1076,18 @@ static void do_ubd_request(request_queue_t *q)
1045 1076
1046static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo) 1077static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1047{ 1078{
1048 struct ubd *dev = bdev->bd_disk->private_data; 1079 struct ubd *ubd_dev = bdev->bd_disk->private_data;
1049 1080
1050 geo->heads = 128; 1081 geo->heads = 128;
1051 geo->sectors = 32; 1082 geo->sectors = 32;
1052 geo->cylinders = dev->size / (128 * 32 * 512); 1083 geo->cylinders = ubd_dev->size / (128 * 32 * 512);
1053 return 0; 1084 return 0;
1054} 1085}
1055 1086
1056static int ubd_ioctl(struct inode * inode, struct file * file, 1087static int ubd_ioctl(struct inode * inode, struct file * file,
1057 unsigned int cmd, unsigned long arg) 1088 unsigned int cmd, unsigned long arg)
1058{ 1089{
1059 struct ubd *dev = inode->i_bdev->bd_disk->private_data; 1090 struct ubd *ubd_dev = inode->i_bdev->bd_disk->private_data;
1060 struct hd_driveid ubd_id = { 1091 struct hd_driveid ubd_id = {
1061 .cyls = 0, 1092 .cyls = 0,
1062 .heads = 128, 1093 .heads = 128,
@@ -1066,7 +1097,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
1066 switch (cmd) { 1097 switch (cmd) {
1067 struct cdrom_volctrl volume; 1098 struct cdrom_volctrl volume;
1068 case HDIO_GET_IDENTITY: 1099 case HDIO_GET_IDENTITY:
1069 ubd_id.cyls = dev->size / (128 * 32 * 512); 1100 ubd_id.cyls = ubd_dev->size / (128 * 32 * 512);
1070 if(copy_to_user((char __user *) arg, (char *) &ubd_id, 1101 if(copy_to_user((char __user *) arg, (char *) &ubd_id,
1071 sizeof(ubd_id))) 1102 sizeof(ubd_id)))
1072 return(-EFAULT); 1103 return(-EFAULT);
@@ -1353,8 +1384,8 @@ void do_io(struct io_thread_req *req)
1353 */ 1384 */
1354int kernel_fd = -1; 1385int kernel_fd = -1;
1355 1386
1356/* Only changed by the io thread */ 1387/* Only changed by the io thread. XXX: currently unused. */
1357int io_count = 0; 1388static int io_count = 0;
1358 1389
1359int io_thread(void *arg) 1390int io_thread(void *arg)
1360{ 1391{