Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.31-rc7 1438 lines 34 kB view raw
1/* 2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) 3 * Licensed under the GPL 4 */ 5 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 11 * 2003-01-29 more tinkering for 2.5.59-1 12 * This should now address the sysfs problems and has 13 * the symlink for devfs to allow for booting with 14 * the common /dev/ubd/discX/... names rather than 15 * only /dev/ubdN/discN this version also has lots of 16 * clean ups preparing for ubd-many. 17 * James McMechan 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/*End stuff from ubd_user.h*/ 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 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/* Protected by ubd_lock */ 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 /* backing file name */ 133 char *file; 134 /* backing file fd */ 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 /* name (and fd, below) of the file opened for writing, either the 147 * backing or the cow file. */ 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/* Protected by ubd_lock */ 190static struct ubd ubd_devs[MAX_DEV] = { [0 ... MAX_DEV - 1] = DEFAULT_UBD }; 191 192/* Only changed by fake_ide_setup which is a setup */ 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/* If *index_out == -1 at exit, the passed option was a general one; 272 * otherwise, the str pointer is used (and owned) inside ubd_devs array, so it 273 * should not be freed on exit. 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/* Only changed by ubd_init, which is an initcall. */ 453static int thread_fd = -1; 454static LIST_HEAD(restart); 455 456/* XXX - move this inside ubd_intr. */ 457/* Called without dev->lock held, and only in interrupt context. */ 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/* Only changed by ubd_init, which is an initcall. */ 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 /*__u64 can be a long on AMD64 and with %lu GCC complains; so 553 * the typecast.*/ 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 /* Successful return case! */ 633 if (backing_file_out == NULL) 634 return fd; 635 636 err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime, 637 &size, &sectorsize, &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 /* Allow switching only if no mismatch. */ 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 /* sysfs register (not for ide fake devices) */ 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 * Perhaps this should also be under the "if (fake_major)" above 865 * using the fake_disk->disk_name 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 /* This string is possibly broken up and stored, so it's only 884 * freed if ubd_setup_common fails, or if only general options 885 * were set. 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 /* you cannot remove a open disk */ 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/* All these are called by mconsole in process context and without 996 * ubd-specific locks. The structure itself is const except for .list. 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/* Used in ubd_init, which is an initcall */ 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 /* Set by CONFIG_BLK_DEV_UBD_SYNC or ubd=sync.*/ 1070 if(global_openflags.s){ 1071 printk(KERN_INFO "ubd: Synchronous mode\n"); 1072 /* Letting ubd=sync be like using ubd#s= instead of ubd#= is 1073 * enough. So use anyway the io thread. */ 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 /* This should no more be needed. And it didn't work anyway to exclude 1112 * read-write remounting of filesystems.*/ 1113 /*if((mode & FMODE_WRITE) && !ubd_dev->openflags.w){ 1114 if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev); 1115 err = -EROFS; 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 /* This takes care of the case where we're exactly at the end of the 1154 * device, and *cow_offset + 1 is off the end. So, just back it up 1155 * by one word. Thanks to Lynn Kerby for the fix and James McMechan 1156 * for the original diagnosis. 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/* Called with dev->lock held */ 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/* Called with dev->lock held */ 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/* Changed in start_io_thread, which is serialized by being called only 1402 * from ubd_init, which is an initcall. 1403 */ 1404int kernel_fd = -1; 1405 1406/* Only changed by the io thread. XXX: currently unused. */ 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}