1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#define UBD_SHIFT 4
21
22#include "linux/kernel.h"
23#include "linux/module.h"
24#include "linux/blkdev.h"
25#include "linux/ata.h"
26#include "linux/hdreg.h"
27#include "linux/init.h"
28#include "linux/cdrom.h"
29#include "linux/proc_fs.h"
30#include "linux/ctype.h"
31#include "linux/capability.h"
32#include "linux/mm.h"
33#include "linux/vmalloc.h"
34#include "linux/blkpg.h"
35#include "linux/genhd.h"
36#include "linux/spinlock.h"
37#include "linux/platform_device.h"
38#include "linux/scatterlist.h"
39#include "asm/segment.h"
40#include "asm/uaccess.h"
41#include "asm/irq.h"
42#include "asm/types.h"
43#include "asm/tlbflush.h"
44#include "mem_user.h"
45#include "kern_util.h"
46#include "kern.h"
47#include "mconsole_kern.h"
48#include "init.h"
49#include "irq_user.h"
50#include "irq_kern.h"
51#include "ubd_user.h"
52#include "os.h"
53#include "mem.h"
54#include "mem_kern.h"
55#include "cow.h"
56
57enum ubd_req { UBD_READ, UBD_WRITE };
58
59struct io_thread_req {
60 struct request *req;
61 enum ubd_req op;
62 int fds[2];
63 unsigned long offsets[2];
64 unsigned long long offset;
65 unsigned long length;
66 char *buffer;
67 int sectorsize;
68 unsigned long sector_mask;
69 unsigned long long cow_offset;
70 unsigned long bitmap_words[2];
71 int error;
72};
73
74static inline int ubd_test_bit(__u64 bit, unsigned char *data)
75{
76 __u64 n;
77 int bits, off;
78
79 bits = sizeof(data[0]) * 8;
80 n = bit / bits;
81 off = bit % bits;
82 return (data[n] & (1 << off)) != 0;
83}
84
85static inline void ubd_set_bit(__u64 bit, unsigned char *data)
86{
87 __u64 n;
88 int bits, off;
89
90 bits = sizeof(data[0]) * 8;
91 n = bit / bits;
92 off = bit % bits;
93 data[n] |= (1 << off);
94}
95
96
97#define DRIVER_NAME "uml-blkdev"
98
99static DEFINE_MUTEX(ubd_lock);
100
101static int ubd_open(struct block_device *bdev, fmode_t mode);
102static int ubd_release(struct gendisk *disk, fmode_t mode);
103static int ubd_ioctl(struct block_device *bdev, fmode_t mode,
104 unsigned int cmd, unsigned long arg);
105static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
106
107#define MAX_DEV (16)
108
109static const struct block_device_operations ubd_blops = {
110 .owner = THIS_MODULE,
111 .open = ubd_open,
112 .release = ubd_release,
113 .ioctl = ubd_ioctl,
114 .getgeo = ubd_getgeo,
115};
116
117
118static int fake_major = UBD_MAJOR;
119static struct gendisk *ubd_gendisk[MAX_DEV];
120static struct gendisk *fake_gendisk[MAX_DEV];
121
122#ifdef CONFIG_BLK_DEV_UBD_SYNC
123#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
124 .cl = 1 })
125#else
126#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 0, .c = 0, \
127 .cl = 1 })
128#endif
129static struct openflags global_openflags = OPEN_FLAGS;
130
131struct cow {
132
133 char *file;
134
135 int fd;
136 unsigned long *bitmap;
137 unsigned long bitmap_len;
138 int bitmap_offset;
139 int data_offset;
140};
141
142#define MAX_SG 64
143
144struct ubd {
145 struct list_head restart;
146
147
148 char *file;
149 int count;
150 int fd;
151 __u64 size;
152 struct openflags boot_openflags;
153 struct openflags openflags;
154 unsigned shared:1;
155 unsigned no_cow:1;
156 struct cow cow;
157 struct platform_device pdev;
158 struct request_queue *queue;
159 spinlock_t lock;
160 struct scatterlist sg[MAX_SG];
161 struct request *request;
162 int start_sg, end_sg;
163};
164
165#define DEFAULT_COW { \
166 .file = NULL, \
167 .fd = -1, \
168 .bitmap = NULL, \
169 .bitmap_offset = 0, \
170 .data_offset = 0, \
171}
172
173#define DEFAULT_UBD { \
174 .file = NULL, \
175 .count = 0, \
176 .fd = -1, \
177 .size = -1, \
178 .boot_openflags = OPEN_FLAGS, \
179 .openflags = OPEN_FLAGS, \
180 .no_cow = 0, \
181 .shared = 0, \
182 .cow = DEFAULT_COW, \
183 .lock = SPIN_LOCK_UNLOCKED, \
184 .request = NULL, \
185 .start_sg = 0, \
186 .end_sg = 0, \
187}
188
189
190static struct ubd ubd_devs[MAX_DEV] = { [0 ... MAX_DEV - 1] = DEFAULT_UBD };
191
192
193static int fake_ide = 0;
194static struct proc_dir_entry *proc_ide_root = NULL;
195static struct proc_dir_entry *proc_ide = NULL;
196
197static void make_proc_ide(void)
198{
199 proc_ide_root = proc_mkdir("ide", NULL);
200 proc_ide = proc_mkdir("ide0", proc_ide_root);
201}
202
203static int proc_ide_read_media(char *page, char **start, off_t off, int count,
204 int *eof, void *data)
205{
206 int len;
207
208 strcpy(page, "disk\n");
209 len = strlen("disk\n");
210 len -= off;
211 if (len < count){
212 *eof = 1;
213 if (len <= 0) return 0;
214 }
215 else len = count;
216 *start = page + off;
217 return len;
218}
219
220static void make_ide_entries(const char *dev_name)
221{
222 struct proc_dir_entry *dir, *ent;
223 char name[64];
224
225 if(proc_ide_root == NULL) make_proc_ide();
226
227 dir = proc_mkdir(dev_name, proc_ide);
228 if(!dir) return;
229
230 ent = create_proc_entry("media", S_IFREG|S_IRUGO, dir);
231 if(!ent) return;
232 ent->data = NULL;
233 ent->read_proc = proc_ide_read_media;
234 ent->write_proc = NULL;
235 snprintf(name, sizeof(name), "ide0/%s", dev_name);
236 proc_symlink(dev_name, proc_ide_root, name);
237}
238
239static int fake_ide_setup(char *str)
240{
241 fake_ide = 1;
242 return 1;
243}
244
245__setup("fake_ide", fake_ide_setup);
246
247__uml_help(fake_ide_setup,
248"fake_ide\n"
249" Create ide0 entries that map onto ubd devices.\n\n"
250);
251
252static int parse_unit(char **ptr)
253{
254 char *str = *ptr, *end;
255 int n = -1;
256
257 if(isdigit(*str)) {
258 n = simple_strtoul(str, &end, 0);
259 if(end == str)
260 return -1;
261 *ptr = end;
262 }
263 else if (('a' <= *str) && (*str <= 'z')) {
264 n = *str - 'a';
265 str++;
266 *ptr = str;
267 }
268 return n;
269}
270
271
272
273
274
275static int ubd_setup_common(char *str, int *index_out, char **error_out)
276{
277 struct ubd *ubd_dev;
278 struct openflags flags = global_openflags;
279 char *backing_file;
280 int n, err = 0, i;
281
282 if(index_out) *index_out = -1;
283 n = *str;
284 if(n == '='){
285 char *end;
286 int major;
287
288 str++;
289 if(!strcmp(str, "sync")){
290 global_openflags = of_sync(global_openflags);
291 goto out1;
292 }
293
294 err = -EINVAL;
295 major = simple_strtoul(str, &end, 0);
296 if((*end != '\0') || (end == str)){
297 *error_out = "Didn't parse major number";
298 goto out1;
299 }
300
301 mutex_lock(&ubd_lock);
302 if (fake_major != UBD_MAJOR) {
303 *error_out = "Can't assign a fake major twice";
304 goto out1;
305 }
306
307 fake_major = major;
308
309 printk(KERN_INFO "Setting extra ubd major number to %d\n",
310 major);
311 err = 0;
312 out1:
313 mutex_unlock(&ubd_lock);
314 return err;
315 }
316
317 n = parse_unit(&str);
318 if(n < 0){
319 *error_out = "Couldn't parse device number";
320 return -EINVAL;
321 }
322 if(n >= MAX_DEV){
323 *error_out = "Device number out of range";
324 return 1;
325 }
326
327 err = -EBUSY;
328 mutex_lock(&ubd_lock);
329
330 ubd_dev = &ubd_devs[n];
331 if(ubd_dev->file != NULL){
332 *error_out = "Device is already configured";
333 goto out;
334 }
335
336 if (index_out)
337 *index_out = n;
338
339 err = -EINVAL;
340 for (i = 0; i < sizeof("rscd="); i++) {
341 switch (*str) {
342 case 'r':
343 flags.w = 0;
344 break;
345 case 's':
346 flags.s = 1;
347 break;
348 case 'd':
349 ubd_dev->no_cow = 1;
350 break;
351 case 'c':
352 ubd_dev->shared = 1;
353 break;
354 case '=':
355 str++;
356 goto break_loop;
357 default:
358 *error_out = "Expected '=' or flag letter "
359 "(r, s, c, or d)";
360 goto out;
361 }
362 str++;
363 }
364
365 if (*str == '=')
366 *error_out = "Too many flags specified";
367 else
368 *error_out = "Missing '='";
369 goto out;
370
371break_loop:
372 backing_file = strchr(str, ',');
373
374 if (backing_file == NULL)
375 backing_file = strchr(str, ':');
376
377 if(backing_file != NULL){
378 if(ubd_dev->no_cow){
379 *error_out = "Can't specify both 'd' and a cow file";
380 goto out;
381 }
382 else {
383 *backing_file = '\0';
384 backing_file++;
385 }
386 }
387 err = 0;
388 ubd_dev->file = str;
389 ubd_dev->cow.file = backing_file;
390 ubd_dev->boot_openflags = flags;
391out:
392 mutex_unlock(&ubd_lock);
393 return err;
394}
395
396static int ubd_setup(char *str)
397{
398 char *error;
399 int err;
400
401 err = ubd_setup_common(str, NULL, &error);
402 if(err)
403 printk(KERN_ERR "Failed to initialize device with \"%s\" : "
404 "%s\n", str, error);
405 return 1;
406}
407
408__setup("ubd", ubd_setup);
409__uml_help(ubd_setup,
410"ubd<n><flags>=<filename>[(:|,)<filename2>]\n"
411" This is used to associate a device with a file in the underlying\n"
412" filesystem. When specifying two filenames, the first one is the\n"
413" COW name and the second is the backing file name. As separator you can\n"
414" use either a ':' or a ',': the first one allows writing things like;\n"
415" ubd0=~/Uml/root_cow:~/Uml/root_backing_file\n"
416" while with a ',' the shell would not expand the 2nd '~'.\n"
417" When using only one filename, UML will detect whether to treat it like\n"
418" a COW file or a backing file. To override this detection, add the 'd'\n"
419" flag:\n"
420" ubd0d=BackingFile\n"
421" Usually, there is a filesystem in the file, but \n"
422" that's not required. Swap devices containing swap files can be\n"
423" specified like this. Also, a file which doesn't contain a\n"
424" filesystem can have its contents read in the virtual \n"
425" machine by running 'dd' on the device. <n> must be in the range\n"
426" 0 to 7. Appending an 'r' to the number will cause that device\n"
427" to be mounted read-only. For example ubd1r=./ext_fs. Appending\n"
428" an 's' will cause data to be written to disk on the host immediately.\n"
429" 'c' will cause the device to be treated as being shared between multiple\n"
430" UMLs and file locking will be turned off - this is appropriate for a\n"
431" cluster filesystem and inappropriate at almost all other times.\n\n"
432);
433
434static int udb_setup(char *str)
435{
436 printk("udb%s specified on command line is almost certainly a ubd -> "
437 "udb TYPO\n", str);
438 return 1;
439}
440
441__setup("udb", udb_setup);
442__uml_help(udb_setup,
443"udb\n"
444" This option is here solely to catch ubd -> udb typos, which can be\n"
445" to impossible to catch visually unless you specifically look for\n"
446" them. The only result of any option starting with 'udb' is an error\n"
447" in the boot output.\n\n"
448);
449
450static void do_ubd_request(struct request_queue * q);
451
452
453static int thread_fd = -1;
454static LIST_HEAD(restart);
455
456
457
458static void ubd_handler(void)
459{
460 struct io_thread_req *req;
461 struct ubd *ubd;
462 struct list_head *list, *next_ele;
463 unsigned long flags;
464 int n;
465
466 while(1){
467 n = os_read_file(thread_fd, &req,
468 sizeof(struct io_thread_req *));
469 if(n != sizeof(req)){
470 if(n == -EAGAIN)
471 break;
472 printk(KERN_ERR "spurious interrupt in ubd_handler, "
473 "err = %d\n", -n);
474 return;
475 }
476
477 blk_end_request(req->req, 0, req->length);
478 kfree(req);
479 }
480 reactivate_fd(thread_fd, UBD_IRQ);
481
482 list_for_each_safe(list, next_ele, &restart){
483 ubd = container_of(list, struct ubd, restart);
484 list_del_init(&ubd->restart);
485 spin_lock_irqsave(&ubd->lock, flags);
486 do_ubd_request(ubd->queue);
487 spin_unlock_irqrestore(&ubd->lock, flags);
488 }
489}
490
491static irqreturn_t ubd_intr(int irq, void *dev)
492{
493 ubd_handler();
494 return IRQ_HANDLED;
495}
496
497
498static int io_pid = -1;
499
500static void kill_io_thread(void)
501{
502 if(io_pid != -1)
503 os_kill_process(io_pid, 1);
504}
505
506__uml_exitcall(kill_io_thread);
507
508static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
509{
510 char *file;
511
512 file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file;
513 return os_file_size(file, size_out);
514}
515
516static int read_cow_bitmap(int fd, void *buf, int offset, int len)
517{
518 int err;
519
520 err = os_seek_file(fd, offset);
521 if (err < 0)
522 return err;
523
524 err = os_read_file(fd, buf, len);
525 if (err < 0)
526 return err;
527
528 return 0;
529}
530
531static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
532{
533 unsigned long modtime;
534 unsigned long long actual;
535 int err;
536
537 err = os_file_modtime(file, &modtime);
538 if (err < 0) {
539 printk(KERN_ERR "Failed to get modification time of backing "
540 "file \"%s\", err = %d\n", file, -err);
541 return err;
542 }
543
544 err = os_file_size(file, &actual);
545 if (err < 0) {
546 printk(KERN_ERR "Failed to get size of backing file \"%s\", "
547 "err = %d\n", file, -err);
548 return err;
549 }
550
551 if (actual != size) {
552
553
554 printk(KERN_ERR "Size mismatch (%llu vs %llu) of COW header "
555 "vs backing file\n", (unsigned long long) size, actual);
556 return -EINVAL;
557 }
558 if (modtime != mtime) {
559 printk(KERN_ERR "mtime mismatch (%ld vs %ld) of COW header vs "
560 "backing file\n", mtime, modtime);
561 return -EINVAL;
562 }
563 return 0;
564}
565
566static int path_requires_switch(char *from_cmdline, char *from_cow, char *cow)
567{
568 struct uml_stat buf1, buf2;
569 int err;
570
571 if (from_cmdline == NULL)
572 return 0;
573 if (!strcmp(from_cmdline, from_cow))
574 return 0;
575
576 err = os_stat_file(from_cmdline, &buf1);
577 if (err < 0) {
578 printk(KERN_ERR "Couldn't stat '%s', err = %d\n", from_cmdline,
579 -err);
580 return 0;
581 }
582 err = os_stat_file(from_cow, &buf2);
583 if (err < 0) {
584 printk(KERN_ERR "Couldn't stat '%s', err = %d\n", from_cow,
585 -err);
586 return 1;
587 }
588 if ((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
589 return 0;
590
591 printk(KERN_ERR "Backing file mismatch - \"%s\" requested, "
592 "\"%s\" specified in COW header of \"%s\"\n",
593 from_cmdline, from_cow, cow);
594 return 1;
595}
596
597static int open_ubd_file(char *file, struct openflags *openflags, int shared,
598 char **backing_file_out, int *bitmap_offset_out,
599 unsigned long *bitmap_len_out, int *data_offset_out,
600 int *create_cow_out)
601{
602 time_t mtime;
603 unsigned long long size;
604 __u32 version, align;
605 char *backing_file;
606 int fd, err, sectorsize, asked_switch, mode = 0644;
607
608 fd = os_open_file(file, *openflags, mode);
609 if (fd < 0) {
610 if ((fd == -ENOENT) && (create_cow_out != NULL))
611 *create_cow_out = 1;
612 if (!openflags->w ||
613 ((fd != -EROFS) && (fd != -EACCES)))
614 return fd;
615 openflags->w = 0;
616 fd = os_open_file(file, *openflags, mode);
617 if (fd < 0)
618 return fd;
619 }
620
621 if (shared)
622 printk(KERN_INFO "Not locking \"%s\" on the host\n", file);
623 else {
624 err = os_lock_file(fd, openflags->w);
625 if (err < 0) {
626 printk(KERN_ERR "Failed to lock '%s', err = %d\n",
627 file, -err);
628 goto out_close;
629 }
630 }
631
632
633 if (backing_file_out == NULL)
634 return fd;
635
636 err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
637 &size, §orsize, &align, bitmap_offset_out);
638 if (err && (*backing_file_out != NULL)) {
639 printk(KERN_ERR "Failed to read COW header from COW file "
640 "\"%s\", errno = %d\n", file, -err);
641 goto out_close;
642 }
643 if (err)
644 return fd;
645
646 asked_switch = path_requires_switch(*backing_file_out, backing_file,
647 file);
648
649
650 if (asked_switch && !backing_file_mismatch(*backing_file_out, size,
651 mtime)) {
652 printk(KERN_ERR "Switching backing file to '%s'\n",
653 *backing_file_out);
654 err = write_cow_header(file, fd, *backing_file_out,
655 sectorsize, align, &size);
656 if (err) {
657 printk(KERN_ERR "Switch failed, errno = %d\n", -err);
658 goto out_close;
659 }
660 } else {
661 *backing_file_out = backing_file;
662 err = backing_file_mismatch(*backing_file_out, size, mtime);
663 if (err)
664 goto out_close;
665 }
666
667 cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
668 bitmap_len_out, data_offset_out);
669
670 return fd;
671 out_close:
672 os_close_file(fd);
673 return err;
674}
675
676static int create_cow_file(char *cow_file, char *backing_file,
677 struct openflags flags,
678 int sectorsize, int alignment, int *bitmap_offset_out,
679 unsigned long *bitmap_len_out, int *data_offset_out)
680{
681 int err, fd;
682
683 flags.c = 1;
684 fd = open_ubd_file(cow_file, &flags, 0, NULL, NULL, NULL, NULL, NULL);
685 if (fd < 0) {
686 err = fd;
687 printk(KERN_ERR "Open of COW file '%s' failed, errno = %d\n",
688 cow_file, -err);
689 goto out;
690 }
691
692 err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
693 bitmap_offset_out, bitmap_len_out,
694 data_offset_out);
695 if (!err)
696 return fd;
697 os_close_file(fd);
698 out:
699 return err;
700}
701
702static void ubd_close_dev(struct ubd *ubd_dev)
703{
704 os_close_file(ubd_dev->fd);
705 if(ubd_dev->cow.file == NULL)
706 return;
707
708 os_close_file(ubd_dev->cow.fd);
709 vfree(ubd_dev->cow.bitmap);
710 ubd_dev->cow.bitmap = NULL;
711}
712
713static int ubd_open_dev(struct ubd *ubd_dev)
714{
715 struct openflags flags;
716 char **back_ptr;
717 int err, create_cow, *create_ptr;
718 int fd;
719
720 ubd_dev->openflags = ubd_dev->boot_openflags;
721 create_cow = 0;
722 create_ptr = (ubd_dev->cow.file != NULL) ? &create_cow : NULL;
723 back_ptr = ubd_dev->no_cow ? NULL : &ubd_dev->cow.file;
724
725 fd = open_ubd_file(ubd_dev->file, &ubd_dev->openflags, ubd_dev->shared,
726 back_ptr, &ubd_dev->cow.bitmap_offset,
727 &ubd_dev->cow.bitmap_len, &ubd_dev->cow.data_offset,
728 create_ptr);
729
730 if((fd == -ENOENT) && create_cow){
731 fd = create_cow_file(ubd_dev->file, ubd_dev->cow.file,
732 ubd_dev->openflags, 1 << 9, PAGE_SIZE,
733 &ubd_dev->cow.bitmap_offset,
734 &ubd_dev->cow.bitmap_len,
735 &ubd_dev->cow.data_offset);
736 if(fd >= 0){
737 printk(KERN_INFO "Creating \"%s\" as COW file for "
738 "\"%s\"\n", ubd_dev->file, ubd_dev->cow.file);
739 }
740 }
741
742 if(fd < 0){
743 printk("Failed to open '%s', errno = %d\n", ubd_dev->file,
744 -fd);
745 return fd;
746 }
747 ubd_dev->fd = fd;
748
749 if(ubd_dev->cow.file != NULL){
750 blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long));
751
752 err = -ENOMEM;
753 ubd_dev->cow.bitmap = vmalloc(ubd_dev->cow.bitmap_len);
754 if(ubd_dev->cow.bitmap == NULL){
755 printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
756 goto error;
757 }
758 flush_tlb_kernel_vm();
759
760 err = read_cow_bitmap(ubd_dev->fd, ubd_dev->cow.bitmap,
761 ubd_dev->cow.bitmap_offset,
762 ubd_dev->cow.bitmap_len);
763 if(err < 0)
764 goto error;
765
766 flags = ubd_dev->openflags;
767 flags.w = 0;
768 err = open_ubd_file(ubd_dev->cow.file, &flags, ubd_dev->shared, NULL,
769 NULL, NULL, NULL, NULL);
770 if(err < 0) goto error;
771 ubd_dev->cow.fd = err;
772 }
773 return 0;
774 error:
775 os_close_file(ubd_dev->fd);
776 return err;
777}
778
779static void ubd_device_release(struct device *dev)
780{
781 struct ubd *ubd_dev = dev_get_drvdata(dev);
782
783 blk_cleanup_queue(ubd_dev->queue);
784 *ubd_dev = ((struct ubd) DEFAULT_UBD);
785}
786
787static int ubd_disk_register(int major, u64 size, int unit,
788 struct gendisk **disk_out)
789{
790 struct gendisk *disk;
791
792 disk = alloc_disk(1 << UBD_SHIFT);
793 if(disk == NULL)
794 return -ENOMEM;
795
796 disk->major = major;
797 disk->first_minor = unit << UBD_SHIFT;
798 disk->fops = &ubd_blops;
799 set_capacity(disk, size / 512);
800 if (major == UBD_MAJOR)
801 sprintf(disk->disk_name, "ubd%c", 'a' + unit);
802 else
803 sprintf(disk->disk_name, "ubd_fake%d", unit);
804
805
806 if (major == UBD_MAJOR) {
807 ubd_devs[unit].pdev.id = unit;
808 ubd_devs[unit].pdev.name = DRIVER_NAME;
809 ubd_devs[unit].pdev.dev.release = ubd_device_release;
810 dev_set_drvdata(&ubd_devs[unit].pdev.dev, &ubd_devs[unit]);
811 platform_device_register(&ubd_devs[unit].pdev);
812 disk->driverfs_dev = &ubd_devs[unit].pdev.dev;
813 }
814
815 disk->private_data = &ubd_devs[unit];
816 disk->queue = ubd_devs[unit].queue;
817 add_disk(disk);
818
819 *disk_out = disk;
820 return 0;
821}
822
823#define ROUND_BLOCK(n) ((n + ((1 << 9) - 1)) & (-1 << 9))
824
825static int ubd_add(int n, char **error_out)
826{
827 struct ubd *ubd_dev = &ubd_devs[n];
828 int err = 0;
829
830 if(ubd_dev->file == NULL)
831 goto out;
832
833 err = ubd_file_size(ubd_dev, &ubd_dev->size);
834 if(err < 0){
835 *error_out = "Couldn't determine size of device's file";
836 goto out;
837 }
838
839 ubd_dev->size = ROUND_BLOCK(ubd_dev->size);
840
841 INIT_LIST_HEAD(&ubd_dev->restart);
842 sg_init_table(ubd_dev->sg, MAX_SG);
843
844 err = -ENOMEM;
845 ubd_dev->queue = blk_init_queue(do_ubd_request, &ubd_dev->lock);
846 if (ubd_dev->queue == NULL) {
847 *error_out = "Failed to initialize device queue";
848 goto out;
849 }
850 ubd_dev->queue->queuedata = ubd_dev;
851
852 blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG);
853 err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]);
854 if(err){
855 *error_out = "Failed to register device";
856 goto out_cleanup;
857 }
858
859 if (fake_major != UBD_MAJOR)
860 ubd_disk_register(fake_major, ubd_dev->size, n,
861 &fake_gendisk[n]);
862
863
864
865
866
867 if (fake_ide)
868 make_ide_entries(ubd_gendisk[n]->disk_name);
869
870 err = 0;
871out:
872 return err;
873
874out_cleanup:
875 blk_cleanup_queue(ubd_dev->queue);
876 goto out;
877}
878
879static int ubd_config(char *str, char **error_out)
880{
881 int n, ret;
882
883
884
885
886
887 str = kstrdup(str, GFP_KERNEL);
888 if (str == NULL) {
889 *error_out = "Failed to allocate memory";
890 return -ENOMEM;
891 }
892
893 ret = ubd_setup_common(str, &n, error_out);
894 if (ret)
895 goto err_free;
896
897 if (n == -1) {
898 ret = 0;
899 goto err_free;
900 }
901
902 mutex_lock(&ubd_lock);
903 ret = ubd_add(n, error_out);
904 if (ret)
905 ubd_devs[n].file = NULL;
906 mutex_unlock(&ubd_lock);
907
908out:
909 return ret;
910
911err_free:
912 kfree(str);
913 goto out;
914}
915
916static int ubd_get_config(char *name, char *str, int size, char **error_out)
917{
918 struct ubd *ubd_dev;
919 int n, len = 0;
920
921 n = parse_unit(&name);
922 if((n >= MAX_DEV) || (n < 0)){
923 *error_out = "ubd_get_config : device number out of range";
924 return -1;
925 }
926
927 ubd_dev = &ubd_devs[n];
928 mutex_lock(&ubd_lock);
929
930 if(ubd_dev->file == NULL){
931 CONFIG_CHUNK(str, size, len, "", 1);
932 goto out;
933 }
934
935 CONFIG_CHUNK(str, size, len, ubd_dev->file, 0);
936
937 if(ubd_dev->cow.file != NULL){
938 CONFIG_CHUNK(str, size, len, ",", 0);
939 CONFIG_CHUNK(str, size, len, ubd_dev->cow.file, 1);
940 }
941 else CONFIG_CHUNK(str, size, len, "", 1);
942
943 out:
944 mutex_unlock(&ubd_lock);
945 return len;
946}
947
948static int ubd_id(char **str, int *start_out, int *end_out)
949{
950 int n;
951
952 n = parse_unit(str);
953 *start_out = 0;
954 *end_out = MAX_DEV - 1;
955 return n;
956}
957
958static int ubd_remove(int n, char **error_out)
959{
960 struct gendisk *disk = ubd_gendisk[n];
961 struct ubd *ubd_dev;
962 int err = -ENODEV;
963
964 mutex_lock(&ubd_lock);
965
966 ubd_dev = &ubd_devs[n];
967
968 if(ubd_dev->file == NULL)
969 goto out;
970
971
972 err = -EBUSY;
973 if(ubd_dev->count > 0)
974 goto out;
975
976 ubd_gendisk[n] = NULL;
977 if(disk != NULL){
978 del_gendisk(disk);
979 put_disk(disk);
980 }
981
982 if(fake_gendisk[n] != NULL){
983 del_gendisk(fake_gendisk[n]);
984 put_disk(fake_gendisk[n]);
985 fake_gendisk[n] = NULL;
986 }
987
988 err = 0;
989 platform_device_unregister(&ubd_dev->pdev);
990out:
991 mutex_unlock(&ubd_lock);
992 return err;
993}
994
995
996
997
998static struct mc_device ubd_mc = {
999 .list = LIST_HEAD_INIT(ubd_mc.list),
1000 .name = "ubd",
1001 .config = ubd_config,
1002 .get_config = ubd_get_config,
1003 .id = ubd_id,
1004 .remove = ubd_remove,
1005};
1006
1007static int __init ubd_mc_init(void)
1008{
1009 mconsole_register_dev(&ubd_mc);
1010 return 0;
1011}
1012
1013__initcall(ubd_mc_init);
1014
1015static int __init ubd0_init(void)
1016{
1017 struct ubd *ubd_dev = &ubd_devs[0];
1018
1019 mutex_lock(&ubd_lock);
1020 if(ubd_dev->file == NULL)
1021 ubd_dev->file = "root_fs";
1022 mutex_unlock(&ubd_lock);
1023
1024 return 0;
1025}
1026
1027__initcall(ubd0_init);
1028
1029
1030static struct platform_driver ubd_driver = {
1031 .driver = {
1032 .name = DRIVER_NAME,
1033 },
1034};
1035
1036static int __init ubd_init(void)
1037{
1038 char *error;
1039 int i, err;
1040
1041 if (register_blkdev(UBD_MAJOR, "ubd"))
1042 return -1;
1043
1044 if (fake_major != UBD_MAJOR) {
1045 char name[sizeof("ubd_nnn\0")];
1046
1047 snprintf(name, sizeof(name), "ubd_%d", fake_major);
1048 if (register_blkdev(fake_major, "ubd"))
1049 return -1;
1050 }
1051 platform_driver_register(&ubd_driver);
1052 mutex_lock(&ubd_lock);
1053 for (i = 0; i < MAX_DEV; i++){
1054 err = ubd_add(i, &error);
1055 if(err)
1056 printk(KERN_ERR "Failed to initialize ubd device %d :"
1057 "%s\n", i, error);
1058 }
1059 mutex_unlock(&ubd_lock);
1060 return 0;
1061}
1062
1063late_initcall(ubd_init);
1064
1065static int __init ubd_driver_init(void){
1066 unsigned long stack;
1067 int err;
1068
1069
1070 if(global_openflags.s){
1071 printk(KERN_INFO "ubd: Synchronous mode\n");
1072
1073
1074 }
1075 stack = alloc_stack(0, 0);
1076 io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
1077 &thread_fd);
1078 if(io_pid < 0){
1079 printk(KERN_ERR
1080 "ubd : Failed to start I/O thread (errno = %d) - "
1081 "falling back to synchronous I/O\n", -io_pid);
1082 io_pid = -1;
1083 return 0;
1084 }
1085 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
1086 IRQF_DISABLED, "ubd", ubd_devs);
1087 if(err != 0)
1088 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
1089 return 0;
1090}
1091
1092device_initcall(ubd_driver_init);
1093
1094static int ubd_open(struct block_device *bdev, fmode_t mode)
1095{
1096 struct gendisk *disk = bdev->bd_disk;
1097 struct ubd *ubd_dev = disk->private_data;
1098 int err = 0;
1099
1100 if(ubd_dev->count == 0){
1101 err = ubd_open_dev(ubd_dev);
1102 if(err){
1103 printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
1104 disk->disk_name, ubd_dev->file, -err);
1105 goto out;
1106 }
1107 }
1108 ubd_dev->count++;
1109 set_disk_ro(disk, !ubd_dev->openflags.w);
1110
1111
1112
1113
1114
1115
1116
1117 out:
1118 return err;
1119}
1120
1121static int ubd_release(struct gendisk *disk, fmode_t mode)
1122{
1123 struct ubd *ubd_dev = disk->private_data;
1124
1125 if(--ubd_dev->count == 0)
1126 ubd_close_dev(ubd_dev);
1127 return 0;
1128}
1129
1130static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
1131 __u64 *cow_offset, unsigned long *bitmap,
1132 __u64 bitmap_offset, unsigned long *bitmap_words,
1133 __u64 bitmap_len)
1134{
1135 __u64 sector = io_offset >> 9;
1136 int i, update_bitmap = 0;
1137
1138 for(i = 0; i < length >> 9; i++){
1139 if(cow_mask != NULL)
1140 ubd_set_bit(i, (unsigned char *) cow_mask);
1141 if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
1142 continue;
1143
1144 update_bitmap = 1;
1145 ubd_set_bit(sector + i, (unsigned char *) bitmap);
1146 }
1147
1148 if(!update_bitmap)
1149 return;
1150
1151 *cow_offset = sector / (sizeof(unsigned long) * 8);
1152
1153
1154
1155
1156
1157
1158 if (*cow_offset == (DIV_ROUND_UP(bitmap_len,
1159 sizeof(unsigned long)) - 1))
1160 (*cow_offset)--;
1161
1162 bitmap_words[0] = bitmap[*cow_offset];
1163 bitmap_words[1] = bitmap[*cow_offset + 1];
1164
1165 *cow_offset *= sizeof(unsigned long);
1166 *cow_offset += bitmap_offset;
1167}
1168
1169static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
1170 __u64 bitmap_offset, __u64 bitmap_len)
1171{
1172 __u64 sector = req->offset >> 9;
1173 int i;
1174
1175 if(req->length > (sizeof(req->sector_mask) * 8) << 9)
1176 panic("Operation too long");
1177
1178 if(req->op == UBD_READ) {
1179 for(i = 0; i < req->length >> 9; i++){
1180 if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
1181 ubd_set_bit(i, (unsigned char *)
1182 &req->sector_mask);
1183 }
1184 }
1185 else cowify_bitmap(req->offset, req->length, &req->sector_mask,
1186 &req->cow_offset, bitmap, bitmap_offset,
1187 req->bitmap_words, bitmap_len);
1188}
1189
1190
1191static void prepare_request(struct request *req, struct io_thread_req *io_req,
1192 unsigned long long offset, int page_offset,
1193 int len, struct page *page)
1194{
1195 struct gendisk *disk = req->rq_disk;
1196 struct ubd *ubd_dev = disk->private_data;
1197
1198 io_req->req = req;
1199 io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd :
1200 ubd_dev->fd;
1201 io_req->fds[1] = ubd_dev->fd;
1202 io_req->cow_offset = -1;
1203 io_req->offset = offset;
1204 io_req->length = len;
1205 io_req->error = 0;
1206 io_req->sector_mask = 0;
1207
1208 io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
1209 io_req->offsets[0] = 0;
1210 io_req->offsets[1] = ubd_dev->cow.data_offset;
1211 io_req->buffer = page_address(page) + page_offset;
1212 io_req->sectorsize = 1 << 9;
1213
1214 if(ubd_dev->cow.file != NULL)
1215 cowify_req(io_req, ubd_dev->cow.bitmap,
1216 ubd_dev->cow.bitmap_offset, ubd_dev->cow.bitmap_len);
1217
1218}
1219
1220
1221static void do_ubd_request(struct request_queue *q)
1222{
1223 struct io_thread_req *io_req;
1224 struct request *req;
1225 sector_t sector;
1226 int n;
1227
1228 while(1){
1229 struct ubd *dev = q->queuedata;
1230 if(dev->end_sg == 0){
1231 struct request *req = blk_fetch_request(q);
1232 if(req == NULL)
1233 return;
1234
1235 dev->request = req;
1236 dev->start_sg = 0;
1237 dev->end_sg = blk_rq_map_sg(q, req, dev->sg);
1238 }
1239
1240 req = dev->request;
1241 sector = blk_rq_pos(req);
1242 while(dev->start_sg < dev->end_sg){
1243 struct scatterlist *sg = &dev->sg[dev->start_sg];
1244
1245 io_req = kmalloc(sizeof(struct io_thread_req),
1246 GFP_ATOMIC);
1247 if(io_req == NULL){
1248 if(list_empty(&dev->restart))
1249 list_add(&dev->restart, &restart);
1250 return;
1251 }
1252 prepare_request(req, io_req,
1253 (unsigned long long)sector << 9,
1254 sg->offset, sg->length, sg_page(sg));
1255
1256 sector += sg->length >> 9;
1257 n = os_write_file(thread_fd, &io_req,
1258 sizeof(struct io_thread_req *));
1259 if(n != sizeof(struct io_thread_req *)){
1260 if(n != -EAGAIN)
1261 printk("write to io thread failed, "
1262 "errno = %d\n", -n);
1263 else if(list_empty(&dev->restart))
1264 list_add(&dev->restart, &restart);
1265 kfree(io_req);
1266 return;
1267 }
1268
1269 dev->start_sg++;
1270 }
1271 dev->end_sg = 0;
1272 dev->request = NULL;
1273 }
1274}
1275
1276static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1277{
1278 struct ubd *ubd_dev = bdev->bd_disk->private_data;
1279
1280 geo->heads = 128;
1281 geo->sectors = 32;
1282 geo->cylinders = ubd_dev->size / (128 * 32 * 512);
1283 return 0;
1284}
1285
1286static int ubd_ioctl(struct block_device *bdev, fmode_t mode,
1287 unsigned int cmd, unsigned long arg)
1288{
1289 struct ubd *ubd_dev = bdev->bd_disk->private_data;
1290 u16 ubd_id[ATA_ID_WORDS];
1291
1292 switch (cmd) {
1293 struct cdrom_volctrl volume;
1294 case HDIO_GET_IDENTITY:
1295 memset(&ubd_id, 0, ATA_ID_WORDS * 2);
1296 ubd_id[ATA_ID_CYLS] = ubd_dev->size / (128 * 32 * 512);
1297 ubd_id[ATA_ID_HEADS] = 128;
1298 ubd_id[ATA_ID_SECTORS] = 32;
1299 if(copy_to_user((char __user *) arg, (char *) &ubd_id,
1300 sizeof(ubd_id)))
1301 return -EFAULT;
1302 return 0;
1303
1304 case CDROMVOLREAD:
1305 if(copy_from_user(&volume, (char __user *) arg, sizeof(volume)))
1306 return -EFAULT;
1307 volume.channel0 = 255;
1308 volume.channel1 = 255;
1309 volume.channel2 = 255;
1310 volume.channel3 = 255;
1311 if(copy_to_user((char __user *) arg, &volume, sizeof(volume)))
1312 return -EFAULT;
1313 return 0;
1314 }
1315 return -EINVAL;
1316}
1317
1318static int update_bitmap(struct io_thread_req *req)
1319{
1320 int n;
1321
1322 if(req->cow_offset == -1)
1323 return 0;
1324
1325 n = os_seek_file(req->fds[1], req->cow_offset);
1326 if(n < 0){
1327 printk("do_io - bitmap lseek failed : err = %d\n", -n);
1328 return 1;
1329 }
1330
1331 n = os_write_file(req->fds[1], &req->bitmap_words,
1332 sizeof(req->bitmap_words));
1333 if(n != sizeof(req->bitmap_words)){
1334 printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
1335 req->fds[1]);
1336 return 1;
1337 }
1338
1339 return 0;
1340}
1341
1342static void do_io(struct io_thread_req *req)
1343{
1344 char *buf;
1345 unsigned long len;
1346 int n, nsectors, start, end, bit;
1347 int err;
1348 __u64 off;
1349
1350 nsectors = req->length / req->sectorsize;
1351 start = 0;
1352 do {
1353 bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
1354 end = start;
1355 while((end < nsectors) &&
1356 (ubd_test_bit(end, (unsigned char *)
1357 &req->sector_mask) == bit))
1358 end++;
1359
1360 off = req->offset + req->offsets[bit] +
1361 start * req->sectorsize;
1362 len = (end - start) * req->sectorsize;
1363 buf = &req->buffer[start * req->sectorsize];
1364
1365 err = os_seek_file(req->fds[bit], off);
1366 if(err < 0){
1367 printk("do_io - lseek failed : err = %d\n", -err);
1368 req->error = 1;
1369 return;
1370 }
1371 if(req->op == UBD_READ){
1372 n = 0;
1373 do {
1374 buf = &buf[n];
1375 len -= n;
1376 n = os_read_file(req->fds[bit], buf, len);
1377 if (n < 0) {
1378 printk("do_io - read failed, err = %d "
1379 "fd = %d\n", -n, req->fds[bit]);
1380 req->error = 1;
1381 return;
1382 }
1383 } while((n < len) && (n != 0));
1384 if (n < len) memset(&buf[n], 0, len - n);
1385 } else {
1386 n = os_write_file(req->fds[bit], buf, len);
1387 if(n != len){
1388 printk("do_io - write failed err = %d "
1389 "fd = %d\n", -n, req->fds[bit]);
1390 req->error = 1;
1391 return;
1392 }
1393 }
1394
1395 start = end;
1396 } while(start < nsectors);
1397
1398 req->error = update_bitmap(req);
1399}
1400
1401
1402
1403
1404int kernel_fd = -1;
1405
1406
1407static int io_count = 0;
1408
1409int io_thread(void *arg)
1410{
1411 struct io_thread_req *req;
1412 int n;
1413
1414 ignore_sigwinch_sig();
1415 while(1){
1416 n = os_read_file(kernel_fd, &req,
1417 sizeof(struct io_thread_req *));
1418 if(n != sizeof(struct io_thread_req *)){
1419 if(n < 0)
1420 printk("io_thread - read failed, fd = %d, "
1421 "err = %d\n", kernel_fd, -n);
1422 else {
1423 printk("io_thread - short read, fd = %d, "
1424 "length = %d\n", kernel_fd, n);
1425 }
1426 continue;
1427 }
1428 io_count++;
1429 do_io(req);
1430 n = os_write_file(kernel_fd, &req,
1431 sizeof(struct io_thread_req *));
1432 if(n != sizeof(struct io_thread_req *))
1433 printk("io_thread - write failed, fd = %d, err = %d\n",
1434 kernel_fd, -n);
1435 }
1436
1437 return 0;
1438}
1439