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