aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/um/drivers/ubd_kern.c76
1 files changed, 43 insertions, 33 deletions
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index fa617e0719ab..0336575d2448 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -71,7 +71,7 @@ struct io_thread_req {
71 int error; 71 int error;
72}; 72};
73 73
74extern int open_ubd_file(char *file, struct openflags *openflags, 74extern int open_ubd_file(char *file, struct openflags *openflags, int shared,
75 char **backing_file_out, int *bitmap_offset_out, 75 char **backing_file_out, int *bitmap_offset_out,
76 unsigned long *bitmap_len_out, int *data_offset_out, 76 unsigned long *bitmap_len_out, int *data_offset_out,
77 int *create_cow_out); 77 int *create_cow_out);
@@ -137,7 +137,7 @@ static int fake_major = MAJOR_NR;
137 137
138static struct gendisk *ubd_gendisk[MAX_DEV]; 138static struct gendisk *ubd_gendisk[MAX_DEV];
139static struct gendisk *fake_gendisk[MAX_DEV]; 139static struct gendisk *fake_gendisk[MAX_DEV];
140 140
141#ifdef CONFIG_BLK_DEV_UBD_SYNC 141#ifdef CONFIG_BLK_DEV_UBD_SYNC
142#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \ 142#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
143 .cl = 1 }) 143 .cl = 1 })
@@ -168,6 +168,7 @@ struct ubd {
168 __u64 size; 168 __u64 size;
169 struct openflags boot_openflags; 169 struct openflags boot_openflags;
170 struct openflags openflags; 170 struct openflags openflags;
171 int shared;
171 int no_cow; 172 int no_cow;
172 struct cow cow; 173 struct cow cow;
173 struct platform_device pdev; 174 struct platform_device pdev;
@@ -189,6 +190,7 @@ struct ubd {
189 .boot_openflags = OPEN_FLAGS, \ 190 .boot_openflags = OPEN_FLAGS, \
190 .openflags = OPEN_FLAGS, \ 191 .openflags = OPEN_FLAGS, \
191 .no_cow = 0, \ 192 .no_cow = 0, \
193 .shared = 0, \
192 .cow = DEFAULT_COW, \ 194 .cow = DEFAULT_COW, \
193} 195}
194 196
@@ -305,7 +307,7 @@ static int ubd_setup_common(char *str, int *index_out)
305 } 307 }
306 major = simple_strtoul(str, &end, 0); 308 major = simple_strtoul(str, &end, 0);
307 if((*end != '\0') || (end == str)){ 309 if((*end != '\0') || (end == str)){
308 printk(KERN_ERR 310 printk(KERN_ERR
309 "ubd_setup : didn't parse major number\n"); 311 "ubd_setup : didn't parse major number\n");
310 return(1); 312 return(1);
311 } 313 }
@@ -316,7 +318,7 @@ static int ubd_setup_common(char *str, int *index_out)
316 printk(KERN_ERR "Can't assign a fake major twice\n"); 318 printk(KERN_ERR "Can't assign a fake major twice\n");
317 goto out1; 319 goto out1;
318 } 320 }
319 321
320 fake_major = major; 322 fake_major = major;
321 323
322 printk(KERN_INFO "Setting extra ubd major number to %d\n", 324 printk(KERN_INFO "Setting extra ubd major number to %d\n",
@@ -351,7 +353,7 @@ static int ubd_setup_common(char *str, int *index_out)
351 if (index_out) 353 if (index_out)
352 *index_out = n; 354 *index_out = n;
353 355
354 for (i = 0; i < 4; i++) { 356 for (i = 0; i < sizeof("rscd="); i++) {
355 switch (*str) { 357 switch (*str) {
356 case 'r': 358 case 'r':
357 flags.w = 0; 359 flags.w = 0;
@@ -362,11 +364,14 @@ static int ubd_setup_common(char *str, int *index_out)
362 case 'd': 364 case 'd':
363 dev->no_cow = 1; 365 dev->no_cow = 1;
364 break; 366 break;
367 case 'c':
368 dev->shared = 1;
369 break;
365 case '=': 370 case '=':
366 str++; 371 str++;
367 goto break_loop; 372 goto break_loop;
368 default: 373 default:
369 printk(KERN_ERR "ubd_setup : Expected '=' or flag letter (r,s or d)\n"); 374 printk(KERN_ERR "ubd_setup : Expected '=' or flag letter (r, s, c, or d)\n");
370 goto out; 375 goto out;
371 } 376 }
372 str++; 377 str++;
@@ -515,7 +520,7 @@ static void ubd_handler(void)
515 spin_unlock(&ubd_io_lock); 520 spin_unlock(&ubd_io_lock);
516 return; 521 return;
517 } 522 }
518 523
519 ubd_finish(rq, req.error); 524 ubd_finish(rq, req.error);
520 reactivate_fd(thread_fd, UBD_IRQ); 525 reactivate_fd(thread_fd, UBD_IRQ);
521 do_ubd_request(ubd_queue); 526 do_ubd_request(ubd_queue);
@@ -532,7 +537,7 @@ static int io_pid = -1;
532 537
533void kill_io_thread(void) 538void kill_io_thread(void)
534{ 539{
535 if(io_pid != -1) 540 if(io_pid != -1)
536 os_kill_process(io_pid, 1); 541 os_kill_process(io_pid, 1);
537} 542}
538 543
@@ -567,14 +572,15 @@ static int ubd_open_dev(struct ubd *dev)
567 create_cow = 0; 572 create_cow = 0;
568 create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL; 573 create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
569 back_ptr = dev->no_cow ? NULL : &dev->cow.file; 574 back_ptr = dev->no_cow ? NULL : &dev->cow.file;
570 dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr, 575 dev->fd = open_ubd_file(dev->file, &dev->openflags, dev->shared,
571 &dev->cow.bitmap_offset, &dev->cow.bitmap_len, 576 back_ptr, &dev->cow.bitmap_offset,
572 &dev->cow.data_offset, create_ptr); 577 &dev->cow.bitmap_len, &dev->cow.data_offset,
578 create_ptr);
573 579
574 if((dev->fd == -ENOENT) && create_cow){ 580 if((dev->fd == -ENOENT) && create_cow){
575 dev->fd = create_cow_file(dev->file, dev->cow.file, 581 dev->fd = create_cow_file(dev->file, dev->cow.file,
576 dev->openflags, 1 << 9, PAGE_SIZE, 582 dev->openflags, 1 << 9, PAGE_SIZE,
577 &dev->cow.bitmap_offset, 583 &dev->cow.bitmap_offset,
578 &dev->cow.bitmap_len, 584 &dev->cow.bitmap_len,
579 &dev->cow.data_offset); 585 &dev->cow.data_offset);
580 if(dev->fd >= 0){ 586 if(dev->fd >= 0){
@@ -598,16 +604,16 @@ static int ubd_open_dev(struct ubd *dev)
598 } 604 }
599 flush_tlb_kernel_vm(); 605 flush_tlb_kernel_vm();
600 606
601 err = read_cow_bitmap(dev->fd, dev->cow.bitmap, 607 err = read_cow_bitmap(dev->fd, dev->cow.bitmap,
602 dev->cow.bitmap_offset, 608 dev->cow.bitmap_offset,
603 dev->cow.bitmap_len); 609 dev->cow.bitmap_len);
604 if(err < 0) 610 if(err < 0)
605 goto error; 611 goto error;
606 612
607 flags = dev->openflags; 613 flags = dev->openflags;
608 flags.w = 0; 614 flags.w = 0;
609 err = open_ubd_file(dev->cow.file, &flags, NULL, NULL, NULL, 615 err = open_ubd_file(dev->cow.file, &flags, dev->shared, NULL,
610 NULL, NULL); 616 NULL, NULL, NULL, NULL);
611 if(err < 0) goto error; 617 if(err < 0) goto error;
612 dev->cow.fd = err; 618 dev->cow.fd = err;
613 } 619 }
@@ -685,11 +691,11 @@ static int ubd_add(int n)
685 dev->size = ROUND_BLOCK(dev->size); 691 dev->size = ROUND_BLOCK(dev->size);
686 692
687 err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]); 693 err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
688 if(err) 694 if(err)
689 goto out_close; 695 goto out_close;
690 696
691 if(fake_major != MAJOR_NR) 697 if(fake_major != MAJOR_NR)
692 ubd_new_disk(fake_major, dev->size, n, 698 ubd_new_disk(fake_major, dev->size, n,
693 &fake_gendisk[n]); 699 &fake_gendisk[n]);
694 700
695 /* perhaps this should also be under the "if (fake_major)" above */ 701 /* perhaps this should also be under the "if (fake_major)" above */
@@ -854,7 +860,7 @@ int ubd_init(void)
854 return -1; 860 return -1;
855 } 861 }
856 platform_driver_register(&ubd_driver); 862 platform_driver_register(&ubd_driver);
857 for (i = 0; i < MAX_DEV; i++) 863 for (i = 0; i < MAX_DEV; i++)
858 ubd_add(i); 864 ubd_add(i);
859 return 0; 865 return 0;
860} 866}
@@ -872,16 +878,16 @@ int ubd_driver_init(void){
872 * enough. So use anyway the io thread. */ 878 * enough. So use anyway the io thread. */
873 } 879 }
874 stack = alloc_stack(0, 0); 880 stack = alloc_stack(0, 0);
875 io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *), 881 io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
876 &thread_fd); 882 &thread_fd);
877 if(io_pid < 0){ 883 if(io_pid < 0){
878 printk(KERN_ERR 884 printk(KERN_ERR
879 "ubd : Failed to start I/O thread (errno = %d) - " 885 "ubd : Failed to start I/O thread (errno = %d) - "
880 "falling back to synchronous I/O\n", -io_pid); 886 "falling back to synchronous I/O\n", -io_pid);
881 io_pid = -1; 887 io_pid = -1;
882 return(0); 888 return(0);
883 } 889 }
884 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, 890 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
885 SA_INTERRUPT, "ubd", ubd_dev); 891 SA_INTERRUPT, "ubd", ubd_dev);
886 if(err != 0) 892 if(err != 0)
887 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err); 893 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
@@ -978,7 +984,7 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
978 if(req->op == UBD_READ) { 984 if(req->op == UBD_READ) {
979 for(i = 0; i < req->length >> 9; i++){ 985 for(i = 0; i < req->length >> 9; i++){
980 if(ubd_test_bit(sector + i, (unsigned char *) bitmap)) 986 if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
981 ubd_set_bit(i, (unsigned char *) 987 ubd_set_bit(i, (unsigned char *)
982 &req->sector_mask); 988 &req->sector_mask);
983 } 989 }
984 } 990 }
@@ -999,7 +1005,7 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
999 1005
1000 /* This should be impossible now */ 1006 /* This should be impossible now */
1001 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){ 1007 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
1002 printk("Write attempted on readonly ubd device %s\n", 1008 printk("Write attempted on readonly ubd device %s\n",
1003 disk->disk_name); 1009 disk->disk_name);
1004 end_request(req, 0); 1010 end_request(req, 0);
1005 return(1); 1011 return(1);
@@ -1182,7 +1188,7 @@ int read_cow_bitmap(int fd, void *buf, int offset, int len)
1182 return(0); 1188 return(0);
1183} 1189}
1184 1190
1185int open_ubd_file(char *file, struct openflags *openflags, 1191int open_ubd_file(char *file, struct openflags *openflags, int shared,
1186 char **backing_file_out, int *bitmap_offset_out, 1192 char **backing_file_out, int *bitmap_offset_out,
1187 unsigned long *bitmap_len_out, int *data_offset_out, 1193 unsigned long *bitmap_len_out, int *data_offset_out,
1188 int *create_cow_out) 1194 int *create_cow_out)
@@ -1206,10 +1212,14 @@ int open_ubd_file(char *file, struct openflags *openflags,
1206 return fd; 1212 return fd;
1207 } 1213 }
1208 1214
1209 err = os_lock_file(fd, openflags->w); 1215 if(shared)
1210 if(err < 0){ 1216 printk("Not locking \"%s\" on the host\n", file);
1211 printk("Failed to lock '%s', err = %d\n", file, -err); 1217 else {
1212 goto out_close; 1218 err = os_lock_file(fd, openflags->w);
1219 if(err < 0){
1220 printk("Failed to lock '%s', err = %d\n", file, -err);
1221 goto out_close;
1222 }
1213 } 1223 }
1214 1224
1215 /* Succesful return case! */ 1225 /* Succesful return case! */
@@ -1260,7 +1270,7 @@ int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
1260 int err, fd; 1270 int err, fd;
1261 1271
1262 flags.c = 1; 1272 flags.c = 1;
1263 fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL); 1273 fd = open_ubd_file(cow_file, &flags, 0, NULL, NULL, NULL, NULL, NULL);
1264 if(fd < 0){ 1274 if(fd < 0){
1265 err = fd; 1275 err = fd;
1266 printk("Open of COW file '%s' failed, errno = %d\n", cow_file, 1276 printk("Open of COW file '%s' failed, errno = %d\n", cow_file,