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