2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
6 /* 2001-09-28...2002-04-17
7 * Partition stuff by James_McMechan@hotmail.com
8 * old style ubd by setting UBD_SHIFT to 0
9 * 2002-09-27...2002-10-18 massive tinkering for 2.5
10 * partitions have changed in 2.5
13 #define MAJOR_NR UBD_MAJOR
16 #include "linux/config.h"
17 #include "linux/module.h"
18 #include "linux/blkdev.h"
19 #include "linux/hdreg.h"
20 #include "linux/init.h"
21 #include "linux/devfs_fs_kernel.h"
22 #include "linux/cdrom.h"
23 #include "linux/proc_fs.h"
24 #include "linux/ctype.h"
25 #include "linux/capability.h"
27 #include "linux/vmalloc.h"
28 #include "linux/blkpg.h"
29 #include "linux/genhd.h"
30 #include "linux/spinlock.h"
31 #include "asm/segment.h"
32 #include "asm/uaccess.h"
34 #include "asm/types.h"
35 #include "asm/tlbflush.h"
36 #include "user_util.h"
38 #include "kern_util.h"
40 #include "mconsole_kern.h"
44 #include "2_5compat.h"
47 static spinlock_t ubd_io_lock = SPIN_LOCK_UNLOCKED;
48 static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED;
50 static void (*do_ubd)(void);
52 static int ubd_open(struct inode * inode, struct file * filp);
53 static int ubd_release(struct inode * inode, struct file * file);
54 static int ubd_ioctl(struct inode * inode, struct file * file,
55 unsigned int cmd, unsigned long arg);
59 static struct block_device_operations ubd_blops = {
62 .release = ubd_release,
66 /* Protected by the queue_lock */
67 static request_queue_t *ubd_queue;
69 /* Protected by ubd_lock */
70 static int fake_major = 0;
72 static struct gendisk *ubd_gendisk[MAX_DEV];
73 static struct gendisk *fake_gendisk[MAX_DEV];
75 #ifdef CONFIG_BLK_DEV_UBD_SYNC
76 #define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
79 #define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 0, .c = 0, \
83 /* Not protected - changed only in ubd_setup_common and then only to
86 static struct openflags global_openflags = OPEN_FLAGS;
91 unsigned long *bitmap;
92 unsigned long bitmap_len;
103 struct openflags boot_openflags;
104 struct openflags openflags;
108 #define DEFAULT_COW { \
112 .bitmap_offset = 0, \
116 #define DEFAULT_UBD { \
122 .boot_openflags = OPEN_FLAGS, \
123 .openflags = OPEN_FLAGS, \
124 .cow = DEFAULT_COW, \
127 struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
129 static int ubd0_init(void)
131 if(ubd_dev[0].file == NULL)
132 ubd_dev[0].file = "root_fs";
136 __initcall(ubd0_init);
138 /* Only changed by fake_ide_setup which is a setup */
139 static int fake_ide = 0;
140 static struct proc_dir_entry *proc_ide_root = NULL;
141 static struct proc_dir_entry *proc_ide = NULL;
143 static void make_proc_ide(void)
145 proc_ide_root = proc_mkdir("ide", 0);
146 proc_ide = proc_mkdir("ide0", proc_ide_root);
149 static int proc_ide_read_media(char *page, char **start, off_t off, int count,
150 int *eof, void *data)
154 strcpy(page, "disk\n");
155 len = strlen("disk\n");
159 if (len <= 0) return 0;
166 static void make_ide_entries(char *dev_name)
168 struct proc_dir_entry *dir, *ent;
171 if(proc_ide_root == NULL) make_proc_ide();
173 dir = proc_mkdir(dev_name, proc_ide);
176 ent = create_proc_entry("media", S_IFREG|S_IRUGO, dir);
180 ent->read_proc = proc_ide_read_media;
181 ent->write_proc = NULL;
182 sprintf(name,"ide0/%s", dev_name);
183 proc_symlink(dev_name, proc_ide_root, name);
186 static int fake_ide_setup(char *str)
192 __setup("fake_ide", fake_ide_setup);
194 __uml_help(fake_ide_setup,
196 " Create ide0 entries that map onto ubd devices.\n\n"
199 static int ubd_setup_common(char *str, int *index_out)
201 struct openflags flags = global_openflags;
205 if(index_out) *index_out = -1;
208 static int fake_major_allowed = 1;
212 if(!strcmp(str, "sync")){
213 global_openflags.s = 1;
216 major = simple_strtoul(str, &end, 0);
217 if((*end != '\0') || (end == str)){
219 "ubd_setup : didn't parse major number\n");
223 if(!fake_major_allowed){
224 printk(KERN_ERR "Can't assign a fake major twice\n");
229 spin_lock(&ubd_lock);
230 if(!fake_major_allowed){
231 printk(KERN_ERR "Can't assign a fake major twice\n");
236 fake_major_allowed = 0;
238 printk(KERN_INFO "Setting extra ubd major number to %d\n",
242 spin_unlock(&ubd_lock);
247 printk(KERN_ERR "ubd_setup : index out of range\n"); }
249 if((n >= '0') && (n <= '9')) n -= '0';
250 else if((n >= 'a') && (n <= 'z')) n -= 'a';
252 printk(KERN_ERR "ubd_setup : device syntax invalid\n");
256 printk(KERN_ERR "ubd_setup : index out of range "
257 "(%d devices)\n", MAX_DEV);
262 spin_lock(&ubd_lock);
264 if(ubd_dev[n].file != NULL){
265 printk(KERN_ERR "ubd_setup : device already configured\n");
269 if(index_out) *index_out = n;
280 printk(KERN_ERR "ubd_setup : Expected '='\n");
285 backing_file = strchr(str, ',');
287 *backing_file = '\0';
290 ubd_dev[n].file = str;
291 if(ubd_is_dir(ubd_dev[n].file))
292 ubd_dev[n].is_dir = 1;
293 ubd_dev[n].cow.file = backing_file;
294 ubd_dev[n].boot_openflags = flags;
296 spin_unlock(&ubd_lock);
300 static int ubd_setup(char *str)
302 ubd_setup_common(str, NULL);
306 __setup("ubd", ubd_setup);
307 __uml_help(ubd_setup,
308 "ubd<n>=<filename>\n"
309 " This is used to associate a device with a file in the underlying\n"
310 " filesystem. Usually, there is a filesystem in the file, but \n"
311 " that's not required. Swap devices containing swap files can be\n"
312 " specified like this. Also, a file which doesn't contain a\n"
313 " filesystem can have its contents read in the virtual \n"
314 " machine by running dd on the device. n must be in the range\n"
315 " 0 to 7. Appending an 'r' to the number will cause that device\n"
316 " to be mounted read-only. For example ubd1r=./ext_fs. Appending\n"
317 " an 's' (has to be _after_ 'r', if there is one) will cause data\n"
318 " to be written to disk on the host immediately.\n\n"
321 static int fakehd_set = 0;
322 static int fakehd(char *str)
325 "fakehd : Changing ubd name to \"hd\".\n");
330 __setup("fakehd", fakehd);
333 " Change the ubd device name to \"hd\".\n\n"
336 static void do_ubd_request(request_queue_t * q);
338 /* Only changed by ubd_init, which is an initcall. */
341 /* Changed by ubd_handler, which is serialized because interrupts only
346 static void ubd_finish(struct request *req, int error)
351 spin_lock(&ubd_io_lock);
353 spin_unlock(&ubd_io_lock);
356 nsect = req->current_nr_sectors;
357 req->sector += nsect;
358 req->buffer += nsect << 9;
360 req->nr_sectors -= nsect;
361 req->current_nr_sectors = 0;
362 spin_lock(&ubd_io_lock);
364 spin_unlock(&ubd_io_lock);
367 static void ubd_handler(void)
369 struct io_thread_req req;
370 struct request *rq = elv_next_request(ubd_queue);
375 n = read_ubd_fs(thread_fd, &req, sizeof(req));
376 if(n != sizeof(req)){
377 printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
378 "errno = %d\n", os_getpid(), -n);
379 spin_lock(&ubd_io_lock);
381 spin_unlock(&ubd_io_lock);
385 if((req.offset != ((__u64) (rq->sector)) << 9) ||
386 (req.length != (rq->current_nr_sectors) << 9))
387 panic("I/O op mismatch");
389 ubd_finish(rq, req.error);
390 reactivate_fd(thread_fd, UBD_IRQ);
391 do_ubd_request(ubd_queue);
394 static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
399 /* Only changed by ubd_init, which is an initcall. */
400 static int io_pid = -1;
402 void kill_io_thread(void)
405 os_kill_process(io_pid, 1);
408 __uml_exitcall(kill_io_thread);
410 static int ubd_file_size(struct ubd *dev, __u64 *size_out)
414 file = dev->cow.file ? dev->cow.file : dev->file;
415 return(os_file_size(file, size_out));
418 static void ubd_close(struct ubd *dev)
420 os_close_file(dev->fd);
421 if(dev->cow.file == NULL)
424 os_close_file(dev->cow.fd);
425 vfree(dev->cow.bitmap);
426 dev->cow.bitmap = NULL;
429 static int ubd_open_dev(struct ubd *dev)
431 struct openflags flags;
432 int err, n, create_cow, *create_ptr;
435 create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
436 dev->fd = open_ubd_file(dev->file, &dev->openflags, &dev->cow.file,
437 &dev->cow.bitmap_offset, &dev->cow.bitmap_len,
438 &dev->cow.data_offset, create_ptr);
440 if((dev->fd == -ENOENT) && create_cow){
442 dev->fd = create_cow_file(dev->file, dev->cow.file,
443 dev->openflags, 1 << 9,
444 &dev->cow.bitmap_offset,
445 &dev->cow.bitmap_len,
446 &dev->cow.data_offset);
448 printk(KERN_INFO "Creating \"%s\" as COW file for "
449 "\"%s\"\n", dev->file, dev->cow.file);
453 if(dev->fd < 0) return(dev->fd);
455 if(dev->cow.file != NULL){
457 dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
458 if(dev->cow.bitmap == NULL) goto error;
459 flush_tlb_kernel_vm();
461 err = read_cow_bitmap(dev->fd, dev->cow.bitmap,
462 dev->cow.bitmap_offset,
463 dev->cow.bitmap_len);
466 flags = dev->openflags;
468 err = open_ubd_file(dev->cow.file, &flags, NULL, NULL, NULL,
470 if(err < 0) goto error;
475 os_close_file(dev->fd);
479 static int ubd_new_disk(int major, u64 size, int unit,
480 struct gendisk **disk_out)
483 struct gendisk *disk;
485 disk = alloc_disk(1 << UBD_SHIFT);
490 disk->first_minor = unit << UBD_SHIFT;
491 disk->fops = &ubd_blops;
492 set_capacity(disk, size / 512);
493 sprintf(disk->disk_name, "ubd");
494 sprintf(disk->devfs_name, "ubd/disc%d", unit);
496 disk->private_data = &ubd_dev[unit];
497 disk->queue = ubd_queue;
504 static int ubd_add(int n)
506 struct ubd *dev = &ubd_dev[n];
515 if (ubd_open_dev(dev))
518 err = ubd_file_size(dev, &dev->size);
522 err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
527 ubd_new_disk(fake_major, dev->size, n,
530 /* perhaps this should also be under the "if (fake_major)" above */
531 /* using the fake_disk->disk_name and also the fakehd_set name */
533 make_ide_entries(ubd_gendisk[n]->disk_name);
539 static int ubd_config(char *str)
543 str = uml_strdup(str);
545 printk(KERN_ERR "ubd_config failed to strdup string\n");
548 err = ubd_setup_common(str, &n);
553 if(n == -1) return(0);
555 spin_lock(&ubd_lock);
558 ubd_dev[n].file = NULL;
559 spin_unlock(&ubd_lock);
564 static int ubd_get_config(char *dev, char *str, int size, char **error_out)
570 major = simple_strtoul(dev, &end, 0);
571 if((*end != '\0') || (end == dev)){
572 *error_out = "ubd_get_config : didn't parse major number";
576 if((major >= MAX_DEV) || (major < 0)){
577 *error_out = "ubd_get_config : major number out of range";
581 ubd = &ubd_dev[major];
582 spin_lock(&ubd_lock);
584 if(ubd->file == NULL){
585 CONFIG_CHUNK(str, size, n, "", 1);
589 CONFIG_CHUNK(str, size, n, ubd->file, 0);
591 if(ubd->cow.file != NULL){
592 CONFIG_CHUNK(str, size, n, ",", 0);
593 CONFIG_CHUNK(str, size, n, ubd->cow.file, 1);
595 else CONFIG_CHUNK(str, size, n, "", 1);
598 spin_unlock(&ubd_lock);
602 static int ubd_remove(char *str)
605 int n, err = -ENODEV;
608 return(err); /* it should be a number 0-7/a-h */
616 return(-EBUSY); /* you cannot remove a open disk */
619 spin_lock(&ubd_lock);
621 if(ubd_gendisk[n] == NULL)
624 del_gendisk(ubd_gendisk[n]);
625 put_disk(ubd_gendisk[n]);
626 ubd_gendisk[n] = NULL;
628 if(fake_gendisk[n] != NULL){
629 del_gendisk(fake_gendisk[n]);
630 put_disk(fake_gendisk[n]);
631 fake_gendisk[n] = NULL;
634 *dev = ((struct ubd) DEFAULT_UBD);
637 spin_unlock(&ubd_lock);
641 static struct mc_device ubd_mc = {
643 .config = ubd_config,
644 .get_config = ubd_get_config,
645 .remove = ubd_remove,
648 static int ubd_mc_init(void)
650 mconsole_register_dev(&ubd_mc);
654 __initcall(ubd_mc_init);
661 if (register_blkdev(MAJOR_NR, "ubd"))
664 ubd_queue = blk_init_queue(do_ubd_request, &ubd_io_lock);
666 unregister_blkdev(MAJOR_NR, "ubd");
670 elevator_init(ubd_queue, &elevator_noop);
672 if (fake_major != 0) {
673 char name[sizeof("ubd_nnn\0")];
675 snprintf(name, sizeof(name), "ubd_%d", fake_major);
677 if (register_blkdev(fake_major, "ubd"))
680 for (i = 0; i < MAX_DEV; i++)
685 late_initcall(ubd_init);
687 int ubd_driver_init(void){
691 if(global_openflags.s){
692 printk(KERN_INFO "ubd : Synchronous mode\n");
695 stack = alloc_stack(0, 0);
696 io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
700 "ubd : Failed to start I/O thread (errno = %d) - "
701 "falling back to synchronous I/O\n", -io_pid);
704 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
705 SA_INTERRUPT, "ubd", ubd_dev);
706 if(err != 0) printk(KERN_ERR
707 "um_request_irq failed - errno = %d\n", -err);
711 device_initcall(ubd_driver_init);
713 static int ubd_open(struct inode *inode, struct file *filp)
715 struct gendisk *disk = inode->i_bdev->bd_disk;
716 struct ubd *dev = disk->private_data;
724 dev->openflags = dev->boot_openflags;
726 err = ubd_open_dev(dev);
728 printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
729 disk->disk_name, dev->file, -err);
734 if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
735 if(--dev->count == 0) ubd_close(dev);
742 static int ubd_release(struct inode * inode, struct file * file)
744 struct gendisk *disk = inode->i_bdev->bd_disk;
745 struct ubd *dev = disk->private_data;
747 if(--dev->count == 0)
752 void cowify_req(struct io_thread_req *req, struct ubd *dev)
754 int i, update_bitmap, sector = req->offset >> 9;
756 if(req->length > (sizeof(req->sector_mask) * 8) << 9)
757 panic("Operation too long");
758 if(req->op == UBD_READ) {
759 for(i = 0; i < req->length >> 9; i++){
760 if(ubd_test_bit(sector + i, (unsigned char *)
762 ubd_set_bit(i, (unsigned char *)
769 for(i = 0; i < req->length >> 9; i++){
770 ubd_set_bit(i, (unsigned char *)
772 if(!ubd_test_bit(sector + i, (unsigned char *)
775 ubd_set_bit(sector + i, (unsigned char *)
779 req->cow_offset = sector / (sizeof(unsigned long) * 8);
780 req->bitmap_words[0] =
781 dev->cow.bitmap[req->cow_offset];
782 req->bitmap_words[1] =
783 dev->cow.bitmap[req->cow_offset + 1];
784 req->cow_offset *= sizeof(unsigned long);
785 req->cow_offset += dev->cow.bitmap_offset;
790 static int prepare_request(struct request *req, struct io_thread_req *io_req)
792 struct gendisk *disk = req->rq_disk;
793 struct ubd *dev = disk->private_data;
797 if(req->rq_status == RQ_INACTIVE) return(1);
800 strcpy(req->buffer, "HOSTFS:");
801 strcat(req->buffer, dev->file);
802 spin_lock(&ubd_io_lock);
804 spin_unlock(&ubd_io_lock);
808 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
809 printk("Write attempted on readonly ubd device %s\n",
811 spin_lock(&ubd_io_lock);
813 spin_unlock(&ubd_io_lock);
818 nsect = req->current_nr_sectors;
820 io_req->op = rq_data_dir(req) == READ ? UBD_READ : UBD_WRITE;
821 io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
822 io_req->fds[1] = dev->fd;
823 io_req->offsets[0] = 0;
824 io_req->offsets[1] = dev->cow.data_offset;
825 io_req->offset = ((__u64) block) << 9;
826 io_req->length = nsect << 9;
827 io_req->buffer = req->buffer;
828 io_req->sectorsize = 1 << 9;
829 io_req->sector_mask = 0;
830 io_req->cow_offset = -1;
833 if(dev->cow.file != NULL) cowify_req(io_req, dev);
837 static void do_ubd_request(request_queue_t *q)
839 struct io_thread_req io_req;
844 while(!list_empty(&q->queue_head)){
845 req = elv_next_request(q);
846 err = prepare_request(req, &io_req);
849 ubd_finish(req, io_req.error);
854 if(do_ubd || list_empty(&q->queue_head)) return;
855 req = elv_next_request(q);
856 err = prepare_request(req, &io_req);
858 do_ubd = ubd_handler;
859 n = write_ubd_fs(thread_fd, (char *) &io_req,
861 if(n != sizeof(io_req))
862 printk("write to io thread failed, "
868 static int ubd_ioctl(struct inode * inode, struct file * file,
869 unsigned int cmd, unsigned long arg)
871 struct hd_geometry *loc = (struct hd_geometry *) arg;
872 struct ubd *dev = inode->i_bdev->bd_disk->private_data;
874 struct hd_driveid ubd_id = {
881 struct hd_geometry g;
882 struct cdrom_volctrl volume;
884 if(!loc) return(-EINVAL);
887 g.cylinders = dev->size / (128 * 32 * 512);
889 return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);
891 case HDIO_SET_UNMASKINTR:
892 if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
893 if((arg > 1) || (inode->i_bdev->bd_contains != inode->i_bdev))
897 case HDIO_GET_UNMASKINTR:
898 if(!arg) return(-EINVAL);
899 err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
904 case HDIO_GET_MULTCOUNT:
905 if(!arg) return(-EINVAL);
906 err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
911 case HDIO_SET_MULTCOUNT:
912 if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
913 if(inode->i_bdev->bd_contains != inode->i_bdev)
917 case HDIO_GET_IDENTITY:
918 ubd_id.cyls = dev->size / (128 * 32 * 512);
919 if(copy_to_user((char *) arg, (char *) &ubd_id,
925 if(copy_from_user(&volume, (char *) arg, sizeof(volume)))
927 volume.channel0 = 255;
928 volume.channel1 = 255;
929 volume.channel2 = 255;
930 volume.channel3 = 255;
931 if(copy_to_user((char *) arg, &volume, sizeof(volume)))
939 * Overrides for Emacs so that we follow Linus's tabbing style.
940 * Emacs will notice this stuff at the end of the file and automatically
941 * adjust the settings for this buffer only. This must remain at the end
943 * ---------------------------------------------------------------------------
945 * c-file-style: "linux"