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