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.c351
1 files changed, 195 insertions, 156 deletions
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 8bd9204ac1ab..70509ddaac03 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -39,7 +39,6 @@
39#include "asm/irq.h" 39#include "asm/irq.h"
40#include "asm/types.h" 40#include "asm/types.h"
41#include "asm/tlbflush.h" 41#include "asm/tlbflush.h"
42#include "user_util.h"
43#include "mem_user.h" 42#include "mem_user.h"
44#include "kern_util.h" 43#include "kern_util.h"
45#include "kern.h" 44#include "kern.h"
@@ -90,7 +89,7 @@ static inline int ubd_test_bit(__u64 bit, unsigned char *data)
90 bits = sizeof(data[0]) * 8; 89 bits = sizeof(data[0]) * 8;
91 n = bit / bits; 90 n = bit / bits;
92 off = bit % bits; 91 off = bit % bits;
93 return((data[n] & (1 << off)) != 0); 92 return (data[n] & (1 << off)) != 0;
94} 93}
95 94
96static inline void ubd_set_bit(__u64 bit, unsigned char *data) 95static inline void ubd_set_bit(__u64 bit, unsigned char *data)
@@ -147,10 +146,13 @@ struct cow {
147 unsigned long *bitmap; 146 unsigned long *bitmap;
148 unsigned long bitmap_len; 147 unsigned long bitmap_len;
149 int bitmap_offset; 148 int bitmap_offset;
150 int data_offset; 149 int data_offset;
151}; 150};
152 151
152#define MAX_SG 64
153
153struct ubd { 154struct ubd {
155 struct list_head restart;
154 /* name (and fd, below) of the file opened for writing, either the 156 /* name (and fd, below) of the file opened for writing, either the
155 * backing or the cow file. */ 157 * backing or the cow file. */
156 char *file; 158 char *file;
@@ -165,15 +167,17 @@ struct ubd {
165 struct platform_device pdev; 167 struct platform_device pdev;
166 struct request_queue *queue; 168 struct request_queue *queue;
167 spinlock_t lock; 169 spinlock_t lock;
168 int active; 170 struct scatterlist sg[MAX_SG];
171 struct request *request;
172 int start_sg, end_sg;
169}; 173};
170 174
171#define DEFAULT_COW { \ 175#define DEFAULT_COW { \
172 .file = NULL, \ 176 .file = NULL, \
173 .fd = -1, \ 177 .fd = -1, \
174 .bitmap = NULL, \ 178 .bitmap = NULL, \
175 .bitmap_offset = 0, \ 179 .bitmap_offset = 0, \
176 .data_offset = 0, \ 180 .data_offset = 0, \
177} 181}
178 182
179#define DEFAULT_UBD { \ 183#define DEFAULT_UBD { \
@@ -183,11 +187,13 @@ struct ubd {
183 .size = -1, \ 187 .size = -1, \
184 .boot_openflags = OPEN_FLAGS, \ 188 .boot_openflags = OPEN_FLAGS, \
185 .openflags = OPEN_FLAGS, \ 189 .openflags = OPEN_FLAGS, \
186 .no_cow = 0, \ 190 .no_cow = 0, \
187 .shared = 0, \ 191 .shared = 0, \
188 .cow = DEFAULT_COW, \ 192 .cow = DEFAULT_COW, \
189 .lock = SPIN_LOCK_UNLOCKED, \ 193 .lock = SPIN_LOCK_UNLOCKED, \
190 .active = 0, \ 194 .request = NULL, \
195 .start_sg = 0, \
196 .end_sg = 0, \
191} 197}
192 198
193/* Protected by ubd_lock */ 199/* Protected by ubd_lock */
@@ -243,7 +249,7 @@ static void make_ide_entries(char *dev_name)
243static int fake_ide_setup(char *str) 249static int fake_ide_setup(char *str)
244{ 250{
245 fake_ide = 1; 251 fake_ide = 1;
246 return(1); 252 return 1;
247} 253}
248 254
249__setup("fake_ide", fake_ide_setup); 255__setup("fake_ide", fake_ide_setup);
@@ -261,7 +267,7 @@ static int parse_unit(char **ptr)
261 if(isdigit(*str)) { 267 if(isdigit(*str)) {
262 n = simple_strtoul(str, &end, 0); 268 n = simple_strtoul(str, &end, 0);
263 if(end == str) 269 if(end == str)
264 return(-1); 270 return -1;
265 *ptr = end; 271 *ptr = end;
266 } 272 }
267 else if (('a' <= *str) && (*str <= 'z')) { 273 else if (('a' <= *str) && (*str <= 'z')) {
@@ -269,7 +275,7 @@ static int parse_unit(char **ptr)
269 str++; 275 str++;
270 *ptr = str; 276 *ptr = str;
271 } 277 }
272 return(n); 278 return n;
273} 279}
274 280
275/* If *index_out == -1 at exit, the passed option was a general one; 281/* If *index_out == -1 at exit, the passed option was a general one;
@@ -436,7 +442,7 @@ static int udb_setup(char *str)
436{ 442{
437 printk("udb%s specified on command line is almost certainly a ubd -> " 443 printk("udb%s specified on command line is almost certainly a ubd -> "
438 "udb TYPO\n", str); 444 "udb TYPO\n", str);
439 return(1); 445 return 1;
440} 446}
441 447
442__setup("udb", udb_setup); 448__setup("udb", udb_setup);
@@ -467,66 +473,75 @@ static void do_ubd_request(request_queue_t * q);
467/* Only changed by ubd_init, which is an initcall. */ 473/* Only changed by ubd_init, which is an initcall. */
468int thread_fd = -1; 474int thread_fd = -1;
469 475
470/* call ubd_finish if you need to serialize */ 476static void ubd_end_request(struct request *req, int bytes, int uptodate)
471static void __ubd_finish(struct request *req, int error)
472{ 477{
473 int nsect; 478 if (!end_that_request_first(req, uptodate, bytes >> 9)) {
474 479 struct ubd *dev = req->rq_disk->private_data;
475 if(error){ 480 unsigned long flags;
476 end_request(req, 0); 481
477 return; 482 add_disk_randomness(req->rq_disk);
483 spin_lock_irqsave(&dev->lock, flags);
484 end_that_request_last(req, uptodate);
485 spin_unlock_irqrestore(&dev->lock, flags);
478 } 486 }
479 nsect = req->current_nr_sectors;
480 req->sector += nsect;
481 req->buffer += nsect << 9;
482 req->errors = 0;
483 req->nr_sectors -= nsect;
484 req->current_nr_sectors = 0;
485 end_request(req, 1);
486} 487}
487 488
488/* Callable only from interrupt context - otherwise you need to do 489/* Callable only from interrupt context - otherwise you need to do
489 * spin_lock_irq()/spin_lock_irqsave() */ 490 * spin_lock_irq()/spin_lock_irqsave() */
490static inline void ubd_finish(struct request *req, int error) 491static inline void ubd_finish(struct request *req, int bytes)
491{ 492{
492 struct ubd *dev = req->rq_disk->private_data; 493 if(bytes < 0){
493 494 ubd_end_request(req, 0, 0);
494 spin_lock(&dev->lock); 495 return;
495 __ubd_finish(req, error); 496 }
496 spin_unlock(&dev->lock); 497 ubd_end_request(req, bytes, 1);
497} 498}
498 499
500static LIST_HEAD(restart);
501
499/* XXX - move this inside ubd_intr. */ 502/* XXX - move this inside ubd_intr. */
500/* Called without dev->lock held, and only in interrupt context. */ 503/* Called without dev->lock held, and only in interrupt context. */
501static void ubd_handler(void) 504static void ubd_handler(void)
502{ 505{
503 struct io_thread_req req; 506 struct io_thread_req *req;
504 struct request *rq; 507 struct request *rq;
505 struct ubd *dev; 508 struct ubd *ubd;
509 struct list_head *list, *next_ele;
510 unsigned long flags;
506 int n; 511 int n;
507 512
508 n = os_read_file(thread_fd, &req, sizeof(req)); 513 while(1){
509 if(n != sizeof(req)){ 514 n = os_read_file(thread_fd, &req,
510 printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, " 515 sizeof(struct io_thread_req *));
511 "err = %d\n", os_getpid(), -n); 516 if(n != sizeof(req)){
512 return; 517 if(n == -EAGAIN)
513 } 518 break;
514 519 printk(KERN_ERR "spurious interrupt in ubd_handler, "
515 rq = req.req; 520 "err = %d\n", -n);
516 dev = rq->rq_disk->private_data; 521 return;
517 dev->active = 0; 522 }
518 523
519 ubd_finish(rq, req.error); 524 rq = req->req;
525 rq->nr_sectors -= req->length >> 9;
526 if(rq->nr_sectors == 0)
527 ubd_finish(rq, rq->hard_nr_sectors << 9);
528 kfree(req);
529 }
520 reactivate_fd(thread_fd, UBD_IRQ); 530 reactivate_fd(thread_fd, UBD_IRQ);
521 spin_lock(&dev->lock); 531
522 do_ubd_request(dev->queue); 532 list_for_each_safe(list, next_ele, &restart){
523 spin_unlock(&dev->lock); 533 ubd = container_of(list, struct ubd, restart);
534 list_del_init(&ubd->restart);
535 spin_lock_irqsave(&ubd->lock, flags);
536 do_ubd_request(ubd->queue);
537 spin_unlock_irqrestore(&ubd->lock, flags);
538 }
524} 539}
525 540
526static irqreturn_t ubd_intr(int irq, void *dev) 541static irqreturn_t ubd_intr(int irq, void *dev)
527{ 542{
528 ubd_handler(); 543 ubd_handler();
529 return(IRQ_HANDLED); 544 return IRQ_HANDLED;
530} 545}
531 546
532/* Only changed by ubd_init, which is an initcall. */ 547/* Only changed by ubd_init, which is an initcall. */
@@ -545,7 +560,7 @@ static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
545 char *file; 560 char *file;
546 561
547 file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file; 562 file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file;
548 return(os_file_size(file, size_out)); 563 return os_file_size(file, size_out);
549} 564}
550 565
551static void ubd_close_dev(struct ubd *ubd_dev) 566static void ubd_close_dev(struct ubd *ubd_dev)
@@ -617,10 +632,18 @@ static int ubd_open_dev(struct ubd *ubd_dev)
617 if(err < 0) goto error; 632 if(err < 0) goto error;
618 ubd_dev->cow.fd = err; 633 ubd_dev->cow.fd = err;
619 } 634 }
620 return(0); 635 return 0;
621 error: 636 error:
622 os_close_file(ubd_dev->fd); 637 os_close_file(ubd_dev->fd);
623 return(err); 638 return err;
639}
640
641static void ubd_device_release(struct device *dev)
642{
643 struct ubd *ubd_dev = dev->driver_data;
644
645 blk_cleanup_queue(ubd_dev->queue);
646 *ubd_dev = ((struct ubd) DEFAULT_UBD);
624} 647}
625 648
626static int ubd_disk_register(int major, u64 size, int unit, 649static int ubd_disk_register(int major, u64 size, int unit,
@@ -630,7 +653,7 @@ static int ubd_disk_register(int major, u64 size, int unit,
630 653
631 disk = alloc_disk(1 << UBD_SHIFT); 654 disk = alloc_disk(1 << UBD_SHIFT);
632 if(disk == NULL) 655 if(disk == NULL)
633 return(-ENOMEM); 656 return -ENOMEM;
634 657
635 disk->major = major; 658 disk->major = major;
636 disk->first_minor = unit << UBD_SHIFT; 659 disk->first_minor = unit << UBD_SHIFT;
@@ -645,6 +668,8 @@ static int ubd_disk_register(int major, u64 size, int unit,
645 if (major == MAJOR_NR) { 668 if (major == MAJOR_NR) {
646 ubd_devs[unit].pdev.id = unit; 669 ubd_devs[unit].pdev.id = unit;
647 ubd_devs[unit].pdev.name = DRIVER_NAME; 670 ubd_devs[unit].pdev.name = DRIVER_NAME;
671 ubd_devs[unit].pdev.dev.release = ubd_device_release;
672 ubd_devs[unit].pdev.dev.driver_data = &ubd_devs[unit];
648 platform_device_register(&ubd_devs[unit].pdev); 673 platform_device_register(&ubd_devs[unit].pdev);
649 disk->driverfs_dev = &ubd_devs[unit].pdev.dev; 674 disk->driverfs_dev = &ubd_devs[unit].pdev.dev;
650 } 675 }
@@ -675,6 +700,8 @@ static int ubd_add(int n, char **error_out)
675 700
676 ubd_dev->size = ROUND_BLOCK(ubd_dev->size); 701 ubd_dev->size = ROUND_BLOCK(ubd_dev->size);
677 702
703 INIT_LIST_HEAD(&ubd_dev->restart);
704
678 err = -ENOMEM; 705 err = -ENOMEM;
679 ubd_dev->queue = blk_init_queue(do_ubd_request, &ubd_dev->lock); 706 ubd_dev->queue = blk_init_queue(do_ubd_request, &ubd_dev->lock);
680 if (ubd_dev->queue == NULL) { 707 if (ubd_dev->queue == NULL) {
@@ -683,6 +710,7 @@ static int ubd_add(int n, char **error_out)
683 } 710 }
684 ubd_dev->queue->queuedata = ubd_dev; 711 ubd_dev->queue->queuedata = ubd_dev;
685 712
713 blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG);
686 err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]); 714 err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]);
687 if(err){ 715 if(err){
688 *error_out = "Failed to register device"; 716 *error_out = "Failed to register device";
@@ -730,14 +758,14 @@ static int ubd_config(char *str, char **error_out)
730 goto err_free; 758 goto err_free;
731 } 759 }
732 760
733 mutex_lock(&ubd_lock); 761 mutex_lock(&ubd_lock);
734 ret = ubd_add(n, error_out); 762 ret = ubd_add(n, error_out);
735 if (ret) 763 if (ret)
736 ubd_devs[n].file = NULL; 764 ubd_devs[n].file = NULL;
737 mutex_unlock(&ubd_lock); 765 mutex_unlock(&ubd_lock);
738 766
739out: 767out:
740 return ret; 768 return ret;
741 769
742err_free: 770err_free:
743 kfree(str); 771 kfree(str);
@@ -752,7 +780,7 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out)
752 n = parse_unit(&name); 780 n = parse_unit(&name);
753 if((n >= MAX_DEV) || (n < 0)){ 781 if((n >= MAX_DEV) || (n < 0)){
754 *error_out = "ubd_get_config : device number out of range"; 782 *error_out = "ubd_get_config : device number out of range";
755 return(-1); 783 return -1;
756 } 784 }
757 785
758 ubd_dev = &ubd_devs[n]; 786 ubd_dev = &ubd_devs[n];
@@ -773,29 +801,27 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out)
773 801
774 out: 802 out:
775 mutex_unlock(&ubd_lock); 803 mutex_unlock(&ubd_lock);
776 return(len); 804 return len;
777} 805}
778 806
779static int ubd_id(char **str, int *start_out, int *end_out) 807static int ubd_id(char **str, int *start_out, int *end_out)
780{ 808{
781 int n; 809 int n;
782 810
783 n = parse_unit(str); 811 n = parse_unit(str);
784 *start_out = 0; 812 *start_out = 0;
785 *end_out = MAX_DEV - 1; 813 *end_out = MAX_DEV - 1;
786 return n; 814 return n;
787} 815}
788 816
789static int ubd_remove(int n, char **error_out) 817static int ubd_remove(int n, char **error_out)
790{ 818{
819 struct gendisk *disk = ubd_gendisk[n];
791 struct ubd *ubd_dev; 820 struct ubd *ubd_dev;
792 int err = -ENODEV; 821 int err = -ENODEV;
793 822
794 mutex_lock(&ubd_lock); 823 mutex_lock(&ubd_lock);
795 824
796 if(ubd_gendisk[n] == NULL)
797 goto out;
798
799 ubd_dev = &ubd_devs[n]; 825 ubd_dev = &ubd_devs[n];
800 826
801 if(ubd_dev->file == NULL) 827 if(ubd_dev->file == NULL)
@@ -806,9 +832,11 @@ static int ubd_remove(int n, char **error_out)
806 if(ubd_dev->count > 0) 832 if(ubd_dev->count > 0)
807 goto out; 833 goto out;
808 834
809 del_gendisk(ubd_gendisk[n]);
810 put_disk(ubd_gendisk[n]);
811 ubd_gendisk[n] = NULL; 835 ubd_gendisk[n] = NULL;
836 if(disk != NULL){
837 del_gendisk(disk);
838 put_disk(disk);
839 }
812 840
813 if(fake_gendisk[n] != NULL){ 841 if(fake_gendisk[n] != NULL){
814 del_gendisk(fake_gendisk[n]); 842 del_gendisk(fake_gendisk[n]);
@@ -816,10 +844,8 @@ static int ubd_remove(int n, char **error_out)
816 fake_gendisk[n] = NULL; 844 fake_gendisk[n] = NULL;
817 } 845 }
818 846
819 blk_cleanup_queue(ubd_dev->queue);
820 platform_device_unregister(&ubd_dev->pdev);
821 *ubd_dev = ((struct ubd) DEFAULT_UBD);
822 err = 0; 847 err = 0;
848 platform_device_unregister(&ubd_dev->pdev);
823out: 849out:
824 mutex_unlock(&ubd_lock); 850 mutex_unlock(&ubd_lock);
825 return err; 851 return err;
@@ -832,7 +858,7 @@ static struct mc_device ubd_mc = {
832 .list = LIST_HEAD_INIT(ubd_mc.list), 858 .list = LIST_HEAD_INIT(ubd_mc.list),
833 .name = "ubd", 859 .name = "ubd",
834 .config = ubd_config, 860 .config = ubd_config,
835 .get_config = ubd_get_config, 861 .get_config = ubd_get_config,
836 .id = ubd_id, 862 .id = ubd_id,
837 .remove = ubd_remove, 863 .remove = ubd_remove,
838}; 864};
@@ -854,7 +880,7 @@ static int __init ubd0_init(void)
854 ubd_dev->file = "root_fs"; 880 ubd_dev->file = "root_fs";
855 mutex_unlock(&ubd_lock); 881 mutex_unlock(&ubd_lock);
856 882
857 return(0); 883 return 0;
858} 884}
859 885
860__initcall(ubd0_init); 886__initcall(ubd0_init);
@@ -882,14 +908,14 @@ static int __init ubd_init(void)
882 return -1; 908 return -1;
883 } 909 }
884 platform_driver_register(&ubd_driver); 910 platform_driver_register(&ubd_driver);
885 mutex_lock(&ubd_lock); 911 mutex_lock(&ubd_lock);
886 for (i = 0; i < MAX_DEV; i++){ 912 for (i = 0; i < MAX_DEV; i++){
887 err = ubd_add(i, &error); 913 err = ubd_add(i, &error);
888 if(err) 914 if(err)
889 printk(KERN_ERR "Failed to initialize ubd device %d :" 915 printk(KERN_ERR "Failed to initialize ubd device %d :"
890 "%s\n", i, error); 916 "%s\n", i, error);
891 } 917 }
892 mutex_unlock(&ubd_lock); 918 mutex_unlock(&ubd_lock);
893 return 0; 919 return 0;
894} 920}
895 921
@@ -913,7 +939,7 @@ static int __init ubd_driver_init(void){
913 "ubd : Failed to start I/O thread (errno = %d) - " 939 "ubd : Failed to start I/O thread (errno = %d) - "
914 "falling back to synchronous I/O\n", -io_pid); 940 "falling back to synchronous I/O\n", -io_pid);
915 io_pid = -1; 941 io_pid = -1;
916 return(0); 942 return 0;
917 } 943 }
918 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, 944 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
919 IRQF_DISABLED, "ubd", ubd_devs); 945 IRQF_DISABLED, "ubd", ubd_devs);
@@ -948,7 +974,7 @@ static int ubd_open(struct inode *inode, struct file *filp)
948 err = -EROFS; 974 err = -EROFS;
949 }*/ 975 }*/
950 out: 976 out:
951 return(err); 977 return err;
952} 978}
953 979
954static int ubd_release(struct inode * inode, struct file * file) 980static int ubd_release(struct inode * inode, struct file * file)
@@ -958,7 +984,7 @@ static int ubd_release(struct inode * inode, struct file * file)
958 984
959 if(--ubd_dev->count == 0) 985 if(--ubd_dev->count == 0)
960 ubd_close_dev(ubd_dev); 986 ubd_close_dev(ubd_dev);
961 return(0); 987 return 0;
962} 988}
963 989
964static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask, 990static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
@@ -1014,7 +1040,7 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
1014 if(ubd_test_bit(sector + i, (unsigned char *) bitmap)) 1040 if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
1015 ubd_set_bit(i, (unsigned char *) 1041 ubd_set_bit(i, (unsigned char *)
1016 &req->sector_mask); 1042 &req->sector_mask);
1017 } 1043 }
1018 } 1044 }
1019 else cowify_bitmap(req->offset, req->length, &req->sector_mask, 1045 else cowify_bitmap(req->offset, req->length, &req->sector_mask,
1020 &req->cow_offset, bitmap, bitmap_offset, 1046 &req->cow_offset, bitmap, bitmap_offset,
@@ -1022,26 +1048,16 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
1022} 1048}
1023 1049
1024/* Called with dev->lock held */ 1050/* Called with dev->lock held */
1025static int prepare_request(struct request *req, struct io_thread_req *io_req) 1051static void prepare_request(struct request *req, struct io_thread_req *io_req,
1052 unsigned long long offset, int page_offset,
1053 int len, struct page *page)
1026{ 1054{
1027 struct gendisk *disk = req->rq_disk; 1055 struct gendisk *disk = req->rq_disk;
1028 struct ubd *ubd_dev = disk->private_data; 1056 struct ubd *ubd_dev = disk->private_data;
1029 __u64 offset;
1030 int len;
1031
1032 /* This should be impossible now */
1033 if((rq_data_dir(req) == WRITE) && !ubd_dev->openflags.w){
1034 printk("Write attempted on readonly ubd device %s\n",
1035 disk->disk_name);
1036 end_request(req, 0);
1037 return(1);
1038 }
1039
1040 offset = ((__u64) req->sector) << 9;
1041 len = req->current_nr_sectors << 9;
1042 1057
1043 io_req->req = req; 1058 io_req->req = req;
1044 io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd : ubd_dev->fd; 1059 io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd :
1060 ubd_dev->fd;
1045 io_req->fds[1] = ubd_dev->fd; 1061 io_req->fds[1] = ubd_dev->fd;
1046 io_req->cow_offset = -1; 1062 io_req->cow_offset = -1;
1047 io_req->offset = offset; 1063 io_req->offset = offset;
@@ -1052,45 +1068,66 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
1052 io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE; 1068 io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
1053 io_req->offsets[0] = 0; 1069 io_req->offsets[0] = 0;
1054 io_req->offsets[1] = ubd_dev->cow.data_offset; 1070 io_req->offsets[1] = ubd_dev->cow.data_offset;
1055 io_req->buffer = req->buffer; 1071 io_req->buffer = page_address(page) + page_offset;
1056 io_req->sectorsize = 1 << 9; 1072 io_req->sectorsize = 1 << 9;
1057 1073
1058 if(ubd_dev->cow.file != NULL) 1074 if(ubd_dev->cow.file != NULL)
1059 cowify_req(io_req, ubd_dev->cow.bitmap, ubd_dev->cow.bitmap_offset, 1075 cowify_req(io_req, ubd_dev->cow.bitmap,
1060 ubd_dev->cow.bitmap_len); 1076 ubd_dev->cow.bitmap_offset, ubd_dev->cow.bitmap_len);
1061 1077
1062 return(0);
1063} 1078}
1064 1079
1065/* Called with dev->lock held */ 1080/* Called with dev->lock held */
1066static void do_ubd_request(request_queue_t *q) 1081static void do_ubd_request(request_queue_t *q)
1067{ 1082{
1068 struct io_thread_req io_req; 1083 struct io_thread_req *io_req;
1069 struct request *req; 1084 struct request *req;
1070 int err, n; 1085 int n;
1071 1086
1072 if(thread_fd == -1){ 1087 while(1){
1073 while((req = elv_next_request(q)) != NULL){
1074 err = prepare_request(req, &io_req);
1075 if(!err){
1076 do_io(&io_req);
1077 __ubd_finish(req, io_req.error);
1078 }
1079 }
1080 }
1081 else {
1082 struct ubd *dev = q->queuedata; 1088 struct ubd *dev = q->queuedata;
1083 if(dev->active || (req = elv_next_request(q)) == NULL) 1089 if(dev->end_sg == 0){
1084 return; 1090 struct request *req = elv_next_request(q);
1085 err = prepare_request(req, &io_req); 1091 if(req == NULL)
1086 if(!err){ 1092 return;
1087 dev->active = 1; 1093
1088 n = os_write_file(thread_fd, (char *) &io_req, 1094 dev->request = req;
1089 sizeof(io_req)); 1095 blkdev_dequeue_request(req);
1090 if(n != sizeof(io_req)) 1096 dev->start_sg = 0;
1091 printk("write to io thread failed, " 1097 dev->end_sg = blk_rq_map_sg(q, req, dev->sg);
1092 "errno = %d\n", -n);
1093 } 1098 }
1099
1100 req = dev->request;
1101 while(dev->start_sg < dev->end_sg){
1102 struct scatterlist *sg = &dev->sg[dev->start_sg];
1103
1104 io_req = kmalloc(sizeof(struct io_thread_req),
1105 GFP_ATOMIC);
1106 if(io_req == NULL){
1107 if(list_empty(&dev->restart))
1108 list_add(&dev->restart, &restart);
1109 return;
1110 }
1111 prepare_request(req, io_req,
1112 (unsigned long long) req->sector << 9,
1113 sg->offset, sg->length, sg->page);
1114
1115 n = os_write_file(thread_fd, &io_req,
1116 sizeof(struct io_thread_req *));
1117 if(n != sizeof(struct io_thread_req *)){
1118 if(n != -EAGAIN)
1119 printk("write to io thread failed, "
1120 "errno = %d\n", -n);
1121 else if(list_empty(&dev->restart))
1122 list_add(&dev->restart, &restart);
1123 return;
1124 }
1125
1126 req->sector += sg->length >> 9;
1127 dev->start_sg++;
1128 }
1129 dev->end_sg = 0;
1130 dev->request = NULL;
1094 } 1131 }
1095} 1132}
1096 1133
@@ -1120,21 +1157,21 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
1120 ubd_id.cyls = ubd_dev->size / (128 * 32 * 512); 1157 ubd_id.cyls = ubd_dev->size / (128 * 32 * 512);
1121 if(copy_to_user((char __user *) arg, (char *) &ubd_id, 1158 if(copy_to_user((char __user *) arg, (char *) &ubd_id,
1122 sizeof(ubd_id))) 1159 sizeof(ubd_id)))
1123 return(-EFAULT); 1160 return -EFAULT;
1124 return(0); 1161 return 0;
1125 1162
1126 case CDROMVOLREAD: 1163 case CDROMVOLREAD:
1127 if(copy_from_user(&volume, (char __user *) arg, sizeof(volume))) 1164 if(copy_from_user(&volume, (char __user *) arg, sizeof(volume)))
1128 return(-EFAULT); 1165 return -EFAULT;
1129 volume.channel0 = 255; 1166 volume.channel0 = 255;
1130 volume.channel1 = 255; 1167 volume.channel1 = 255;
1131 volume.channel2 = 255; 1168 volume.channel2 = 255;
1132 volume.channel3 = 255; 1169 volume.channel3 = 255;
1133 if(copy_to_user((char __user *) arg, &volume, sizeof(volume))) 1170 if(copy_to_user((char __user *) arg, &volume, sizeof(volume)))
1134 return(-EFAULT); 1171 return -EFAULT;
1135 return(0); 1172 return 0;
1136 } 1173 }
1137 return(-EINVAL); 1174 return -EINVAL;
1138} 1175}
1139 1176
1140static int path_requires_switch(char *from_cmdline, char *from_cow, char *cow) 1177static int path_requires_switch(char *from_cmdline, char *from_cow, char *cow)
@@ -1176,29 +1213,29 @@ static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
1176 if(err < 0){ 1213 if(err < 0){
1177 printk("Failed to get modification time of backing file " 1214 printk("Failed to get modification time of backing file "
1178 "\"%s\", err = %d\n", file, -err); 1215 "\"%s\", err = %d\n", file, -err);
1179 return(err); 1216 return err;
1180 } 1217 }
1181 1218
1182 err = os_file_size(file, &actual); 1219 err = os_file_size(file, &actual);
1183 if(err < 0){ 1220 if(err < 0){
1184 printk("Failed to get size of backing file \"%s\", " 1221 printk("Failed to get size of backing file \"%s\", "
1185 "err = %d\n", file, -err); 1222 "err = %d\n", file, -err);
1186 return(err); 1223 return err;
1187 } 1224 }
1188 1225
1189 if(actual != size){ 1226 if(actual != size){
1190 /*__u64 can be a long on AMD64 and with %lu GCC complains; so 1227 /*__u64 can be a long on AMD64 and with %lu GCC complains; so
1191 * the typecast.*/ 1228 * the typecast.*/
1192 printk("Size mismatch (%llu vs %llu) of COW header vs backing " 1229 printk("Size mismatch (%llu vs %llu) of COW header vs backing "
1193 "file\n", (unsigned long long) size, actual); 1230 "file\n", (unsigned long long) size, actual);
1194 return(-EINVAL); 1231 return -EINVAL;
1195 } 1232 }
1196 if(modtime != mtime){ 1233 if(modtime != mtime){
1197 printk("mtime mismatch (%ld vs %ld) of COW header vs backing " 1234 printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
1198 "file\n", mtime, modtime); 1235 "file\n", mtime, modtime);
1199 return(-EINVAL); 1236 return -EINVAL;
1200 } 1237 }
1201 return(0); 1238 return 0;
1202} 1239}
1203 1240
1204int read_cow_bitmap(int fd, void *buf, int offset, int len) 1241int read_cow_bitmap(int fd, void *buf, int offset, int len)
@@ -1207,13 +1244,13 @@ int read_cow_bitmap(int fd, void *buf, int offset, int len)
1207 1244
1208 err = os_seek_file(fd, offset); 1245 err = os_seek_file(fd, offset);
1209 if(err < 0) 1246 if(err < 0)
1210 return(err); 1247 return err;
1211 1248
1212 err = os_read_file(fd, buf, len); 1249 err = os_read_file(fd, buf, len);
1213 if(err < 0) 1250 if(err < 0)
1214 return(err); 1251 return err;
1215 1252
1216 return(0); 1253 return 0;
1217} 1254}
1218 1255
1219int open_ubd_file(char *file, struct openflags *openflags, int shared, 1256int open_ubd_file(char *file, struct openflags *openflags, int shared,
@@ -1231,14 +1268,14 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared,
1231 if (fd < 0) { 1268 if (fd < 0) {
1232 if ((fd == -ENOENT) && (create_cow_out != NULL)) 1269 if ((fd == -ENOENT) && (create_cow_out != NULL))
1233 *create_cow_out = 1; 1270 *create_cow_out = 1;
1234 if (!openflags->w || 1271 if (!openflags->w ||
1235 ((fd != -EROFS) && (fd != -EACCES))) 1272 ((fd != -EROFS) && (fd != -EACCES)))
1236 return fd; 1273 return fd;
1237 openflags->w = 0; 1274 openflags->w = 0;
1238 fd = os_open_file(file, *openflags, mode); 1275 fd = os_open_file(file, *openflags, mode);
1239 if (fd < 0) 1276 if (fd < 0)
1240 return fd; 1277 return fd;
1241 } 1278 }
1242 1279
1243 if(shared) 1280 if(shared)
1244 printk("Not locking \"%s\" on the host\n", file); 1281 printk("Not locking \"%s\" on the host\n", file);
@@ -1252,7 +1289,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared,
1252 1289
1253 /* Successful return case! */ 1290 /* Successful return case! */
1254 if(backing_file_out == NULL) 1291 if(backing_file_out == NULL)
1255 return(fd); 1292 return fd;
1256 1293
1257 err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime, 1294 err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
1258 &size, &sectorsize, &align, bitmap_offset_out); 1295 &size, &sectorsize, &align, bitmap_offset_out);
@@ -1262,7 +1299,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared,
1262 goto out_close; 1299 goto out_close;
1263 } 1300 }
1264 if(err) 1301 if(err)
1265 return(fd); 1302 return fd;
1266 1303
1267 asked_switch = path_requires_switch(*backing_file_out, backing_file, file); 1304 asked_switch = path_requires_switch(*backing_file_out, backing_file, file);
1268 1305
@@ -1285,7 +1322,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared,
1285 cow_sizes(version, size, sectorsize, align, *bitmap_offset_out, 1322 cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
1286 bitmap_len_out, data_offset_out); 1323 bitmap_len_out, data_offset_out);
1287 1324
1288 return fd; 1325 return fd;
1289 out_close: 1326 out_close:
1290 os_close_file(fd); 1327 os_close_file(fd);
1291 return err; 1328 return err;
@@ -1310,10 +1347,10 @@ int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
1310 bitmap_offset_out, bitmap_len_out, 1347 bitmap_offset_out, bitmap_len_out,
1311 data_offset_out); 1348 data_offset_out);
1312 if(!err) 1349 if(!err)
1313 return(fd); 1350 return fd;
1314 os_close_file(fd); 1351 os_close_file(fd);
1315 out: 1352 out:
1316 return(err); 1353 return err;
1317} 1354}
1318 1355
1319static int update_bitmap(struct io_thread_req *req) 1356static int update_bitmap(struct io_thread_req *req)
@@ -1321,23 +1358,23 @@ static int update_bitmap(struct io_thread_req *req)
1321 int n; 1358 int n;
1322 1359
1323 if(req->cow_offset == -1) 1360 if(req->cow_offset == -1)
1324 return(0); 1361 return 0;
1325 1362
1326 n = os_seek_file(req->fds[1], req->cow_offset); 1363 n = os_seek_file(req->fds[1], req->cow_offset);
1327 if(n < 0){ 1364 if(n < 0){
1328 printk("do_io - bitmap lseek failed : err = %d\n", -n); 1365 printk("do_io - bitmap lseek failed : err = %d\n", -n);
1329 return(1); 1366 return 1;
1330 } 1367 }
1331 1368
1332 n = os_write_file(req->fds[1], &req->bitmap_words, 1369 n = os_write_file(req->fds[1], &req->bitmap_words,
1333 sizeof(req->bitmap_words)); 1370 sizeof(req->bitmap_words));
1334 if(n != sizeof(req->bitmap_words)){ 1371 if(n != sizeof(req->bitmap_words)){
1335 printk("do_io - bitmap update failed, err = %d fd = %d\n", -n, 1372 printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
1336 req->fds[1]); 1373 req->fds[1]);
1337 return(1); 1374 return 1;
1338 } 1375 }
1339 1376
1340 return(0); 1377 return 0;
1341} 1378}
1342 1379
1343void do_io(struct io_thread_req *req) 1380void do_io(struct io_thread_req *req)
@@ -1409,13 +1446,14 @@ static int io_count = 0;
1409 1446
1410int io_thread(void *arg) 1447int io_thread(void *arg)
1411{ 1448{
1412 struct io_thread_req req; 1449 struct io_thread_req *req;
1413 int n; 1450 int n;
1414 1451
1415 ignore_sigwinch_sig(); 1452 ignore_sigwinch_sig();
1416 while(1){ 1453 while(1){
1417 n = os_read_file(kernel_fd, &req, sizeof(req)); 1454 n = os_read_file(kernel_fd, &req,
1418 if(n != sizeof(req)){ 1455 sizeof(struct io_thread_req *));
1456 if(n != sizeof(struct io_thread_req *)){
1419 if(n < 0) 1457 if(n < 0)
1420 printk("io_thread - read failed, fd = %d, " 1458 printk("io_thread - read failed, fd = %d, "
1421 "err = %d\n", kernel_fd, -n); 1459 "err = %d\n", kernel_fd, -n);
@@ -1426,9 +1464,10 @@ int io_thread(void *arg)
1426 continue; 1464 continue;
1427 } 1465 }
1428 io_count++; 1466 io_count++;
1429 do_io(&req); 1467 do_io(req);
1430 n = os_write_file(kernel_fd, &req, sizeof(req)); 1468 n = os_write_file(kernel_fd, &req,
1431 if(n != sizeof(req)) 1469 sizeof(struct io_thread_req *));
1470 if(n != sizeof(struct io_thread_req *))
1432 printk("io_thread - write failed, fd = %d, err = %d\n", 1471 printk("io_thread - write failed, fd = %d, err = %d\n",
1433 kernel_fd, -n); 1472 kernel_fd, -n);
1434 } 1473 }