]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - arch/um/drivers/ubd_kern.c
block: introduce new block status code type
[mirror_ubuntu-artful-kernel.git] / arch / um / drivers / ubd_kern.c
CommitLineData
6c29256c 1/*
f88f0bdf 2 * Copyright (C) 2015-2016 Anton Ivanov (aivanov@brocade.com)
1da177e4
LT
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
1da177e4
LT
21#define UBD_SHIFT 4
22
8ea3c06a
AV
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>
37185b33 37#include <kern_util.h>
1da177e4 38#include "mconsole_kern.h"
37185b33
AV
39#include <init.h>
40#include <irq_kern.h>
8ea3c06a 41#include "ubd.h"
37185b33 42#include <os.h>
1da177e4
LT
43#include "cow.h"
44
805f11a0 45enum ubd_req { UBD_READ, UBD_WRITE, UBD_FLUSH };
1da177e4
LT
46
47struct io_thread_req {
62f96cb0 48 struct request *req;
91acb21f 49 enum ubd_req op;
1da177e4
LT
50 int fds[2];
51 unsigned long offsets[2];
52 unsigned long long offset;
53 unsigned long length;
54 char *buffer;
55 int sectorsize;
91acb21f
JD
56 unsigned long sector_mask;
57 unsigned long long cow_offset;
58 unsigned long bitmap_words[2];
1da177e4
LT
59 int error;
60};
61
f88f0bdf
AI
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
91acb21f 73static inline int ubd_test_bit(__u64 bit, unsigned char *data)
1da177e4
LT
74{
75 __u64 n;
76 int bits, off;
77
91acb21f 78 bits = sizeof(data[0]) * 8;
1da177e4
LT
79 n = bit / bits;
80 off = bit % bits;
dc764e50 81 return (data[n] & (1 << off)) != 0;
1da177e4
LT
82}
83
91acb21f 84static inline void ubd_set_bit(__u64 bit, unsigned char *data)
1da177e4
LT
85{
86 __u64 n;
87 int bits, off;
88
91acb21f 89 bits = sizeof(data[0]) * 8;
1da177e4
LT
90 n = bit / bits;
91 off = bit % bits;
91acb21f 92 data[n] |= (1 << off);
1da177e4
LT
93}
94/*End stuff from ubd_user.h*/
95
96#define DRIVER_NAME "uml-blkdev"
97
d7fb2c38 98static DEFINE_MUTEX(ubd_lock);
9a181c58 99static DEFINE_MUTEX(ubd_mutex); /* replaces BKL, might not be needed */
1da177e4 100
a625c998 101static int ubd_open(struct block_device *bdev, fmode_t mode);
db2a144b 102static void ubd_release(struct gendisk *disk, fmode_t mode);
a625c998 103static int ubd_ioctl(struct block_device *bdev, fmode_t mode,
1da177e4 104 unsigned int cmd, unsigned long arg);
a885c8c4 105static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
1da177e4 106
97d88ac8 107#define MAX_DEV (16)
1da177e4 108
83d5cde4 109static const struct block_device_operations ubd_blops = {
1da177e4 110 .owner = THIS_MODULE,
a625c998
AV
111 .open = ubd_open,
112 .release = ubd_release,
113 .ioctl = ubd_ioctl,
a885c8c4 114 .getgeo = ubd_getgeo,
1da177e4
LT
115};
116
1da177e4 117/* Protected by ubd_lock */
792dd4fc 118static int fake_major = UBD_MAJOR;
1da177e4
LT
119static struct gendisk *ubd_gendisk[MAX_DEV];
120static struct gendisk *fake_gendisk[MAX_DEV];
6c29256c 121
1da177e4
LT
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
1da177e4
LT
129static struct openflags global_openflags = OPEN_FLAGS;
130
131struct cow {
2a9d32f6 132 /* backing file name */
1da177e4 133 char *file;
2a9d32f6 134 /* backing file fd */
1da177e4
LT
135 int fd;
136 unsigned long *bitmap;
137 unsigned long bitmap_len;
138 int bitmap_offset;
dc764e50 139 int data_offset;
1da177e4
LT
140};
141
a0044bdf
JD
142#define MAX_SG 64
143
1da177e4 144struct ubd {
a0044bdf 145 struct list_head restart;
2a9d32f6
PBG
146 /* name (and fd, below) of the file opened for writing, either the
147 * backing or the cow file. */
1da177e4
LT
148 char *file;
149 int count;
150 int fd;
151 __u64 size;
152 struct openflags boot_openflags;
153 struct openflags openflags;
84e945e3
PBG
154 unsigned shared:1;
155 unsigned no_cow:1;
1da177e4
LT
156 struct cow cow;
157 struct platform_device pdev;
62f96cb0
JD
158 struct request_queue *queue;
159 spinlock_t lock;
a0044bdf
JD
160 struct scatterlist sg[MAX_SG];
161 struct request *request;
162 int start_sg, end_sg;
47526903 163 sector_t rq_pos;
1da177e4
LT
164};
165
166#define DEFAULT_COW { \
167 .file = NULL, \
dc764e50
JD
168 .fd = -1, \
169 .bitmap = NULL, \
1da177e4 170 .bitmap_offset = 0, \
dc764e50 171 .data_offset = 0, \
1da177e4
LT
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, \
dc764e50 181 .no_cow = 0, \
6c29256c 182 .shared = 0, \
dc764e50 183 .cow = DEFAULT_COW, \
22e65004 184 .lock = __SPIN_LOCK_UNLOCKED(ubd_devs.lock), \
a0044bdf
JD
185 .request = NULL, \
186 .start_sg = 0, \
187 .end_sg = 0, \
47526903 188 .rq_pos = 0, \
1da177e4
LT
189}
190
b8831a1d 191/* Protected by ubd_lock */
5dc62b1b 192static struct ubd ubd_devs[MAX_DEV] = { [0 ... MAX_DEV - 1] = DEFAULT_UBD };
1da177e4 193
1da177e4
LT
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
6613c5e8 205static int fake_ide_media_proc_show(struct seq_file *m, void *v)
1da177e4 206{
6613c5e8
AD
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);
1da177e4
LT
214}
215
6613c5e8
AD
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
c0a9290e 224static void make_ide_entries(const char *dev_name)
1da177e4
LT
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
6613c5e8 234 ent = proc_create("media", S_IRUGO, dir, &fake_ide_media_proc_fops);
1da177e4 235 if(!ent) return;
c0a9290e 236 snprintf(name, sizeof(name), "ide0/%s", dev_name);
1da177e4
LT
237 proc_symlink(dev_name, proc_ide_root, name);
238}
239
240static int fake_ide_setup(char *str)
241{
242 fake_ide = 1;
dc764e50 243 return 1;
1da177e4
LT
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)
dc764e50 261 return -1;
1da177e4
LT
262 *ptr = end;
263 }
97d88ac8 264 else if (('a' <= *str) && (*str <= 'z')) {
1da177e4
LT
265 n = *str - 'a';
266 str++;
267 *ptr = str;
268 }
dc764e50 269 return n;
1da177e4
LT
270}
271
d8d7c28e
PBG
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 */
f28169d2 276static int ubd_setup_common(char *str, int *index_out, char **error_out)
1da177e4 277{
7d314e34 278 struct ubd *ubd_dev;
1da177e4
LT
279 struct openflags flags = global_openflags;
280 char *backing_file;
b8831a1d 281 int n, err = 0, i;
1da177e4
LT
282
283 if(index_out) *index_out = -1;
284 n = *str;
285 if(n == '='){
286 char *end;
287 int major;
288
289 str++;
1da177e4
LT
290 if(!strcmp(str, "sync")){
291 global_openflags = of_sync(global_openflags);
b8831a1d 292 goto out1;
1da177e4 293 }
b8831a1d
JD
294
295 err = -EINVAL;
1da177e4
LT
296 major = simple_strtoul(str, &end, 0);
297 if((*end != '\0') || (end == str)){
f28169d2 298 *error_out = "Didn't parse major number";
b8831a1d 299 goto out1;
1da177e4
LT
300 }
301
f28169d2 302 mutex_lock(&ubd_lock);
792dd4fc 303 if (fake_major != UBD_MAJOR) {
f28169d2
JD
304 *error_out = "Can't assign a fake major twice";
305 goto out1;
306 }
6c29256c 307
f28169d2 308 fake_major = major;
1da177e4
LT
309
310 printk(KERN_INFO "Setting extra ubd major number to %d\n",
311 major);
f28169d2
JD
312 err = 0;
313 out1:
314 mutex_unlock(&ubd_lock);
315 return err;
1da177e4
LT
316 }
317
318 n = parse_unit(&str);
319 if(n < 0){
f28169d2
JD
320 *error_out = "Couldn't parse device number";
321 return -EINVAL;
1da177e4
LT
322 }
323 if(n >= MAX_DEV){
f28169d2
JD
324 *error_out = "Device number out of range";
325 return 1;
1da177e4
LT
326 }
327
f28169d2 328 err = -EBUSY;
d7fb2c38 329 mutex_lock(&ubd_lock);
1da177e4 330
7d314e34
PBG
331 ubd_dev = &ubd_devs[n];
332 if(ubd_dev->file != NULL){
f28169d2 333 *error_out = "Device is already configured";
1da177e4
LT
334 goto out;
335 }
336
337 if (index_out)
338 *index_out = n;
339
f28169d2 340 err = -EINVAL;
6c29256c 341 for (i = 0; i < sizeof("rscd="); i++) {
1da177e4
LT
342 switch (*str) {
343 case 'r':
344 flags.w = 0;
345 break;
346 case 's':
347 flags.s = 1;
348 break;
349 case 'd':
7d314e34 350 ubd_dev->no_cow = 1;
1da177e4 351 break;
6c29256c 352 case 'c':
7d314e34 353 ubd_dev->shared = 1;
6c29256c 354 break;
1da177e4
LT
355 case '=':
356 str++;
357 goto break_loop;
358 default:
f28169d2
JD
359 *error_out = "Expected '=' or flag letter "
360 "(r, s, c, or d)";
1da177e4
LT
361 goto out;
362 }
363 str++;
364 }
365
f28169d2
JD
366 if (*str == '=')
367 *error_out = "Too many flags specified";
368 else
369 *error_out = "Missing '='";
1da177e4
LT
370 goto out;
371
372break_loop:
1da177e4
LT
373 backing_file = strchr(str, ',');
374
f28169d2 375 if (backing_file == NULL)
1da177e4 376 backing_file = strchr(str, ':');
1da177e4 377
f28169d2
JD
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 }
1da177e4
LT
383 else {
384 *backing_file = '\0';
385 backing_file++;
386 }
387 }
f28169d2 388 err = 0;
7d314e34
PBG
389 ubd_dev->file = str;
390 ubd_dev->cow.file = backing_file;
391 ubd_dev->boot_openflags = flags;
1da177e4 392out:
d7fb2c38 393 mutex_unlock(&ubd_lock);
f28169d2 394 return err;
1da177e4
LT
395}
396
397static int ubd_setup(char *str)
398{
f28169d2
JD
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;
1da177e4
LT
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"
f28169d2 418" When using only one filename, UML will detect whether to treat it like\n"
1da177e4
LT
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"
20ede453
JD
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"
1da177e4
LT
433);
434
8299ca5c 435static int udb_setup(char *str)
1da177e4
LT
436{
437 printk("udb%s specified on command line is almost certainly a ubd -> "
438 "udb TYPO\n", str);
dc764e50 439 return 1;
1da177e4
LT
440}
441
442__setup("udb", udb_setup);
443__uml_help(udb_setup,
444"udb\n"
0894e27e
JD
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"
1da177e4
LT
448" in the boot output.\n\n"
449);
450
165125e1 451static void do_ubd_request(struct request_queue * q);
91acb21f
JD
452
453/* Only changed by ubd_init, which is an initcall. */
5dc62b1b 454static int thread_fd = -1;
a0044bdf
JD
455static LIST_HEAD(restart);
456
f88f0bdf
AI
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
62f96cb0 510/* Called without dev->lock held, and only in interrupt context. */
91acb21f 511static void ubd_handler(void)
1da177e4 512{
a0044bdf
JD
513 struct ubd *ubd;
514 struct list_head *list, *next_ele;
515 unsigned long flags;
91acb21f 516 int n;
f88f0bdf 517 int count;
91acb21f 518
a0044bdf 519 while(1){
f88f0bdf
AI
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) {
a0044bdf
JD
528 if(n == -EAGAIN)
529 break;
530 printk(KERN_ERR "spurious interrupt in ubd_handler, "
531 "err = %d\n", -n);
532 return;
533 }
f88f0bdf
AI
534 for (count = 0; count < n/sizeof(struct io_thread_req *); count++) {
535 blk_end_request(
536 (*irq_req_buffer)[count]->req,
2a842aca 537 BLK_STS_OK,
f88f0bdf
AI
538 (*irq_req_buffer)[count]->length
539 );
540 kfree((*irq_req_buffer)[count]);
541 }
a0044bdf 542 }
62f96cb0 543 reactivate_fd(thread_fd, UBD_IRQ);
a0044bdf
JD
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 }
1da177e4
LT
552}
553
7bea96fd 554static irqreturn_t ubd_intr(int irq, void *dev)
1da177e4 555{
91acb21f 556 ubd_handler();
dc764e50 557 return IRQ_HANDLED;
91acb21f 558}
09ace81c 559
91acb21f
JD
560/* Only changed by ubd_init, which is an initcall. */
561static int io_pid = -1;
09ace81c 562
5dc62b1b 563static void kill_io_thread(void)
91acb21f 564{
6c29256c 565 if(io_pid != -1)
91acb21f 566 os_kill_process(io_pid, 1);
09ace81c 567}
1da177e4 568
91acb21f
JD
569__uml_exitcall(kill_io_thread);
570
d8d7c28e 571static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
1da177e4
LT
572{
573 char *file;
85356398
RW
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
d4afcba9 591 fd = os_open_file(ubd_dev->file, of_read(OPENFLAGS()), 0);
85356398
RW
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);
1da177e4 598
85356398
RW
599 if(err == -EINVAL)
600 file = ubd_dev->file;
601 else
602 file = backing_file;
603
604out:
dc764e50 605 return os_file_size(file, size_out);
1da177e4
LT
606}
607
5dc62b1b
WC
608static int read_cow_bitmap(int fd, void *buf, int offset, int len)
609{
610 int err;
611
8c6157b6 612 err = os_pread_file(fd, buf, len, offset);
5dc62b1b
WC
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
5f75a4f8 790static void ubd_close_dev(struct ubd *ubd_dev)
1da177e4 791{
7d314e34
PBG
792 os_close_file(ubd_dev->fd);
793 if(ubd_dev->cow.file == NULL)
1da177e4
LT
794 return;
795
7d314e34
PBG
796 os_close_file(ubd_dev->cow.fd);
797 vfree(ubd_dev->cow.bitmap);
798 ubd_dev->cow.bitmap = NULL;
1da177e4
LT
799}
800
7d314e34 801static int ubd_open_dev(struct ubd *ubd_dev)
1da177e4
LT
802{
803 struct openflags flags;
804 char **back_ptr;
805 int err, create_cow, *create_ptr;
0bf16bff 806 int fd;
1da177e4 807
7d314e34 808 ubd_dev->openflags = ubd_dev->boot_openflags;
1da177e4 809 create_cow = 0;
7d314e34
PBG
810 create_ptr = (ubd_dev->cow.file != NULL) ? &create_cow : NULL;
811 back_ptr = ubd_dev->no_cow ? NULL : &ubd_dev->cow.file;
0bf16bff
PBG
812
813 fd = open_ubd_file(ubd_dev->file, &ubd_dev->openflags, ubd_dev->shared,
7d314e34
PBG
814 back_ptr, &ubd_dev->cow.bitmap_offset,
815 &ubd_dev->cow.bitmap_len, &ubd_dev->cow.data_offset,
6c29256c 816 create_ptr);
1da177e4 817
0bf16bff
PBG
818 if((fd == -ENOENT) && create_cow){
819 fd = create_cow_file(ubd_dev->file, ubd_dev->cow.file,
7d314e34
PBG
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);
0bf16bff 824 if(fd >= 0){
1da177e4 825 printk(KERN_INFO "Creating \"%s\" as COW file for "
7d314e34 826 "\"%s\"\n", ubd_dev->file, ubd_dev->cow.file);
1da177e4
LT
827 }
828 }
829
0bf16bff 830 if(fd < 0){
7d314e34 831 printk("Failed to open '%s', errno = %d\n", ubd_dev->file,
0bf16bff
PBG
832 -fd);
833 return fd;
1da177e4 834 }
0bf16bff 835 ubd_dev->fd = fd;
1da177e4 836
7d314e34 837 if(ubd_dev->cow.file != NULL){
086fa5ff 838 blk_queue_max_hw_sectors(ubd_dev->queue, 8 * sizeof(long));
f4768ffd 839
1da177e4 840 err = -ENOMEM;
da2486ba 841 ubd_dev->cow.bitmap = vmalloc(ubd_dev->cow.bitmap_len);
7d314e34 842 if(ubd_dev->cow.bitmap == NULL){
1da177e4
LT
843 printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
844 goto error;
845 }
846 flush_tlb_kernel_vm();
847
7d314e34
PBG
848 err = read_cow_bitmap(ubd_dev->fd, ubd_dev->cow.bitmap,
849 ubd_dev->cow.bitmap_offset,
850 ubd_dev->cow.bitmap_len);
1da177e4
LT
851 if(err < 0)
852 goto error;
853
7d314e34 854 flags = ubd_dev->openflags;
1da177e4 855 flags.w = 0;
7d314e34 856 err = open_ubd_file(ubd_dev->cow.file, &flags, ubd_dev->shared, NULL,
6c29256c 857 NULL, NULL, NULL, NULL);
1da177e4 858 if(err < 0) goto error;
7d314e34 859 ubd_dev->cow.fd = err;
1da177e4 860 }
dc764e50 861 return 0;
1da177e4 862 error:
7d314e34 863 os_close_file(ubd_dev->fd);
dc764e50 864 return err;
1da177e4
LT
865}
866
2e3f5251
JD
867static void ubd_device_release(struct device *dev)
868{
8691b97b 869 struct ubd *ubd_dev = dev_get_drvdata(dev);
2e3f5251
JD
870
871 blk_cleanup_queue(ubd_dev->queue);
872 *ubd_dev = ((struct ubd) DEFAULT_UBD);
873}
874
5f75a4f8 875static int ubd_disk_register(int major, u64 size, int unit,
b8831a1d 876 struct gendisk **disk_out)
1da177e4 877{
d72a5783 878 struct device *parent = NULL;
1da177e4 879 struct gendisk *disk;
1da177e4
LT
880
881 disk = alloc_disk(1 << UBD_SHIFT);
882 if(disk == NULL)
dc764e50 883 return -ENOMEM;
1da177e4
LT
884
885 disk->major = major;
886 disk->first_minor = unit << UBD_SHIFT;
887 disk->fops = &ubd_blops;
888 set_capacity(disk, size / 512);
792dd4fc 889 if (major == UBD_MAJOR)
1da177e4 890 sprintf(disk->disk_name, "ubd%c", 'a' + unit);
ce7b0f46 891 else
1da177e4 892 sprintf(disk->disk_name, "ubd_fake%d", unit);
1da177e4
LT
893
894 /* sysfs register (not for ide fake devices) */
792dd4fc 895 if (major == UBD_MAJOR) {
7d314e34
PBG
896 ubd_devs[unit].pdev.id = unit;
897 ubd_devs[unit].pdev.name = DRIVER_NAME;
2e3f5251 898 ubd_devs[unit].pdev.dev.release = ubd_device_release;
8691b97b 899 dev_set_drvdata(&ubd_devs[unit].pdev.dev, &ubd_devs[unit]);
7d314e34 900 platform_device_register(&ubd_devs[unit].pdev);
d72a5783 901 parent = &ubd_devs[unit].pdev.dev;
1da177e4
LT
902 }
903
7d314e34 904 disk->private_data = &ubd_devs[unit];
62f96cb0 905 disk->queue = ubd_devs[unit].queue;
d72a5783 906 device_add_disk(parent, disk);
1da177e4
LT
907
908 *disk_out = disk;
909 return 0;
910}
911
912#define ROUND_BLOCK(n) ((n + ((1 << 9) - 1)) & (-1 << 9))
913
f28169d2 914static int ubd_add(int n, char **error_out)
1da177e4 915{
7d314e34 916 struct ubd *ubd_dev = &ubd_devs[n];
f28169d2 917 int err = 0;
1da177e4 918
7d314e34 919 if(ubd_dev->file == NULL)
ec7cf783 920 goto out;
1da177e4 921
7d314e34 922 err = ubd_file_size(ubd_dev, &ubd_dev->size);
f28169d2
JD
923 if(err < 0){
924 *error_out = "Couldn't determine size of device's file";
80c13749 925 goto out;
f28169d2 926 }
1da177e4 927
7d314e34 928 ubd_dev->size = ROUND_BLOCK(ubd_dev->size);
1da177e4 929
a0044bdf 930 INIT_LIST_HEAD(&ubd_dev->restart);
4f40c055 931 sg_init_table(ubd_dev->sg, MAX_SG);
a0044bdf 932
62f96cb0
JD
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";
80c13749 937 goto out;
62f96cb0
JD
938 }
939 ubd_dev->queue->queuedata = ubd_dev;
f935a8ce 940 blk_queue_write_cache(ubd_dev->queue, true, false);
62f96cb0 941
8a78362c 942 blk_queue_max_segments(ubd_dev->queue, MAX_SG);
792dd4fc 943 err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]);
62f96cb0
JD
944 if(err){
945 *error_out = "Failed to register device";
946 goto out_cleanup;
947 }
6c29256c 948
792dd4fc 949 if (fake_major != UBD_MAJOR)
5f75a4f8 950 ubd_disk_register(fake_major, ubd_dev->size, n,
62f96cb0 951 &fake_gendisk[n]);
1da177e4 952
83380cc1
JD
953 /*
954 * Perhaps this should also be under the "if (fake_major)" above
955 * using the fake_disk->disk_name
956 */
1da177e4
LT
957 if (fake_ide)
958 make_ide_entries(ubd_gendisk[n]->disk_name);
959
ec7cf783 960 err = 0;
ec7cf783
JD
961out:
962 return err;
62f96cb0
JD
963
964out_cleanup:
965 blk_cleanup_queue(ubd_dev->queue);
966 goto out;
1da177e4
LT
967}
968
f28169d2 969static int ubd_config(char *str, char **error_out)
1da177e4 970{
e7f6552f 971 int n, ret;
1da177e4 972
f28169d2
JD
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 */
970d6e3a 977 str = kstrdup(str, GFP_KERNEL);
e7f6552f 978 if (str == NULL) {
f28169d2
JD
979 *error_out = "Failed to allocate memory";
980 return -ENOMEM;
1da177e4 981 }
f28169d2
JD
982
983 ret = ubd_setup_common(str, &n, error_out);
984 if (ret)
e7f6552f 985 goto err_free;
f28169d2 986
e7f6552f
PBG
987 if (n == -1) {
988 ret = 0;
d8d7c28e 989 goto err_free;
1da177e4 990 }
1da177e4 991
dc764e50 992 mutex_lock(&ubd_lock);
f28169d2 993 ret = ubd_add(n, error_out);
e7f6552f 994 if (ret)
7d314e34 995 ubd_devs[n].file = NULL;
dc764e50 996 mutex_unlock(&ubd_lock);
1da177e4 997
e7f6552f 998out:
dc764e50 999 return ret;
e7f6552f
PBG
1000
1001err_free:
1002 kfree(str);
1003 goto out;
1da177e4
LT
1004}
1005
1006static int ubd_get_config(char *name, char *str, int size, char **error_out)
1007{
7d314e34 1008 struct ubd *ubd_dev;
1da177e4
LT
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";
dc764e50 1014 return -1;
1da177e4
LT
1015 }
1016
7d314e34 1017 ubd_dev = &ubd_devs[n];
d7fb2c38 1018 mutex_lock(&ubd_lock);
1da177e4 1019
7d314e34 1020 if(ubd_dev->file == NULL){
1da177e4
LT
1021 CONFIG_CHUNK(str, size, len, "", 1);
1022 goto out;
1023 }
1024
7d314e34 1025 CONFIG_CHUNK(str, size, len, ubd_dev->file, 0);
1da177e4 1026
7d314e34 1027 if(ubd_dev->cow.file != NULL){
1da177e4 1028 CONFIG_CHUNK(str, size, len, ",", 0);
7d314e34 1029 CONFIG_CHUNK(str, size, len, ubd_dev->cow.file, 1);
1da177e4
LT
1030 }
1031 else CONFIG_CHUNK(str, size, len, "", 1);
1032
1033 out:
d7fb2c38 1034 mutex_unlock(&ubd_lock);
dc764e50 1035 return len;
1da177e4
LT
1036}
1037
29d56cfe
JD
1038static int ubd_id(char **str, int *start_out, int *end_out)
1039{
dc764e50 1040 int n;
29d56cfe
JD
1041
1042 n = parse_unit(str);
dc764e50
JD
1043 *start_out = 0;
1044 *end_out = MAX_DEV - 1;
1045 return n;
29d56cfe
JD
1046}
1047
f28169d2 1048static int ubd_remove(int n, char **error_out)
1da177e4 1049{
2e3f5251 1050 struct gendisk *disk = ubd_gendisk[n];
7d314e34 1051 struct ubd *ubd_dev;
29d56cfe 1052 int err = -ENODEV;
1da177e4 1053
d7fb2c38 1054 mutex_lock(&ubd_lock);
1da177e4 1055
7d314e34 1056 ubd_dev = &ubd_devs[n];
1da177e4 1057
7d314e34 1058 if(ubd_dev->file == NULL)
29d56cfe 1059 goto out;
1da177e4 1060
29d56cfe
JD
1061 /* you cannot remove a open disk */
1062 err = -EBUSY;
7d314e34 1063 if(ubd_dev->count > 0)
1da177e4
LT
1064 goto out;
1065
dc764e50 1066 ubd_gendisk[n] = NULL;
b47d2deb
JD
1067 if(disk != NULL){
1068 del_gendisk(disk);
1069 put_disk(disk);
1070 }
1da177e4
LT
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
1da177e4 1078 err = 0;
2e3f5251 1079 platform_device_unregister(&ubd_dev->pdev);
29d56cfe 1080out:
d7fb2c38 1081 mutex_unlock(&ubd_lock);
29d56cfe 1082 return err;
1da177e4
LT
1083}
1084
f28169d2 1085/* All these are called by mconsole in process context and without
b8831a1d 1086 * ubd-specific locks. The structure itself is const except for .list.
f28169d2 1087 */
1da177e4 1088static struct mc_device ubd_mc = {
84f48d4f 1089 .list = LIST_HEAD_INIT(ubd_mc.list),
1da177e4
LT
1090 .name = "ubd",
1091 .config = ubd_config,
dc764e50 1092 .get_config = ubd_get_config,
29d56cfe 1093 .id = ubd_id,
1da177e4
LT
1094 .remove = ubd_remove,
1095};
1096
d8d7c28e 1097static int __init ubd_mc_init(void)
1da177e4
LT
1098{
1099 mconsole_register_dev(&ubd_mc);
1100 return 0;
1101}
1102
1103__initcall(ubd_mc_init);
1104
d8d7c28e
PBG
1105static int __init ubd0_init(void)
1106{
1107 struct ubd *ubd_dev = &ubd_devs[0];
1108
b8831a1d 1109 mutex_lock(&ubd_lock);
d8d7c28e
PBG
1110 if(ubd_dev->file == NULL)
1111 ubd_dev->file = "root_fs";
b8831a1d
JD
1112 mutex_unlock(&ubd_lock);
1113
dc764e50 1114 return 0;
d8d7c28e
PBG
1115}
1116
1117__initcall(ubd0_init);
1118
b8831a1d 1119/* Used in ubd_init, which is an initcall */
3ae5eaec
RK
1120static struct platform_driver ubd_driver = {
1121 .driver = {
1122 .name = DRIVER_NAME,
1123 },
1da177e4
LT
1124};
1125
d8d7c28e 1126static int __init ubd_init(void)
1da177e4 1127{
f28169d2
JD
1128 char *error;
1129 int i, err;
1da177e4 1130
792dd4fc 1131 if (register_blkdev(UBD_MAJOR, "ubd"))
1da177e4
LT
1132 return -1;
1133
792dd4fc 1134 if (fake_major != UBD_MAJOR) {
1da177e4
LT
1135 char name[sizeof("ubd_nnn\0")];
1136
1137 snprintf(name, sizeof(name), "ubd_%d", fake_major);
1da177e4
LT
1138 if (register_blkdev(fake_major, "ubd"))
1139 return -1;
1140 }
f88f0bdf
AI
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 }
3ae5eaec 1163 platform_driver_register(&ubd_driver);
dc764e50 1164 mutex_lock(&ubd_lock);
f28169d2
JD
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 }
dc764e50 1171 mutex_unlock(&ubd_lock);
1da177e4
LT
1172 return 0;
1173}
1174
1175late_initcall(ubd_init);
1176
d8d7c28e 1177static int __init ubd_driver_init(void){
91acb21f
JD
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);
6c29256c 1188 io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
91acb21f
JD
1189 &thread_fd);
1190 if(io_pid < 0){
6c29256c 1191 printk(KERN_ERR
91acb21f
JD
1192 "ubd : Failed to start I/O thread (errno = %d) - "
1193 "falling back to synchronous I/O\n", -io_pid);
1194 io_pid = -1;
dc764e50 1195 return 0;
91acb21f 1196 }
6c29256c 1197 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
c0b79a90 1198 0, "ubd", ubd_devs);
91acb21f
JD
1199 if(err != 0)
1200 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
f4c57a78 1201 return 0;
91acb21f
JD
1202}
1203
1204device_initcall(ubd_driver_init);
1205
a625c998 1206static int ubd_open(struct block_device *bdev, fmode_t mode)
1da177e4 1207{
a625c998 1208 struct gendisk *disk = bdev->bd_disk;
7d314e34 1209 struct ubd *ubd_dev = disk->private_data;
1da177e4
LT
1210 int err = 0;
1211
9a181c58 1212 mutex_lock(&ubd_mutex);
7d314e34
PBG
1213 if(ubd_dev->count == 0){
1214 err = ubd_open_dev(ubd_dev);
1da177e4
LT
1215 if(err){
1216 printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
7d314e34 1217 disk->disk_name, ubd_dev->file, -err);
1da177e4
LT
1218 goto out;
1219 }
1220 }
7d314e34
PBG
1221 ubd_dev->count++;
1222 set_disk_ro(disk, !ubd_dev->openflags.w);
2c49be99
PBG
1223
1224 /* This should no more be needed. And it didn't work anyway to exclude
1225 * read-write remounting of filesystems.*/
a625c998 1226 /*if((mode & FMODE_WRITE) && !ubd_dev->openflags.w){
5f75a4f8 1227 if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev);
1da177e4 1228 err = -EROFS;
2c49be99 1229 }*/
6e9624b8 1230out:
9a181c58 1231 mutex_unlock(&ubd_mutex);
dc764e50 1232 return err;
1da177e4
LT
1233}
1234
db2a144b 1235static void ubd_release(struct gendisk *disk, fmode_t mode)
1da177e4 1236{
7d314e34 1237 struct ubd *ubd_dev = disk->private_data;
1da177e4 1238
9a181c58 1239 mutex_lock(&ubd_mutex);
7d314e34 1240 if(--ubd_dev->count == 0)
5f75a4f8 1241 ubd_close_dev(ubd_dev);
9a181c58 1242 mutex_unlock(&ubd_mutex);
1da177e4
LT
1243}
1244
91acb21f
JD
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)
1da177e4 1249{
91acb21f
JD
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;
1da177e4 1258
91acb21f
JD
1259 update_bitmap = 1;
1260 ubd_set_bit(sector + i, (unsigned char *) bitmap);
1261 }
1262
1263 if(!update_bitmap)
1264 return;
1da177e4 1265
91acb21f 1266 *cow_offset = sector / (sizeof(unsigned long) * 8);
1da177e4 1267
91acb21f
JD
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 */
6d074242
JO
1273 if (*cow_offset == (DIV_ROUND_UP(bitmap_len,
1274 sizeof(unsigned long)) - 1))
91acb21f
JD
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))
6c29256c 1296 ubd_set_bit(i, (unsigned char *)
91acb21f 1297 &req->sector_mask);
dc764e50 1298 }
91acb21f
JD
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);
1da177e4
LT
1303}
1304
62f96cb0 1305/* Called with dev->lock held */
a0044bdf
JD
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)
1da177e4
LT
1309{
1310 struct gendisk *disk = req->rq_disk;
7d314e34 1311 struct ubd *ubd_dev = disk->private_data;
91acb21f 1312
62f96cb0 1313 io_req->req = req;
a0044bdf
JD
1314 io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd :
1315 ubd_dev->fd;
7d314e34 1316 io_req->fds[1] = ubd_dev->fd;
91acb21f 1317 io_req->cow_offset = -1;
1da177e4
LT
1318 io_req->offset = offset;
1319 io_req->length = len;
1320 io_req->error = 0;
91acb21f
JD
1321 io_req->sector_mask = 0;
1322
1323 io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
1da177e4 1324 io_req->offsets[0] = 0;
7d314e34 1325 io_req->offsets[1] = ubd_dev->cow.data_offset;
a0044bdf 1326 io_req->buffer = page_address(page) + page_offset;
1da177e4
LT
1327 io_req->sectorsize = 1 << 9;
1328
7d314e34 1329 if(ubd_dev->cow.file != NULL)
a0044bdf
JD
1330 cowify_req(io_req, ubd_dev->cow.bitmap,
1331 ubd_dev->cow.bitmap_offset, ubd_dev->cow.bitmap_len);
91acb21f 1332
1da177e4
LT
1333}
1334
805f11a0
RW
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
bc1d72e7
RW
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
62f96cb0 1365/* Called with dev->lock held */
165125e1 1366static void do_ubd_request(struct request_queue *q)
1da177e4 1367{
2adcec21 1368 struct io_thread_req *io_req;
1da177e4 1369 struct request *req;
a0044bdf
JD
1370
1371 while(1){
2a9529a0 1372 struct ubd *dev = q->queuedata;
2a236122 1373 if(dev->request == NULL){
9934c8c0 1374 struct request *req = blk_fetch_request(q);
a0044bdf
JD
1375 if(req == NULL)
1376 return;
1377
1378 dev->request = req;
47526903 1379 dev->rq_pos = blk_rq_pos(req);
a0044bdf
JD
1380 dev->start_sg = 0;
1381 dev->end_sg = blk_rq_map_sg(q, req, dev->sg);
1382 }
1383
1384 req = dev->request;
805f11a0 1385
3a5e02ce 1386 if (req_op(req) == REQ_OP_FLUSH) {
805f11a0
RW
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);
2a236122
TK
1395 if (submit_request(io_req, dev) == false)
1396 return;
805f11a0
RW
1397 }
1398
a0044bdf
JD
1399 while(dev->start_sg < dev->end_sg){
1400 struct scatterlist *sg = &dev->sg[dev->start_sg];
1401
2adcec21 1402 io_req = kmalloc(sizeof(struct io_thread_req),
990c5587 1403 GFP_ATOMIC);
2adcec21
JD
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,
47526903 1410 (unsigned long long)dev->rq_pos << 9,
45711f1a 1411 sg->offset, sg->length, sg_page(sg));
a0044bdf 1412
bc1d72e7 1413 if (submit_request(io_req, dev) == false)
a0044bdf 1414 return;
a0044bdf 1415
47526903 1416 dev->rq_pos += sg->length >> 9;
a0044bdf 1417 dev->start_sg++;
1da177e4 1418 }
a0044bdf
JD
1419 dev->end_sg = 0;
1420 dev->request = NULL;
1da177e4
LT
1421 }
1422}
1423
a885c8c4
CH
1424static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1425{
7d314e34 1426 struct ubd *ubd_dev = bdev->bd_disk->private_data;
a885c8c4
CH
1427
1428 geo->heads = 128;
1429 geo->sectors = 32;
7d314e34 1430 geo->cylinders = ubd_dev->size / (128 * 32 * 512);
a885c8c4
CH
1431 return 0;
1432}
1433
a625c998 1434static int ubd_ioctl(struct block_device *bdev, fmode_t mode,
1da177e4
LT
1435 unsigned int cmd, unsigned long arg)
1436{
a625c998 1437 struct ubd *ubd_dev = bdev->bd_disk->private_data;
73855e13 1438 u16 ubd_id[ATA_ID_WORDS];
1da177e4
LT
1439
1440 switch (cmd) {
1da177e4 1441 struct cdrom_volctrl volume;
1da177e4 1442 case HDIO_GET_IDENTITY:
73855e13
BZ
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;
1da177e4
LT
1447 if(copy_to_user((char __user *) arg, (char *) &ubd_id,
1448 sizeof(ubd_id)))
dc764e50
JD
1449 return -EFAULT;
1450 return 0;
b8831a1d 1451
1da177e4
LT
1452 case CDROMVOLREAD:
1453 if(copy_from_user(&volume, (char __user *) arg, sizeof(volume)))
dc764e50 1454 return -EFAULT;
1da177e4
LT
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)))
dc764e50
JD
1460 return -EFAULT;
1461 return 0;
1da177e4 1462 }
dc764e50 1463 return -EINVAL;
1da177e4
LT
1464}
1465
91acb21f 1466static int update_bitmap(struct io_thread_req *req)
1da177e4 1467{
91acb21f 1468 int n;
1da177e4 1469
91acb21f 1470 if(req->cow_offset == -1)
dc764e50 1471 return 0;
1da177e4 1472
8c6157b6
AI
1473 n = os_pwrite_file(req->fds[1], &req->bitmap_words,
1474 sizeof(req->bitmap_words), req->cow_offset);
91acb21f
JD
1475 if(n != sizeof(req->bitmap_words)){
1476 printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
1477 req->fds[1]);
dc764e50 1478 return 1;
91acb21f 1479 }
1da177e4 1480
dc764e50 1481 return 0;
91acb21f 1482}
1da177e4 1483
5dc62b1b 1484static void do_io(struct io_thread_req *req)
91acb21f
JD
1485{
1486 char *buf;
1487 unsigned long len;
1488 int n, nsectors, start, end, bit;
91acb21f
JD
1489 __u64 off;
1490
805f11a0
RW
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
91acb21f
JD
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
91acb21f
JD
1517 if(req->op == UBD_READ){
1518 n = 0;
1519 do {
1520 buf = &buf[n];
1521 len -= n;
8c6157b6 1522 n = os_pread_file(req->fds[bit], buf, len, off);
91acb21f
JD
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 {
8c6157b6 1532 n = os_pwrite_file(req->fds[bit], buf, len, off);
91acb21f
JD
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);
1da177e4 1543
91acb21f 1544 req->error = update_bitmap(req);
1da177e4 1545}
91acb21f
JD
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
d8d7c28e
PBG
1552/* Only changed by the io thread. XXX: currently unused. */
1553static int io_count = 0;
91acb21f
JD
1554
1555int io_thread(void *arg)
1556{
f88f0bdf 1557 int n, count, written, res;
91acb21f 1558
91d44ff8
RW
1559 os_fix_helper_signals();
1560
91acb21f 1561 while(1){
f88f0bdf
AI
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 {
91acb21f 1574 printk("io_thread - read failed, fd = %d, "
f88f0bdf
AI
1575 "err = %d,"
1576 "reminder = %d\n",
1577 kernel_fd, -n, io_remainder_size);
91acb21f 1578 }
91acb21f 1579 }
f88f0bdf
AI
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);
91acb21f 1602 }
91acb21f 1603
1b57e9c2
JD
1604 return 0;
1605}