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.c570
1 files changed, 255 insertions, 315 deletions
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 344b24d09a7c..e77a38da4350 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -35,6 +35,7 @@
35#include "linux/blkpg.h" 35#include "linux/blkpg.h"
36#include "linux/genhd.h" 36#include "linux/genhd.h"
37#include "linux/spinlock.h" 37#include "linux/spinlock.h"
38#include "asm/atomic.h"
38#include "asm/segment.h" 39#include "asm/segment.h"
39#include "asm/uaccess.h" 40#include "asm/uaccess.h"
40#include "asm/irq.h" 41#include "asm/irq.h"
@@ -53,20 +54,21 @@
53#include "mem.h" 54#include "mem.h"
54#include "mem_kern.h" 55#include "mem_kern.h"
55#include "cow.h" 56#include "cow.h"
57#include "aio.h"
56 58
57enum ubd_req { UBD_READ, UBD_WRITE }; 59enum ubd_req { UBD_READ, UBD_WRITE };
58 60
59struct io_thread_req { 61struct io_thread_req {
60 enum ubd_req op; 62 enum aio_type op;
61 int fds[2]; 63 int fds[2];
62 unsigned long offsets[2]; 64 unsigned long offsets[2];
63 unsigned long long offset; 65 unsigned long long offset;
64 unsigned long length; 66 unsigned long length;
65 char *buffer; 67 char *buffer;
66 int sectorsize; 68 int sectorsize;
67 unsigned long sector_mask; 69 int bitmap_offset;
68 unsigned long long cow_offset; 70 long bitmap_start;
69 unsigned long bitmap_words[2]; 71 long bitmap_end;
70 int error; 72 int error;
71}; 73};
72 74
@@ -80,28 +82,31 @@ extern int create_cow_file(char *cow_file, char *backing_file,
80 unsigned long *bitmap_len_out, 82 unsigned long *bitmap_len_out,
81 int *data_offset_out); 83 int *data_offset_out);
82extern int read_cow_bitmap(int fd, void *buf, int offset, int len); 84extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
83extern void do_io(struct io_thread_req *req); 85extern void do_io(struct io_thread_req *req, struct request *r,
86 unsigned long *bitmap);
84 87
85static inline int ubd_test_bit(__u64 bit, unsigned char *data) 88static inline int ubd_test_bit(__u64 bit, void *data)
86{ 89{
90 unsigned char *buffer = data;
87 __u64 n; 91 __u64 n;
88 int bits, off; 92 int bits, off;
89 93
90 bits = sizeof(data[0]) * 8; 94 bits = sizeof(buffer[0]) * 8;
91 n = bit / bits; 95 n = bit / bits;
92 off = bit % bits; 96 off = bit % bits;
93 return((data[n] & (1 << off)) != 0); 97 return((buffer[n] & (1 << off)) != 0);
94} 98}
95 99
96static inline void ubd_set_bit(__u64 bit, unsigned char *data) 100static inline void ubd_set_bit(__u64 bit, void *data)
97{ 101{
102 unsigned char *buffer = data;
98 __u64 n; 103 __u64 n;
99 int bits, off; 104 int bits, off;
100 105
101 bits = sizeof(data[0]) * 8; 106 bits = sizeof(buffer[0]) * 8;
102 n = bit / bits; 107 n = bit / bits;
103 off = bit % bits; 108 off = bit % bits;
104 data[n] |= (1 << off); 109 buffer[n] |= (1 << off);
105} 110}
106/*End stuff from ubd_user.h*/ 111/*End stuff from ubd_user.h*/
107 112
@@ -110,8 +115,6 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data)
110static DEFINE_SPINLOCK(ubd_io_lock); 115static DEFINE_SPINLOCK(ubd_io_lock);
111static DEFINE_SPINLOCK(ubd_lock); 116static DEFINE_SPINLOCK(ubd_lock);
112 117
113static void (*do_ubd)(void);
114
115static int ubd_open(struct inode * inode, struct file * filp); 118static int ubd_open(struct inode * inode, struct file * filp);
116static int ubd_release(struct inode * inode, struct file * file); 119static int ubd_release(struct inode * inode, struct file * file);
117static int ubd_ioctl(struct inode * inode, struct file * file, 120static int ubd_ioctl(struct inode * inode, struct file * file,
@@ -158,6 +161,8 @@ struct cow {
158 int data_offset; 161 int data_offset;
159}; 162};
160 163
164#define MAX_SG 64
165
161struct ubd { 166struct ubd {
162 char *file; 167 char *file;
163 int count; 168 int count;
@@ -168,6 +173,7 @@ struct ubd {
168 int no_cow; 173 int no_cow;
169 struct cow cow; 174 struct cow cow;
170 struct platform_device pdev; 175 struct platform_device pdev;
176 struct scatterlist sg[MAX_SG];
171}; 177};
172 178
173#define DEFAULT_COW { \ 179#define DEFAULT_COW { \
@@ -460,80 +466,113 @@ __uml_help(fakehd,
460); 466);
461 467
462static void do_ubd_request(request_queue_t * q); 468static void do_ubd_request(request_queue_t * q);
463 469static int in_ubd;
464/* Only changed by ubd_init, which is an initcall. */
465int thread_fd = -1;
466 470
467/* Changed by ubd_handler, which is serialized because interrupts only 471/* Changed by ubd_handler, which is serialized because interrupts only
468 * happen on CPU 0. 472 * happen on CPU 0.
469 */ 473 */
470int intr_count = 0; 474int intr_count = 0;
471 475
472/* call ubd_finish if you need to serialize */ 476static void ubd_end_request(struct request *req, int bytes, int uptodate)
473static void __ubd_finish(struct request *req, int error)
474{ 477{
475 int nsect; 478 if (!end_that_request_first(req, uptodate, bytes >> 9)) {
476 479 add_disk_randomness(req->rq_disk);
477 if(error){ 480 end_that_request_last(req);
478 end_request(req, 0);
479 return;
480 } 481 }
481 nsect = req->current_nr_sectors;
482 req->sector += nsect;
483 req->buffer += nsect << 9;
484 req->errors = 0;
485 req->nr_sectors -= nsect;
486 req->current_nr_sectors = 0;
487 end_request(req, 1);
488} 482}
489 483
490static inline void ubd_finish(struct request *req, int error) 484/* call ubd_finish if you need to serialize */
485static void __ubd_finish(struct request *req, int bytes)
491{ 486{
492 spin_lock(&ubd_io_lock); 487 if(bytes < 0){
493 __ubd_finish(req, error); 488 ubd_end_request(req, 0, 0);
494 spin_unlock(&ubd_io_lock); 489 return;
490 }
491
492 ubd_end_request(req, bytes, 1);
495} 493}
496 494
497/* Called without ubd_io_lock held */ 495static inline void ubd_finish(struct request *req, int bytes)
498static void ubd_handler(void)
499{ 496{
500 struct io_thread_req req; 497 spin_lock(&ubd_io_lock);
501 struct request *rq = elv_next_request(ubd_queue); 498 __ubd_finish(req, bytes);
502 int n; 499 spin_unlock(&ubd_io_lock);
503
504 do_ubd = NULL;
505 intr_count++;
506 n = os_read_file(thread_fd, &req, sizeof(req));
507 if(n != sizeof(req)){
508 printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
509 "err = %d\n", os_getpid(), -n);
510 spin_lock(&ubd_io_lock);
511 end_request(rq, 0);
512 spin_unlock(&ubd_io_lock);
513 return;
514 }
515
516 ubd_finish(rq, req.error);
517 reactivate_fd(thread_fd, UBD_IRQ);
518 do_ubd_request(ubd_queue);
519} 500}
520 501
502struct bitmap_io {
503 atomic_t count;
504 struct aio_context aio;
505};
506
507struct ubd_aio {
508 struct aio_context aio;
509 struct request *req;
510 int len;
511 struct bitmap_io *bitmap;
512 void *bitmap_buf;
513};
514
515static int ubd_reply_fd = -1;
516
521static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused) 517static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused)
522{ 518{
523 ubd_handler(); 519 struct aio_thread_reply reply;
524 return(IRQ_HANDLED); 520 struct ubd_aio *aio;
525} 521 struct request *req;
522 int err, n, fd = (int) (long) dev;
523
524 while(1){
525 err = os_read_file(fd, &reply, sizeof(reply));
526 if(err == -EAGAIN)
527 break;
528 if(err < 0){
529 printk("ubd_aio_handler - read returned err %d\n",
530 -err);
531 break;
532 }
526 533
527/* Only changed by ubd_init, which is an initcall. */ 534 aio = container_of(reply.data, struct ubd_aio, aio);
528static int io_pid = -1; 535 n = reply.err;
529 536
530void kill_io_thread(void) 537 if(n == 0){
531{ 538 req = aio->req;
532 if(io_pid != -1) 539 req->nr_sectors -= aio->len >> 9;
533 os_kill_process(io_pid, 1); 540
534} 541 if((aio->bitmap != NULL) &&
542 (atomic_dec_and_test(&aio->bitmap->count))){
543 aio->aio = aio->bitmap->aio;
544 aio->len = 0;
545 kfree(aio->bitmap);
546 aio->bitmap = NULL;
547 submit_aio(&aio->aio);
548 }
549 else {
550 if((req->nr_sectors == 0) &&
551 (aio->bitmap == NULL)){
552 int len = req->hard_nr_sectors << 9;
553 ubd_finish(req, len);
554 }
555
556 if(aio->bitmap_buf != NULL)
557 kfree(aio->bitmap_buf);
558 kfree(aio);
559 }
560 }
561 else if(n < 0){
562 ubd_finish(aio->req, n);
563 if(aio->bitmap != NULL)
564 kfree(aio->bitmap);
565 if(aio->bitmap_buf != NULL)
566 kfree(aio->bitmap_buf);
567 kfree(aio);
568 }
569 }
570 reactivate_fd(fd, UBD_IRQ);
535 571
536__uml_exitcall(kill_io_thread); 572 do_ubd_request(ubd_queue);
573
574 return(IRQ_HANDLED);
575}
537 576
538static int ubd_file_size(struct ubd *dev, __u64 *size_out) 577static int ubd_file_size(struct ubd *dev, __u64 *size_out)
539{ 578{
@@ -569,7 +608,7 @@ static int ubd_open_dev(struct ubd *dev)
569 &dev->cow.data_offset, create_ptr); 608 &dev->cow.data_offset, create_ptr);
570 609
571 if((dev->fd == -ENOENT) && create_cow){ 610 if((dev->fd == -ENOENT) && create_cow){
572 dev->fd = create_cow_file(dev->file, dev->cow.file, 611 dev->fd = create_cow_file(dev->file, dev->cow.file,
573 dev->openflags, 1 << 9, PAGE_SIZE, 612 dev->openflags, 1 << 9, PAGE_SIZE,
574 &dev->cow.bitmap_offset, 613 &dev->cow.bitmap_offset,
575 &dev->cow.bitmap_len, 614 &dev->cow.bitmap_len,
@@ -668,21 +707,22 @@ static int ubd_add(int n)
668 struct ubd *dev = &ubd_dev[n]; 707 struct ubd *dev = &ubd_dev[n];
669 int err; 708 int err;
670 709
710 err = -ENODEV;
671 if(dev->file == NULL) 711 if(dev->file == NULL)
672 return(-ENODEV); 712 goto out;
673 713
674 if (ubd_open_dev(dev)) 714 if (ubd_open_dev(dev))
675 return(-ENODEV); 715 goto out;
676 716
677 err = ubd_file_size(dev, &dev->size); 717 err = ubd_file_size(dev, &dev->size);
678 if(err < 0) 718 if(err < 0)
679 return(err); 719 goto out_close;
680 720
681 dev->size = ROUND_BLOCK(dev->size); 721 dev->size = ROUND_BLOCK(dev->size);
682 722
683 err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]); 723 err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
684 if(err) 724 if(err)
685 return(err); 725 goto out_close;
686 726
687 if(fake_major != MAJOR_NR) 727 if(fake_major != MAJOR_NR)
688 ubd_new_disk(fake_major, dev->size, n, 728 ubd_new_disk(fake_major, dev->size, n,
@@ -693,8 +733,11 @@ static int ubd_add(int n)
693 if (fake_ide) 733 if (fake_ide)
694 make_ide_entries(ubd_gendisk[n]->disk_name); 734 make_ide_entries(ubd_gendisk[n]->disk_name);
695 735
736 err = 0;
737out_close:
696 ubd_close(dev); 738 ubd_close(dev);
697 return 0; 739out:
740 return err;
698} 741}
699 742
700static int ubd_config(char *str) 743static int ubd_config(char *str)
@@ -827,6 +870,10 @@ int ubd_init(void)
827{ 870{
828 int i; 871 int i;
829 872
873 ubd_reply_fd = init_aio_irq(UBD_IRQ, "ubd", ubd_intr);
874 if(ubd_reply_fd < 0)
875 printk("Setting up ubd AIO failed, err = %d\n", ubd_reply_fd);
876
830 devfs_mk_dir("ubd"); 877 devfs_mk_dir("ubd");
831 if (register_blkdev(MAJOR_NR, "ubd")) 878 if (register_blkdev(MAJOR_NR, "ubd"))
832 return -1; 879 return -1;
@@ -837,6 +884,7 @@ int ubd_init(void)
837 return -1; 884 return -1;
838 } 885 }
839 886
887 blk_queue_max_hw_segments(ubd_queue, MAX_SG);
840 if (fake_major != MAJOR_NR) { 888 if (fake_major != MAJOR_NR) {
841 char name[sizeof("ubd_nnn\0")]; 889 char name[sizeof("ubd_nnn\0")];
842 890
@@ -848,40 +896,12 @@ int ubd_init(void)
848 driver_register(&ubd_driver); 896 driver_register(&ubd_driver);
849 for (i = 0; i < MAX_DEV; i++) 897 for (i = 0; i < MAX_DEV; i++)
850 ubd_add(i); 898 ubd_add(i);
899
851 return 0; 900 return 0;
852} 901}
853 902
854late_initcall(ubd_init); 903late_initcall(ubd_init);
855 904
856int ubd_driver_init(void){
857 unsigned long stack;
858 int err;
859
860 /* Set by CONFIG_BLK_DEV_UBD_SYNC or ubd=sync.*/
861 if(global_openflags.s){
862 printk(KERN_INFO "ubd: Synchronous mode\n");
863 /* Letting ubd=sync be like using ubd#s= instead of ubd#= is
864 * enough. So use anyway the io thread. */
865 }
866 stack = alloc_stack(0, 0);
867 io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
868 &thread_fd);
869 if(io_pid < 0){
870 printk(KERN_ERR
871 "ubd : Failed to start I/O thread (errno = %d) - "
872 "falling back to synchronous I/O\n", -io_pid);
873 io_pid = -1;
874 return(0);
875 }
876 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
877 SA_INTERRUPT, "ubd", ubd_dev);
878 if(err != 0)
879 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
880 return(err);
881}
882
883device_initcall(ubd_driver_init);
884
885static int ubd_open(struct inode *inode, struct file *filp) 905static int ubd_open(struct inode *inode, struct file *filp)
886{ 906{
887 struct gendisk *disk = inode->i_bdev->bd_disk; 907 struct gendisk *disk = inode->i_bdev->bd_disk;
@@ -919,105 +939,55 @@ static int ubd_release(struct inode * inode, struct file * file)
919 return(0); 939 return(0);
920} 940}
921 941
922static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask, 942static void cowify_bitmap(struct io_thread_req *req, unsigned long *bitmap)
923 __u64 *cow_offset, unsigned long *bitmap,
924 __u64 bitmap_offset, unsigned long *bitmap_words,
925 __u64 bitmap_len)
926{ 943{
927 __u64 sector = io_offset >> 9; 944 __u64 sector = req->offset / req->sectorsize;
928 int i, update_bitmap = 0; 945 int i;
929
930 for(i = 0; i < length >> 9; i++){
931 if(cow_mask != NULL)
932 ubd_set_bit(i, (unsigned char *) cow_mask);
933 if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
934 continue;
935
936 update_bitmap = 1;
937 ubd_set_bit(sector + i, (unsigned char *) bitmap);
938 }
939
940 if(!update_bitmap)
941 return;
942
943 *cow_offset = sector / (sizeof(unsigned long) * 8);
944
945 /* This takes care of the case where we're exactly at the end of the
946 * device, and *cow_offset + 1 is off the end. So, just back it up
947 * by one word. Thanks to Lynn Kerby for the fix and James McMechan
948 * for the original diagnosis.
949 */
950 if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) /
951 sizeof(unsigned long) - 1))
952 (*cow_offset)--;
953
954 bitmap_words[0] = bitmap[*cow_offset];
955 bitmap_words[1] = bitmap[*cow_offset + 1];
956
957 *cow_offset *= sizeof(unsigned long);
958 *cow_offset += bitmap_offset;
959}
960 946
961static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, 947 for(i = 0; i < req->length / req->sectorsize; i++){
962 __u64 bitmap_offset, __u64 bitmap_len) 948 if(ubd_test_bit(sector + i, bitmap))
963{ 949 continue;
964 __u64 sector = req->offset >> 9;
965 int i;
966 950
967 if(req->length > (sizeof(req->sector_mask) * 8) << 9) 951 if(req->bitmap_start == -1)
968 panic("Operation too long"); 952 req->bitmap_start = sector + i;
953 req->bitmap_end = sector + i + 1;
969 954
970 if(req->op == UBD_READ) { 955 ubd_set_bit(sector + i, bitmap);
971 for(i = 0; i < req->length >> 9; i++){ 956 }
972 if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
973 ubd_set_bit(i, (unsigned char *)
974 &req->sector_mask);
975 }
976 }
977 else cowify_bitmap(req->offset, req->length, &req->sector_mask,
978 &req->cow_offset, bitmap, bitmap_offset,
979 req->bitmap_words, bitmap_len);
980} 957}
981 958
982/* Called with ubd_io_lock held */ 959/* Called with ubd_io_lock held */
983static int prepare_request(struct request *req, struct io_thread_req *io_req) 960static int prepare_request(struct request *req, struct io_thread_req *io_req,
961 unsigned long long offset, int page_offset,
962 int len, struct page *page)
984{ 963{
985 struct gendisk *disk = req->rq_disk; 964 struct gendisk *disk = req->rq_disk;
986 struct ubd *dev = disk->private_data; 965 struct ubd *dev = disk->private_data;
987 __u64 offset;
988 int len;
989
990 if(req->rq_status == RQ_INACTIVE) return(1);
991 966
992 /* This should be impossible now */ 967 /* This should be impossible now */
993 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){ 968 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
994 printk("Write attempted on readonly ubd device %s\n", 969 printk("Write attempted on readonly ubd device %s\n",
995 disk->disk_name); 970 disk->disk_name);
996 end_request(req, 0); 971 ubd_end_request(req, 0, 0);
997 return(1); 972 return(1);
998 } 973 }
999 974
1000 offset = ((__u64) req->sector) << 9;
1001 len = req->current_nr_sectors << 9;
1002
1003 io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd; 975 io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
1004 io_req->fds[1] = dev->fd; 976 io_req->fds[1] = dev->fd;
1005 io_req->cow_offset = -1;
1006 io_req->offset = offset; 977 io_req->offset = offset;
1007 io_req->length = len; 978 io_req->length = len;
1008 io_req->error = 0; 979 io_req->error = 0;
1009 io_req->sector_mask = 0; 980 io_req->op = (rq_data_dir(req) == READ) ? AIO_READ : AIO_WRITE;
1010
1011 io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
1012 io_req->offsets[0] = 0; 981 io_req->offsets[0] = 0;
1013 io_req->offsets[1] = dev->cow.data_offset; 982 io_req->offsets[1] = dev->cow.data_offset;
1014 io_req->buffer = req->buffer; 983 io_req->buffer = page_address(page) + page_offset;
1015 io_req->sectorsize = 1 << 9; 984 io_req->sectorsize = 1 << 9;
985 io_req->bitmap_offset = dev->cow.bitmap_offset;
986 io_req->bitmap_start = -1;
987 io_req->bitmap_end = -1;
1016 988
1017 if(dev->cow.file != NULL) 989 if((dev->cow.file != NULL) && (io_req->op == UBD_WRITE))
1018 cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset, 990 cowify_bitmap(io_req, dev->cow.bitmap);
1019 dev->cow.bitmap_len);
1020
1021 return(0); 991 return(0);
1022} 992}
1023 993
@@ -1026,30 +996,36 @@ static void do_ubd_request(request_queue_t *q)
1026{ 996{
1027 struct io_thread_req io_req; 997 struct io_thread_req io_req;
1028 struct request *req; 998 struct request *req;
1029 int err, n; 999 __u64 sector;
1030 1000 int err;
1031 if(thread_fd == -1){ 1001
1032 while((req = elv_next_request(q)) != NULL){ 1002 if(in_ubd)
1033 err = prepare_request(req, &io_req); 1003 return;
1034 if(!err){ 1004 in_ubd = 1;
1035 do_io(&io_req); 1005 while((req = elv_next_request(q)) != NULL){
1036 __ubd_finish(req, io_req.error); 1006 struct gendisk *disk = req->rq_disk;
1037 } 1007 struct ubd *dev = disk->private_data;
1038 } 1008 int n, i;
1039 } 1009
1040 else { 1010 blkdev_dequeue_request(req);
1041 if(do_ubd || (req = elv_next_request(q)) == NULL) 1011
1042 return; 1012 sector = req->sector;
1043 err = prepare_request(req, &io_req); 1013 n = blk_rq_map_sg(q, req, dev->sg);
1044 if(!err){ 1014
1045 do_ubd = ubd_handler; 1015 for(i = 0; i < n; i++){
1046 n = os_write_file(thread_fd, (char *) &io_req, 1016 struct scatterlist *sg = &dev->sg[i];
1047 sizeof(io_req)); 1017
1048 if(n != sizeof(io_req)) 1018 err = prepare_request(req, &io_req, sector << 9,
1049 printk("write to io thread failed, " 1019 sg->offset, sg->length,
1050 "errno = %d\n", -n); 1020 sg->page);
1021 if(err)
1022 continue;
1023
1024 sector += sg->length >> 9;
1025 do_io(&io_req, req, dev->cow.bitmap);
1051 } 1026 }
1052 } 1027 }
1028 in_ubd = 0;
1053} 1029}
1054 1030
1055static int ubd_ioctl(struct inode * inode, struct file * file, 1031static int ubd_ioctl(struct inode * inode, struct file * file,
@@ -1265,131 +1241,95 @@ int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
1265 return(err); 1241 return(err);
1266} 1242}
1267 1243
1268static int update_bitmap(struct io_thread_req *req) 1244void do_io(struct io_thread_req *req, struct request *r, unsigned long *bitmap)
1269{
1270 int n;
1271
1272 if(req->cow_offset == -1)
1273 return(0);
1274
1275 n = os_seek_file(req->fds[1], req->cow_offset);
1276 if(n < 0){
1277 printk("do_io - bitmap lseek failed : err = %d\n", -n);
1278 return(1);
1279 }
1280
1281 n = os_write_file(req->fds[1], &req->bitmap_words,
1282 sizeof(req->bitmap_words));
1283 if(n != sizeof(req->bitmap_words)){
1284 printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
1285 req->fds[1]);
1286 return(1);
1287 }
1288
1289 return(0);
1290}
1291
1292void do_io(struct io_thread_req *req)
1293{ 1245{
1294 char *buf; 1246 struct ubd_aio *aio;
1295 unsigned long len; 1247 struct bitmap_io *bitmap_io = NULL;
1296 int n, nsectors, start, end, bit; 1248 char *buf;
1297 int err; 1249 void *bitmap_buf = NULL;
1298 __u64 off; 1250 unsigned long len, sector;
1299 1251 int nsectors, start, end, bit, err;
1300 nsectors = req->length / req->sectorsize; 1252 __u64 off;
1301 start = 0; 1253
1302 do { 1254 if(req->bitmap_start != -1){
1303 bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask); 1255 /* Round up to the nearest word */
1304 end = start; 1256 int round = sizeof(unsigned long);
1305 while((end < nsectors) && 1257 len = (req->bitmap_end - req->bitmap_start +
1306 (ubd_test_bit(end, (unsigned char *) 1258 round * 8 - 1) / (round * 8);
1307 &req->sector_mask) == bit)) 1259 len *= round;
1308 end++; 1260
1309 1261 off = req->bitmap_start / (8 * round);
1310 off = req->offset + req->offsets[bit] + 1262 off *= round;
1311 start * req->sectorsize; 1263
1312 len = (end - start) * req->sectorsize; 1264 bitmap_io = kmalloc(sizeof(*bitmap_io), GFP_KERNEL);
1313 buf = &req->buffer[start * req->sectorsize]; 1265 if(bitmap_io == NULL){
1314 1266 printk("Failed to kmalloc bitmap IO\n");
1315 err = os_seek_file(req->fds[bit], off); 1267 req->error = 1;
1316 if(err < 0){ 1268 return;
1317 printk("do_io - lseek failed : err = %d\n", -err); 1269 }
1318 req->error = 1;
1319 return;
1320 }
1321 if(req->op == UBD_READ){
1322 n = 0;
1323 do {
1324 buf = &buf[n];
1325 len -= n;
1326 n = os_read_file(req->fds[bit], buf, len);
1327 if (n < 0) {
1328 printk("do_io - read failed, err = %d "
1329 "fd = %d\n", -n, req->fds[bit]);
1330 req->error = 1;
1331 return;
1332 }
1333 } while((n < len) && (n != 0));
1334 if (n < len) memset(&buf[n], 0, len - n);
1335 } else {
1336 n = os_write_file(req->fds[bit], buf, len);
1337 if(n != len){
1338 printk("do_io - write failed err = %d "
1339 "fd = %d\n", -n, req->fds[bit]);
1340 req->error = 1;
1341 return;
1342 }
1343 }
1344 1270
1345 start = end; 1271 bitmap_buf = kmalloc(len, GFP_KERNEL);
1346 } while(start < nsectors); 1272 if(bitmap_buf == NULL){
1273 printk("do_io : kmalloc of bitmap chunk "
1274 "failed\n");
1275 kfree(bitmap_io);
1276 req->error = 1;
1277 return;
1278 }
1279 memcpy(bitmap_buf, &bitmap[off / sizeof(bitmap[0])], len);
1280
1281 *bitmap_io = ((struct bitmap_io)
1282 { .count = ATOMIC_INIT(0),
1283 .aio = INIT_AIO(AIO_WRITE, req->fds[1],
1284 bitmap_buf, len,
1285 req->bitmap_offset + off,
1286 ubd_reply_fd) } );
1287 }
1347 1288
1348 req->error = update_bitmap(req); 1289 nsectors = req->length / req->sectorsize;
1349} 1290 start = 0;
1291 end = nsectors;
1292 bit = 0;
1293 do {
1294 if(bitmap != NULL){
1295 sector = req->offset / req->sectorsize;
1296 bit = ubd_test_bit(sector + start, bitmap);
1297 end = start;
1298 while((end < nsectors) &&
1299 (ubd_test_bit(sector + end, bitmap) == bit))
1300 end++;
1301 }
1350 1302
1351/* Changed in start_io_thread, which is serialized by being called only 1303 off = req->offsets[bit] + req->offset +
1352 * from ubd_init, which is an initcall. 1304 start * req->sectorsize;
1353 */ 1305 len = (end - start) * req->sectorsize;
1354int kernel_fd = -1; 1306 buf = &req->buffer[start * req->sectorsize];
1355 1307
1356/* Only changed by the io thread */ 1308 aio = kmalloc(sizeof(*aio), GFP_KERNEL);
1357int io_count = 0; 1309 if(aio == NULL){
1310 req->error = 1;
1311 return;
1312 }
1358 1313
1359int io_thread(void *arg) 1314 *aio = ((struct ubd_aio)
1360{ 1315 { .aio = INIT_AIO(req->op, req->fds[bit], buf,
1361 struct io_thread_req req; 1316 len, off, ubd_reply_fd),
1362 int n; 1317 .len = len,
1318 .req = r,
1319 .bitmap = bitmap_io,
1320 .bitmap_buf = bitmap_buf });
1321
1322 if(aio->bitmap != NULL)
1323 atomic_inc(&aio->bitmap->count);
1324
1325 err = submit_aio(&aio->aio);
1326 if(err){
1327 printk("do_io - submit_aio failed, "
1328 "err = %d\n", err);
1329 req->error = 1;
1330 return;
1331 }
1363 1332
1364 ignore_sigwinch_sig(); 1333 start = end;
1365 while(1){ 1334 } while(start < nsectors);
1366 n = os_read_file(kernel_fd, &req, sizeof(req));
1367 if(n != sizeof(req)){
1368 if(n < 0)
1369 printk("io_thread - read failed, fd = %d, "
1370 "err = %d\n", kernel_fd, -n);
1371 else {
1372 printk("io_thread - short read, fd = %d, "
1373 "length = %d\n", kernel_fd, n);
1374 }
1375 continue;
1376 }
1377 io_count++;
1378 do_io(&req);
1379 n = os_write_file(kernel_fd, &req, sizeof(req));
1380 if(n != sizeof(req))
1381 printk("io_thread - write failed, fd = %d, err = %d\n",
1382 kernel_fd, -n);
1383 }
1384} 1335}
1385
1386/*
1387 * Overrides for Emacs so that we follow Linus's tabbing style.
1388 * Emacs will notice this stuff at the end of the file and automatically
1389 * adjust the settings for this buffer only. This must remain at the end
1390 * of the file.
1391 * ---------------------------------------------------------------------------
1392 * Local variables:
1393 * c-file-style: "linux"
1394 * End:
1395 */