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_seek_file(fd, offset);
539 if (err < 0)
540 return err;
541
542 err = os_read_file(fd, buf, len);
543 if (err < 0)
544 return err;
545
546 return 0;
547}
548
549static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
550{
551 unsigned long modtime;
552 unsigned long long actual;
553 int err;
554
555 err = os_file_modtime(file, &modtime);
556 if (err < 0) {
557 printk(KERN_ERR "Failed to get modification time of backing "
558 "file \"%s\", err = %d\n", file, -err);
559 return err;
560 }
561
562 err = os_file_size(file, &actual);
563 if (err < 0) {
564 printk(KERN_ERR "Failed to get size of backing file \"%s\", "
565 "err = %d\n", file, -err);
566 return err;
567 }
568
569 if (actual != size) {
570
571
572 printk(KERN_ERR "Size mismatch (%llu vs %llu) of COW header "
573 "vs backing file\n", (unsigned long long) size, actual);
574 return -EINVAL;
575 }
576 if (modtime != mtime) {
577 printk(KERN_ERR "mtime mismatch (%ld vs %ld) of COW header vs "
578 "backing file\n", mtime, modtime);
579 return -EINVAL;
580 }
581 return 0;
582}
583
584static int path_requires_switch(char *from_cmdline, char *from_cow, char *cow)
585{
586 struct uml_stat buf1, buf2;
587 int err;
588
589 if (from_cmdline == NULL)
590 return 0;
591 if (!strcmp(from_cmdline, from_cow))
592 return 0;
593
594 err = os_stat_file(from_cmdline, &buf1);
595 if (err < 0) {
596 printk(KERN_ERR "Couldn't stat '%s', err = %d\n", from_cmdline,
597 -err);
598 return 0;
599 }
600 err = os_stat_file(from_cow, &buf2);
601 if (err < 0) {
602 printk(KERN_ERR "Couldn't stat '%s', err = %d\n", from_cow,
603 -err);
604 return 1;
605 }
606 if ((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
607 return 0;
608
609 printk(KERN_ERR "Backing file mismatch - \"%s\" requested, "
610 "\"%s\" specified in COW header of \"%s\"\n",
611 from_cmdline, from_cow, cow);
612 return 1;
613}
614
615static int open_ubd_file(char *file, struct openflags *openflags, int shared,
616 char **backing_file_out, int *bitmap_offset_out,
617 unsigned long *bitmap_len_out, int *data_offset_out,
618 int *create_cow_out)
619{
620 time_t mtime;
621 unsigned long long size;
622 __u32 version, align;
623 char *backing_file;
624 int fd, err, sectorsize, asked_switch, mode = 0644;
625
626 fd = os_open_file(file, *openflags, mode);
627 if (fd < 0) {
628 if ((fd == -ENOENT) && (create_cow_out != NULL))
629 *create_cow_out = 1;
630 if (!openflags->w ||
631 ((fd != -EROFS) && (fd != -EACCES)))
632 return fd;
633 openflags->w = 0;
634 fd = os_open_file(file, *openflags, mode);
635 if (fd < 0)
636 return fd;
637 }
638
639 if (shared)
640 printk(KERN_INFO "Not locking \"%s\" on the host\n", file);
641 else {
642 err = os_lock_file(fd, openflags->w);
643 if (err < 0) {
644 printk(KERN_ERR "Failed to lock '%s', err = %d\n",
645 file, -err);
646 goto out_close;
647 }
648 }
649
650
651 if (backing_file_out == NULL)
652 return fd;
653
654 err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
655 &size, §orsize, &align, bitmap_offset_out);
656 if (err && (*backing_file_out != NULL)) {
657 printk(KERN_ERR "Failed to read COW header from COW file "
658 "\"%s\", errno = %d\n", file, -err);
659 goto out_close;
660 }
661 if (err)
662 return fd;
663
664 asked_switch = path_requires_switch(*backing_file_out, backing_file,
665 file);
666
667
668 if (asked_switch && !backing_file_mismatch(*backing_file_out, size,
669 mtime)) {
670 printk(KERN_ERR "Switching backing file to '%s'\n",
671 *backing_file_out);
672 err = write_cow_header(file, fd, *backing_file_out,
673 sectorsize, align, &size);
674 if (err) {
675 printk(KERN_ERR "Switch failed, errno = %d\n", -err);
676 goto out_close;
677 }
678 } else {
679 *backing_file_out = backing_file;
680 err = backing_file_mismatch(*backing_file_out, size, mtime);
681 if (err)
682 goto out_close;
683 }
684
685 cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
686 bitmap_len_out, data_offset_out);
687
688 return fd;
689 out_close:
690 os_close_file(fd);
691 return err;
692}
693
694static int create_cow_file(char *cow_file, char *backing_file,
695 struct openflags flags,
696 int sectorsize, int alignment, int *bitmap_offset_out,
697 unsigned long *bitmap_len_out, int *data_offset_out)
698{
699 int err, fd;
700
701 flags.c = 1;
702 fd = open_ubd_file(cow_file, &flags, 0, NULL, NULL, NULL, NULL, NULL);
703 if (fd < 0) {
704 err = fd;
705 printk(KERN_ERR "Open of COW file '%s' failed, errno = %d\n",
706 cow_file, -err);
707 goto out;
708 }
709
710 err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
711 bitmap_offset_out, bitmap_len_out,
712 data_offset_out);
713 if (!err)
714 return fd;
715 os_close_file(fd);
716 out:
717 return err;
718}
719
720static void ubd_close_dev(struct ubd *ubd_dev)
721{
722 os_close_file(ubd_dev->fd);
723 if(ubd_dev->cow.file == NULL)
724 return;
725
726 os_close_file(ubd_dev->cow.fd);
727 vfree(ubd_dev->cow.bitmap);
728 ubd_dev->cow.bitmap = NULL;
729}
730
731static int ubd_open_dev(struct ubd *ubd_dev)
732{
733 struct openflags flags;
734 char **back_ptr;
735 int err, create_cow, *create_ptr;
736 int fd;
737
738 ubd_dev->openflags = ubd_dev->boot_openflags;
739 create_cow = 0;
740 create_ptr = (ubd_dev->cow.file != NULL) ? &create_cow : NULL;
741 back_ptr = ubd_dev->no_cow ? NULL : &ubd_dev->cow.file;
742
743 fd = open_ubd_file(ubd_dev->file, &ubd_dev->openflags, ubd_dev->shared,
744 back_ptr, &ubd_dev->cow.bitmap_offset,
745 &ubd_dev->cow.bitmap_len, &ubd_dev->cow.data_offset,
746 create_ptr);
747
748 if((fd == -ENOENT) && create_cow){
749 fd = create_cow_file(ubd_dev->file, ubd_dev->cow.file,
750 ubd_dev->openflags, 1 << 9, PAGE_SIZE,
751 &ubd_dev->cow.bitmap_offset,
752 &ubd_dev->cow.bitmap_len,
753 &ubd_dev->cow.data_offset);
754 if(fd >= 0){
755 printk(KERN_INFO "Creating \"%s\" as COW file for "
756 "\"%s\"\n", ubd_dev->file, ubd_dev->cow.file);
757 }
758 }
759
760 if(fd < 0){
761 printk("Failed to open '%s', errno = %d\n", ubd_dev->file,
762 -fd);
763 return fd;
764 }
765 ubd_dev->fd = fd;
766
767 if(ubd_dev->cow.file != NULL){
768 blk_queue_max_hw_sectors(ubd_dev->queue, 8 * sizeof(long));
769
770 err = -ENOMEM;
771 ubd_dev->cow.bitmap = vmalloc(ubd_dev->cow.bitmap_len);
772 if(ubd_dev->cow.bitmap == NULL){
773 printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
774 goto error;
775 }
776 flush_tlb_kernel_vm();
777
778 err = read_cow_bitmap(ubd_dev->fd, ubd_dev->cow.bitmap,
779 ubd_dev->cow.bitmap_offset,
780 ubd_dev->cow.bitmap_len);
781 if(err < 0)
782 goto error;
783
784 flags = ubd_dev->openflags;
785 flags.w = 0;
786 err = open_ubd_file(ubd_dev->cow.file, &flags, ubd_dev->shared, NULL,
787 NULL, NULL, NULL, NULL);
788 if(err < 0) goto error;
789 ubd_dev->cow.fd = err;
790 }
791 return 0;
792 error:
793 os_close_file(ubd_dev->fd);
794 return err;
795}
796
797static void ubd_device_release(struct device *dev)
798{
799 struct ubd *ubd_dev = dev_get_drvdata(dev);
800
801 blk_cleanup_queue(ubd_dev->queue);
802 *ubd_dev = ((struct ubd) DEFAULT_UBD);
803}
804
805static int ubd_disk_register(int major, u64 size, int unit,
806 struct gendisk **disk_out)
807{
808 struct gendisk *disk;
809
810 disk = alloc_disk(1 << UBD_SHIFT);
811 if(disk == NULL)
812 return -ENOMEM;
813
814 disk->major = major;
815 disk->first_minor = unit << UBD_SHIFT;
816 disk->fops = &ubd_blops;
817 set_capacity(disk, size / 512);
818 if (major == UBD_MAJOR)
819 sprintf(disk->disk_name, "ubd%c", 'a' + unit);
820 else
821 sprintf(disk->disk_name, "ubd_fake%d", unit);
822
823
824 if (major == UBD_MAJOR) {
825 ubd_devs[unit].pdev.id = unit;
826 ubd_devs[unit].pdev.name = DRIVER_NAME;
827 ubd_devs[unit].pdev.dev.release = ubd_device_release;
828 dev_set_drvdata(&ubd_devs[unit].pdev.dev, &ubd_devs[unit]);
829 platform_device_register(&ubd_devs[unit].pdev);
830 disk->driverfs_dev = &ubd_devs[unit].pdev.dev;
831 }
832
833 disk->private_data = &ubd_devs[unit];
834 disk->queue = ubd_devs[unit].queue;
835 add_disk(disk);
836
837 *disk_out = disk;
838 return 0;
839}
840
841#define ROUND_BLOCK(n) ((n + ((1 << 9) - 1)) & (-1 << 9))
842
843static int ubd_add(int n, char **error_out)
844{
845 struct ubd *ubd_dev = &ubd_devs[n];
846 int err = 0;
847
848 if(ubd_dev->file == NULL)
849 goto out;
850
851 err = ubd_file_size(ubd_dev, &ubd_dev->size);
852 if(err < 0){
853 *error_out = "Couldn't determine size of device's file";
854 goto out;
855 }
856
857 ubd_dev->size = ROUND_BLOCK(ubd_dev->size);
858
859 INIT_LIST_HEAD(&ubd_dev->restart);
860 sg_init_table(ubd_dev->sg, MAX_SG);
861
862 err = -ENOMEM;
863 ubd_dev->queue = blk_init_queue(do_ubd_request, &ubd_dev->lock);
864 if (ubd_dev->queue == NULL) {
865 *error_out = "Failed to initialize device queue";
866 goto out;
867 }
868 ubd_dev->queue->queuedata = ubd_dev;
869 blk_queue_flush(ubd_dev->queue, REQ_FLUSH);
870
871 blk_queue_max_segments(ubd_dev->queue, MAX_SG);
872 err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]);
873 if(err){
874 *error_out = "Failed to register device";
875 goto out_cleanup;
876 }
877
878 if (fake_major != UBD_MAJOR)
879 ubd_disk_register(fake_major, ubd_dev->size, n,
880 &fake_gendisk[n]);
881
882
883
884
885
886 if (fake_ide)
887 make_ide_entries(ubd_gendisk[n]->disk_name);
888
889 err = 0;
890out:
891 return err;
892
893out_cleanup:
894 blk_cleanup_queue(ubd_dev->queue);
895 goto out;
896}
897
898static int ubd_config(char *str, char **error_out)
899{
900 int n, ret;
901
902
903
904
905
906 str = kstrdup(str, GFP_KERNEL);
907 if (str == NULL) {
908 *error_out = "Failed to allocate memory";
909 return -ENOMEM;
910 }
911
912 ret = ubd_setup_common(str, &n, error_out);
913 if (ret)
914 goto err_free;
915
916 if (n == -1) {
917 ret = 0;
918 goto err_free;
919 }
920
921 mutex_lock(&ubd_lock);
922 ret = ubd_add(n, error_out);
923 if (ret)
924 ubd_devs[n].file = NULL;
925 mutex_unlock(&ubd_lock);
926
927out:
928 return ret;
929
930err_free:
931 kfree(str);
932 goto out;
933}
934
935static int ubd_get_config(char *name, char *str, int size, char **error_out)
936{
937 struct ubd *ubd_dev;
938 int n, len = 0;
939
940 n = parse_unit(&name);
941 if((n >= MAX_DEV) || (n < 0)){
942 *error_out = "ubd_get_config : device number out of range";
943 return -1;
944 }
945
946 ubd_dev = &ubd_devs[n];
947 mutex_lock(&ubd_lock);
948
949 if(ubd_dev->file == NULL){
950 CONFIG_CHUNK(str, size, len, "", 1);
951 goto out;
952 }
953
954 CONFIG_CHUNK(str, size, len, ubd_dev->file, 0);
955
956 if(ubd_dev->cow.file != NULL){
957 CONFIG_CHUNK(str, size, len, ",", 0);
958 CONFIG_CHUNK(str, size, len, ubd_dev->cow.file, 1);
959 }
960 else CONFIG_CHUNK(str, size, len, "", 1);
961
962 out:
963 mutex_unlock(&ubd_lock);
964 return len;
965}
966
967static int ubd_id(char **str, int *start_out, int *end_out)
968{
969 int n;
970
971 n = parse_unit(str);
972 *start_out = 0;
973 *end_out = MAX_DEV - 1;
974 return n;
975}
976
977static int ubd_remove(int n, char **error_out)
978{
979 struct gendisk *disk = ubd_gendisk[n];
980 struct ubd *ubd_dev;
981 int err = -ENODEV;
982
983 mutex_lock(&ubd_lock);
984
985 ubd_dev = &ubd_devs[n];
986
987 if(ubd_dev->file == NULL)
988 goto out;
989
990
991 err = -EBUSY;
992 if(ubd_dev->count > 0)
993 goto out;
994
995 ubd_gendisk[n] = NULL;
996 if(disk != NULL){
997 del_gendisk(disk);
998 put_disk(disk);
999 }
1000
1001 if(fake_gendisk[n] != NULL){
1002 del_gendisk(fake_gendisk[n]);
1003 put_disk(fake_gendisk[n]);
1004 fake_gendisk[n] = NULL;
1005 }
1006
1007 err = 0;
1008 platform_device_unregister(&ubd_dev->pdev);
1009out:
1010 mutex_unlock(&ubd_lock);
1011 return err;
1012}
1013
1014
1015
1016
1017static struct mc_device ubd_mc = {
1018 .list = LIST_HEAD_INIT(ubd_mc.list),
1019 .name = "ubd",
1020 .config = ubd_config,
1021 .get_config = ubd_get_config,
1022 .id = ubd_id,
1023 .remove = ubd_remove,
1024};
1025
1026static int __init ubd_mc_init(void)
1027{
1028 mconsole_register_dev(&ubd_mc);
1029 return 0;
1030}
1031
1032__initcall(ubd_mc_init);
1033
1034static int __init ubd0_init(void)
1035{
1036 struct ubd *ubd_dev = &ubd_devs[0];
1037
1038 mutex_lock(&ubd_lock);
1039 if(ubd_dev->file == NULL)
1040 ubd_dev->file = "root_fs";
1041 mutex_unlock(&ubd_lock);
1042
1043 return 0;
1044}
1045
1046__initcall(ubd0_init);
1047
1048
1049static struct platform_driver ubd_driver = {
1050 .driver = {
1051 .name = DRIVER_NAME,
1052 },
1053};
1054
1055static int __init ubd_init(void)
1056{
1057 char *error;
1058 int i, err;
1059
1060 if (register_blkdev(UBD_MAJOR, "ubd"))
1061 return -1;
1062
1063 if (fake_major != UBD_MAJOR) {
1064 char name[sizeof("ubd_nnn\0")];
1065
1066 snprintf(name, sizeof(name), "ubd_%d", fake_major);
1067 if (register_blkdev(fake_major, "ubd"))
1068 return -1;
1069 }
1070 platform_driver_register(&ubd_driver);
1071 mutex_lock(&ubd_lock);
1072 for (i = 0; i < MAX_DEV; i++){
1073 err = ubd_add(i, &error);
1074 if(err)
1075 printk(KERN_ERR "Failed to initialize ubd device %d :"
1076 "%s\n", i, error);
1077 }
1078 mutex_unlock(&ubd_lock);
1079 return 0;
1080}
1081
1082late_initcall(ubd_init);
1083
1084static int __init ubd_driver_init(void){
1085 unsigned long stack;
1086 int err;
1087
1088
1089 if(global_openflags.s){
1090 printk(KERN_INFO "ubd: Synchronous mode\n");
1091
1092
1093 }
1094 stack = alloc_stack(0, 0);
1095 io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
1096 &thread_fd);
1097 if(io_pid < 0){
1098 printk(KERN_ERR
1099 "ubd : Failed to start I/O thread (errno = %d) - "
1100 "falling back to synchronous I/O\n", -io_pid);
1101 io_pid = -1;
1102 return 0;
1103 }
1104 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
1105 0, "ubd", ubd_devs);
1106 if(err != 0)
1107 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
1108 return 0;
1109}
1110
1111device_initcall(ubd_driver_init);
1112
1113static int ubd_open(struct block_device *bdev, fmode_t mode)
1114{
1115 struct gendisk *disk = bdev->bd_disk;
1116 struct ubd *ubd_dev = disk->private_data;
1117 int err = 0;
1118
1119 mutex_lock(&ubd_mutex);
1120 if(ubd_dev->count == 0){
1121 err = ubd_open_dev(ubd_dev);
1122 if(err){
1123 printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
1124 disk->disk_name, ubd_dev->file, -err);
1125 goto out;
1126 }
1127 }
1128 ubd_dev->count++;
1129 set_disk_ro(disk, !ubd_dev->openflags.w);
1130
1131
1132
1133
1134
1135
1136
1137out:
1138 mutex_unlock(&ubd_mutex);
1139 return err;
1140}
1141
1142static void ubd_release(struct gendisk *disk, fmode_t mode)
1143{
1144 struct ubd *ubd_dev = disk->private_data;
1145
1146 mutex_lock(&ubd_mutex);
1147 if(--ubd_dev->count == 0)
1148 ubd_close_dev(ubd_dev);
1149 mutex_unlock(&ubd_mutex);
1150}
1151
1152static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
1153 __u64 *cow_offset, unsigned long *bitmap,
1154 __u64 bitmap_offset, unsigned long *bitmap_words,
1155 __u64 bitmap_len)
1156{
1157 __u64 sector = io_offset >> 9;
1158 int i, update_bitmap = 0;
1159
1160 for(i = 0; i < length >> 9; i++){
1161 if(cow_mask != NULL)
1162 ubd_set_bit(i, (unsigned char *) cow_mask);
1163 if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
1164 continue;
1165
1166 update_bitmap = 1;
1167 ubd_set_bit(sector + i, (unsigned char *) bitmap);
1168 }
1169
1170 if(!update_bitmap)
1171 return;
1172
1173 *cow_offset = sector / (sizeof(unsigned long) * 8);
1174
1175
1176
1177
1178
1179
1180 if (*cow_offset == (DIV_ROUND_UP(bitmap_len,
1181 sizeof(unsigned long)) - 1))
1182 (*cow_offset)--;
1183
1184 bitmap_words[0] = bitmap[*cow_offset];
1185 bitmap_words[1] = bitmap[*cow_offset + 1];
1186
1187 *cow_offset *= sizeof(unsigned long);
1188 *cow_offset += bitmap_offset;
1189}
1190
1191static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
1192 __u64 bitmap_offset, __u64 bitmap_len)
1193{
1194 __u64 sector = req->offset >> 9;
1195 int i;
1196
1197 if(req->length > (sizeof(req->sector_mask) * 8) << 9)
1198 panic("Operation too long");
1199
1200 if(req->op == UBD_READ) {
1201 for(i = 0; i < req->length >> 9; i++){
1202 if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
1203 ubd_set_bit(i, (unsigned char *)
1204 &req->sector_mask);
1205 }
1206 }
1207 else cowify_bitmap(req->offset, req->length, &req->sector_mask,
1208 &req->cow_offset, bitmap, bitmap_offset,
1209 req->bitmap_words, bitmap_len);
1210}
1211
1212
1213static void prepare_request(struct request *req, struct io_thread_req *io_req,
1214 unsigned long long offset, int page_offset,
1215 int len, struct page *page)
1216{
1217 struct gendisk *disk = req->rq_disk;
1218 struct ubd *ubd_dev = disk->private_data;
1219
1220 io_req->req = req;
1221 io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd :
1222 ubd_dev->fd;
1223 io_req->fds[1] = ubd_dev->fd;
1224 io_req->cow_offset = -1;
1225 io_req->offset = offset;
1226 io_req->length = len;
1227 io_req->error = 0;
1228 io_req->sector_mask = 0;
1229
1230 io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
1231 io_req->offsets[0] = 0;
1232 io_req->offsets[1] = ubd_dev->cow.data_offset;
1233 io_req->buffer = page_address(page) + page_offset;
1234 io_req->sectorsize = 1 << 9;
1235
1236 if(ubd_dev->cow.file != NULL)
1237 cowify_req(io_req, ubd_dev->cow.bitmap,
1238 ubd_dev->cow.bitmap_offset, ubd_dev->cow.bitmap_len);
1239
1240}
1241
1242
1243static void prepare_flush_request(struct request *req,
1244 struct io_thread_req *io_req)
1245{
1246 struct gendisk *disk = req->rq_disk;
1247 struct ubd *ubd_dev = disk->private_data;
1248
1249 io_req->req = req;
1250 io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd :
1251 ubd_dev->fd;
1252 io_req->op = UBD_FLUSH;
1253}
1254
1255static bool submit_request(struct io_thread_req *io_req, struct ubd *dev)
1256{
1257 int n = os_write_file(thread_fd, &io_req,
1258 sizeof(io_req));
1259 if (n != sizeof(io_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
1266 kfree(io_req);
1267 return false;
1268 }
1269 return true;
1270}
1271
1272
1273static void do_ubd_request(struct request_queue *q)
1274{
1275 struct io_thread_req *io_req;
1276 struct request *req;
1277
1278 while(1){
1279 struct ubd *dev = q->queuedata;
1280 if(dev->request == NULL){
1281 struct request *req = blk_fetch_request(q);
1282 if(req == NULL)
1283 return;
1284
1285 dev->request = req;
1286 dev->rq_pos = blk_rq_pos(req);
1287 dev->start_sg = 0;
1288 dev->end_sg = blk_rq_map_sg(q, req, dev->sg);
1289 }
1290
1291 req = dev->request;
1292
1293 if (req->cmd_flags & REQ_FLUSH) {
1294 io_req = kmalloc(sizeof(struct io_thread_req),
1295 GFP_ATOMIC);
1296 if (io_req == NULL) {
1297 if (list_empty(&dev->restart))
1298 list_add(&dev->restart, &restart);
1299 return;
1300 }
1301 prepare_flush_request(req, io_req);
1302 if (submit_request(io_req, dev) == false)
1303 return;
1304 }
1305
1306 while(dev->start_sg < dev->end_sg){
1307 struct scatterlist *sg = &dev->sg[dev->start_sg];
1308
1309 io_req = kmalloc(sizeof(struct io_thread_req),
1310 GFP_ATOMIC);
1311 if(io_req == NULL){
1312 if(list_empty(&dev->restart))
1313 list_add(&dev->restart, &restart);
1314 return;
1315 }
1316 prepare_request(req, io_req,
1317 (unsigned long long)dev->rq_pos << 9,
1318 sg->offset, sg->length, sg_page(sg));
1319
1320 if (submit_request(io_req, dev) == false)
1321 return;
1322
1323 dev->rq_pos += sg->length >> 9;
1324 dev->start_sg++;
1325 }
1326 dev->end_sg = 0;
1327 dev->request = NULL;
1328 }
1329}
1330
1331static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1332{
1333 struct ubd *ubd_dev = bdev->bd_disk->private_data;
1334
1335 geo->heads = 128;
1336 geo->sectors = 32;
1337 geo->cylinders = ubd_dev->size / (128 * 32 * 512);
1338 return 0;
1339}
1340
1341static int ubd_ioctl(struct block_device *bdev, fmode_t mode,
1342 unsigned int cmd, unsigned long arg)
1343{
1344 struct ubd *ubd_dev = bdev->bd_disk->private_data;
1345 u16 ubd_id[ATA_ID_WORDS];
1346
1347 switch (cmd) {
1348 struct cdrom_volctrl volume;
1349 case HDIO_GET_IDENTITY:
1350 memset(&ubd_id, 0, ATA_ID_WORDS * 2);
1351 ubd_id[ATA_ID_CYLS] = ubd_dev->size / (128 * 32 * 512);
1352 ubd_id[ATA_ID_HEADS] = 128;
1353 ubd_id[ATA_ID_SECTORS] = 32;
1354 if(copy_to_user((char __user *) arg, (char *) &ubd_id,
1355 sizeof(ubd_id)))
1356 return -EFAULT;
1357 return 0;
1358
1359 case CDROMVOLREAD:
1360 if(copy_from_user(&volume, (char __user *) arg, sizeof(volume)))
1361 return -EFAULT;
1362 volume.channel0 = 255;
1363 volume.channel1 = 255;
1364 volume.channel2 = 255;
1365 volume.channel3 = 255;
1366 if(copy_to_user((char __user *) arg, &volume, sizeof(volume)))
1367 return -EFAULT;
1368 return 0;
1369 }
1370 return -EINVAL;
1371}
1372
1373static int update_bitmap(struct io_thread_req *req)
1374{
1375 int n;
1376
1377 if(req->cow_offset == -1)
1378 return 0;
1379
1380 n = os_seek_file(req->fds[1], req->cow_offset);
1381 if(n < 0){
1382 printk("do_io - bitmap lseek failed : err = %d\n", -n);
1383 return 1;
1384 }
1385
1386 n = os_write_file(req->fds[1], &req->bitmap_words,
1387 sizeof(req->bitmap_words));
1388 if(n != sizeof(req->bitmap_words)){
1389 printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
1390 req->fds[1]);
1391 return 1;
1392 }
1393
1394 return 0;
1395}
1396
1397static void do_io(struct io_thread_req *req)
1398{
1399 char *buf;
1400 unsigned long len;
1401 int n, nsectors, start, end, bit;
1402 int err;
1403 __u64 off;
1404
1405 if (req->op == UBD_FLUSH) {
1406
1407 n = os_sync_file(req->fds[0]);
1408 if (n != 0) {
1409 printk("do_io - sync failed err = %d "
1410 "fd = %d\n", -n, req->fds[0]);
1411 req->error = 1;
1412 }
1413 return;
1414 }
1415
1416 nsectors = req->length / req->sectorsize;
1417 start = 0;
1418 do {
1419 bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
1420 end = start;
1421 while((end < nsectors) &&
1422 (ubd_test_bit(end, (unsigned char *)
1423 &req->sector_mask) == bit))
1424 end++;
1425
1426 off = req->offset + req->offsets[bit] +
1427 start * req->sectorsize;
1428 len = (end - start) * req->sectorsize;
1429 buf = &req->buffer[start * req->sectorsize];
1430
1431 err = os_seek_file(req->fds[bit], off);
1432 if(err < 0){
1433 printk("do_io - lseek failed : err = %d\n", -err);
1434 req->error = 1;
1435 return;
1436 }
1437 if(req->op == UBD_READ){
1438 n = 0;
1439 do {
1440 buf = &buf[n];
1441 len -= n;
1442 n = os_read_file(req->fds[bit], buf, len);
1443 if (n < 0) {
1444 printk("do_io - read failed, err = %d "
1445 "fd = %d\n", -n, req->fds[bit]);
1446 req->error = 1;
1447 return;
1448 }
1449 } while((n < len) && (n != 0));
1450 if (n < len) memset(&buf[n], 0, len - n);
1451 } else {
1452 n = os_write_file(req->fds[bit], buf, len);
1453 if(n != len){
1454 printk("do_io - write failed err = %d "
1455 "fd = %d\n", -n, req->fds[bit]);
1456 req->error = 1;
1457 return;
1458 }
1459 }
1460
1461 start = end;
1462 } while(start < nsectors);
1463
1464 req->error = update_bitmap(req);
1465}
1466
1467
1468
1469
1470int kernel_fd = -1;
1471
1472
1473static int io_count = 0;
1474
1475int io_thread(void *arg)
1476{
1477 struct io_thread_req *req;
1478 int n;
1479
1480 os_fix_helper_signals();
1481
1482 while(1){
1483 n = os_read_file(kernel_fd, &req,
1484 sizeof(struct io_thread_req *));
1485 if(n != sizeof(struct io_thread_req *)){
1486 if(n < 0)
1487 printk("io_thread - read failed, fd = %d, "
1488 "err = %d\n", kernel_fd, -n);
1489 else {
1490 printk("io_thread - short read, fd = %d, "
1491 "length = %d\n", kernel_fd, n);
1492 }
1493 continue;
1494 }
1495 io_count++;
1496 do_io(req);
1497 n = os_write_file(kernel_fd, &req,
1498 sizeof(struct io_thread_req *));
1499 if(n != sizeof(struct io_thread_req *))
1500 printk("io_thread - write failed, fd = %d, err = %d\n",
1501 kernel_fd, -n);
1502 }
1503
1504 return 0;
1505}
1506