include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[linux-2.6-block.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
e16f5350 22#include "linux/kernel.h"
1da177e4
LT
23#include "linux/module.h"
24#include "linux/blkdev.h"
73855e13 25#include "linux/ata.h"
1da177e4
LT
26#include "linux/hdreg.h"
27#include "linux/init.h"
1da177e4
LT
28#include "linux/cdrom.h"
29#include "linux/proc_fs.h"
6613c5e8 30#include "linux/seq_file.h"
1da177e4
LT
31#include "linux/ctype.h"
32#include "linux/capability.h"
33#include "linux/mm.h"
5a0e3ad6 34#include "linux/slab.h"
1da177e4
LT
35#include "linux/vmalloc.h"
36#include "linux/blkpg.h"
37#include "linux/genhd.h"
38#include "linux/spinlock.h"
d052d1be 39#include "linux/platform_device.h"
23464ffa 40#include "linux/scatterlist.h"
1da177e4
LT
41#include "asm/segment.h"
42#include "asm/uaccess.h"
43#include "asm/irq.h"
44#include "asm/types.h"
45#include "asm/tlbflush.h"
1da177e4
LT
46#include "mem_user.h"
47#include "kern_util.h"
48#include "kern.h"
49#include "mconsole_kern.h"
50#include "init.h"
51#include "irq_user.h"
52#include "irq_kern.h"
53#include "ubd_user.h"
1da177e4
LT
54#include "os.h"
55#include "mem.h"
56#include "mem_kern.h"
57#include "cow.h"
58
7b9014c1 59enum ubd_req { UBD_READ, UBD_WRITE };
1da177e4
LT
60
61struct io_thread_req {
62f96cb0 62 struct request *req;
91acb21f 63 enum ubd_req op;
1da177e4
LT
64 int fds[2];
65 unsigned long offsets[2];
66 unsigned long long offset;
67 unsigned long length;
68 char *buffer;
69 int sectorsize;
91acb21f
JD
70 unsigned long sector_mask;
71 unsigned long long cow_offset;
72 unsigned long bitmap_words[2];
1da177e4
LT
73 int error;
74};
75
91acb21f 76static inline int ubd_test_bit(__u64 bit, unsigned char *data)
1da177e4
LT
77{
78 __u64 n;
79 int bits, off;
80
91acb21f 81 bits = sizeof(data[0]) * 8;
1da177e4
LT
82 n = bit / bits;
83 off = bit % bits;
dc764e50 84 return (data[n] & (1 << off)) != 0;
1da177e4
LT
85}
86
91acb21f 87static inline void ubd_set_bit(__u64 bit, unsigned char *data)
1da177e4
LT
88{
89 __u64 n;
90 int bits, off;
91
91acb21f 92 bits = sizeof(data[0]) * 8;
1da177e4
LT
93 n = bit / bits;
94 off = bit % bits;
91acb21f 95 data[n] |= (1 << off);
1da177e4
LT
96}
97/*End stuff from ubd_user.h*/
98
99#define DRIVER_NAME "uml-blkdev"
100
d7fb2c38 101static DEFINE_MUTEX(ubd_lock);
1da177e4 102
a625c998
AV
103static int ubd_open(struct block_device *bdev, fmode_t mode);
104static int ubd_release(struct gendisk *disk, fmode_t mode);
105static int ubd_ioctl(struct block_device *bdev, fmode_t mode,
1da177e4 106 unsigned int cmd, unsigned long arg);
a885c8c4 107static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
1da177e4 108
97d88ac8 109#define MAX_DEV (16)
1da177e4 110
83d5cde4 111static const struct block_device_operations ubd_blops = {
1da177e4 112 .owner = THIS_MODULE,
a625c998
AV
113 .open = ubd_open,
114 .release = ubd_release,
115 .ioctl = ubd_ioctl,
a885c8c4 116 .getgeo = ubd_getgeo,
1da177e4
LT
117};
118
1da177e4 119/* Protected by ubd_lock */
792dd4fc 120static int fake_major = UBD_MAJOR;
1da177e4
LT
121static struct gendisk *ubd_gendisk[MAX_DEV];
122static struct gendisk *fake_gendisk[MAX_DEV];
6c29256c 123
1da177e4
LT
124#ifdef CONFIG_BLK_DEV_UBD_SYNC
125#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
126 .cl = 1 })
127#else
128#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 0, .c = 0, \
129 .cl = 1 })
130#endif
1da177e4
LT
131static struct openflags global_openflags = OPEN_FLAGS;
132
133struct cow {
2a9d32f6 134 /* backing file name */
1da177e4 135 char *file;
2a9d32f6 136 /* backing file fd */
1da177e4
LT
137 int fd;
138 unsigned long *bitmap;
139 unsigned long bitmap_len;
140 int bitmap_offset;
dc764e50 141 int data_offset;
1da177e4
LT
142};
143
a0044bdf
JD
144#define MAX_SG 64
145
1da177e4 146struct ubd {
a0044bdf 147 struct list_head restart;
2a9d32f6
PBG
148 /* name (and fd, below) of the file opened for writing, either the
149 * backing or the cow file. */
1da177e4
LT
150 char *file;
151 int count;
152 int fd;
153 __u64 size;
154 struct openflags boot_openflags;
155 struct openflags openflags;
84e945e3
PBG
156 unsigned shared:1;
157 unsigned no_cow:1;
1da177e4
LT
158 struct cow cow;
159 struct platform_device pdev;
62f96cb0
JD
160 struct request_queue *queue;
161 spinlock_t lock;
a0044bdf
JD
162 struct scatterlist sg[MAX_SG];
163 struct request *request;
164 int start_sg, end_sg;
1da177e4
LT
165};
166
167#define DEFAULT_COW { \
168 .file = NULL, \
dc764e50
JD
169 .fd = -1, \
170 .bitmap = NULL, \
1da177e4 171 .bitmap_offset = 0, \
dc764e50 172 .data_offset = 0, \
1da177e4
LT
173}
174
175#define DEFAULT_UBD { \
176 .file = NULL, \
177 .count = 0, \
178 .fd = -1, \
179 .size = -1, \
180 .boot_openflags = OPEN_FLAGS, \
181 .openflags = OPEN_FLAGS, \
dc764e50 182 .no_cow = 0, \
6c29256c 183 .shared = 0, \
dc764e50 184 .cow = DEFAULT_COW, \
62f96cb0 185 .lock = SPIN_LOCK_UNLOCKED, \
a0044bdf
JD
186 .request = NULL, \
187 .start_sg = 0, \
188 .end_sg = 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
2fe30a34 457/* XXX - move this inside ubd_intr. */
62f96cb0 458/* Called without dev->lock held, and only in interrupt context. */
91acb21f 459static void ubd_handler(void)
1da177e4 460{
2adcec21 461 struct io_thread_req *req;
a0044bdf
JD
462 struct ubd *ubd;
463 struct list_head *list, *next_ele;
464 unsigned long flags;
91acb21f
JD
465 int n;
466
a0044bdf 467 while(1){
a6ea4cce
JD
468 n = os_read_file(thread_fd, &req,
469 sizeof(struct io_thread_req *));
a0044bdf
JD
470 if(n != sizeof(req)){
471 if(n == -EAGAIN)
472 break;
473 printk(KERN_ERR "spurious interrupt in ubd_handler, "
474 "err = %d\n", -n);
475 return;
476 }
62f96cb0 477
4d6c84d9 478 blk_end_request(req->req, 0, req->length);
2adcec21 479 kfree(req);
a0044bdf 480 }
62f96cb0 481 reactivate_fd(thread_fd, UBD_IRQ);
a0044bdf
JD
482
483 list_for_each_safe(list, next_ele, &restart){
484 ubd = container_of(list, struct ubd, restart);
485 list_del_init(&ubd->restart);
486 spin_lock_irqsave(&ubd->lock, flags);
487 do_ubd_request(ubd->queue);
488 spin_unlock_irqrestore(&ubd->lock, flags);
489 }
1da177e4
LT
490}
491
7bea96fd 492static irqreturn_t ubd_intr(int irq, void *dev)
1da177e4 493{
91acb21f 494 ubd_handler();
dc764e50 495 return IRQ_HANDLED;
91acb21f 496}
09ace81c 497
91acb21f
JD
498/* Only changed by ubd_init, which is an initcall. */
499static int io_pid = -1;
09ace81c 500
5dc62b1b 501static void kill_io_thread(void)
91acb21f 502{
6c29256c 503 if(io_pid != -1)
91acb21f 504 os_kill_process(io_pid, 1);
09ace81c 505}
1da177e4 506
91acb21f
JD
507__uml_exitcall(kill_io_thread);
508
d8d7c28e 509static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
1da177e4
LT
510{
511 char *file;
512
7d314e34 513 file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file;
dc764e50 514 return os_file_size(file, size_out);
1da177e4
LT
515}
516
5dc62b1b
WC
517static int read_cow_bitmap(int fd, void *buf, int offset, int len)
518{
519 int err;
520
521 err = os_seek_file(fd, offset);
522 if (err < 0)
523 return err;
524
525 err = os_read_file(fd, buf, len);
526 if (err < 0)
527 return err;
528
529 return 0;
530}
531
532static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
533{
534 unsigned long modtime;
535 unsigned long long actual;
536 int err;
537
538 err = os_file_modtime(file, &modtime);
539 if (err < 0) {
540 printk(KERN_ERR "Failed to get modification time of backing "
541 "file \"%s\", err = %d\n", file, -err);
542 return err;
543 }
544
545 err = os_file_size(file, &actual);
546 if (err < 0) {
547 printk(KERN_ERR "Failed to get size of backing file \"%s\", "
548 "err = %d\n", file, -err);
549 return err;
550 }
551
552 if (actual != size) {
553 /*__u64 can be a long on AMD64 and with %lu GCC complains; so
554 * the typecast.*/
555 printk(KERN_ERR "Size mismatch (%llu vs %llu) of COW header "
556 "vs backing file\n", (unsigned long long) size, actual);
557 return -EINVAL;
558 }
559 if (modtime != mtime) {
560 printk(KERN_ERR "mtime mismatch (%ld vs %ld) of COW header vs "
561 "backing file\n", mtime, modtime);
562 return -EINVAL;
563 }
564 return 0;
565}
566
567static int path_requires_switch(char *from_cmdline, char *from_cow, char *cow)
568{
569 struct uml_stat buf1, buf2;
570 int err;
571
572 if (from_cmdline == NULL)
573 return 0;
574 if (!strcmp(from_cmdline, from_cow))
575 return 0;
576
577 err = os_stat_file(from_cmdline, &buf1);
578 if (err < 0) {
579 printk(KERN_ERR "Couldn't stat '%s', err = %d\n", from_cmdline,
580 -err);
581 return 0;
582 }
583 err = os_stat_file(from_cow, &buf2);
584 if (err < 0) {
585 printk(KERN_ERR "Couldn't stat '%s', err = %d\n", from_cow,
586 -err);
587 return 1;
588 }
589 if ((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
590 return 0;
591
592 printk(KERN_ERR "Backing file mismatch - \"%s\" requested, "
593 "\"%s\" specified in COW header of \"%s\"\n",
594 from_cmdline, from_cow, cow);
595 return 1;
596}
597
598static int open_ubd_file(char *file, struct openflags *openflags, int shared,
599 char **backing_file_out, int *bitmap_offset_out,
600 unsigned long *bitmap_len_out, int *data_offset_out,
601 int *create_cow_out)
602{
603 time_t mtime;
604 unsigned long long size;
605 __u32 version, align;
606 char *backing_file;
607 int fd, err, sectorsize, asked_switch, mode = 0644;
608
609 fd = os_open_file(file, *openflags, mode);
610 if (fd < 0) {
611 if ((fd == -ENOENT) && (create_cow_out != NULL))
612 *create_cow_out = 1;
613 if (!openflags->w ||
614 ((fd != -EROFS) && (fd != -EACCES)))
615 return fd;
616 openflags->w = 0;
617 fd = os_open_file(file, *openflags, mode);
618 if (fd < 0)
619 return fd;
620 }
621
622 if (shared)
623 printk(KERN_INFO "Not locking \"%s\" on the host\n", file);
624 else {
625 err = os_lock_file(fd, openflags->w);
626 if (err < 0) {
627 printk(KERN_ERR "Failed to lock '%s', err = %d\n",
628 file, -err);
629 goto out_close;
630 }
631 }
632
633 /* Successful return case! */
634 if (backing_file_out == NULL)
635 return fd;
636
637 err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
638 &size, &sectorsize, &align, bitmap_offset_out);
639 if (err && (*backing_file_out != NULL)) {
640 printk(KERN_ERR "Failed to read COW header from COW file "
641 "\"%s\", errno = %d\n", file, -err);
642 goto out_close;
643 }
644 if (err)
645 return fd;
646
647 asked_switch = path_requires_switch(*backing_file_out, backing_file,
648 file);
649
650 /* Allow switching only if no mismatch. */
651 if (asked_switch && !backing_file_mismatch(*backing_file_out, size,
652 mtime)) {
653 printk(KERN_ERR "Switching backing file to '%s'\n",
654 *backing_file_out);
655 err = write_cow_header(file, fd, *backing_file_out,
656 sectorsize, align, &size);
657 if (err) {
658 printk(KERN_ERR "Switch failed, errno = %d\n", -err);
659 goto out_close;
660 }
661 } else {
662 *backing_file_out = backing_file;
663 err = backing_file_mismatch(*backing_file_out, size, mtime);
664 if (err)
665 goto out_close;
666 }
667
668 cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
669 bitmap_len_out, data_offset_out);
670
671 return fd;
672 out_close:
673 os_close_file(fd);
674 return err;
675}
676
677static int create_cow_file(char *cow_file, char *backing_file,
678 struct openflags flags,
679 int sectorsize, int alignment, int *bitmap_offset_out,
680 unsigned long *bitmap_len_out, int *data_offset_out)
681{
682 int err, fd;
683
684 flags.c = 1;
685 fd = open_ubd_file(cow_file, &flags, 0, NULL, NULL, NULL, NULL, NULL);
686 if (fd < 0) {
687 err = fd;
688 printk(KERN_ERR "Open of COW file '%s' failed, errno = %d\n",
689 cow_file, -err);
690 goto out;
691 }
692
693 err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
694 bitmap_offset_out, bitmap_len_out,
695 data_offset_out);
696 if (!err)
697 return fd;
698 os_close_file(fd);
699 out:
700 return err;
701}
702
5f75a4f8 703static void ubd_close_dev(struct ubd *ubd_dev)
1da177e4 704{
7d314e34
PBG
705 os_close_file(ubd_dev->fd);
706 if(ubd_dev->cow.file == NULL)
1da177e4
LT
707 return;
708
7d314e34
PBG
709 os_close_file(ubd_dev->cow.fd);
710 vfree(ubd_dev->cow.bitmap);
711 ubd_dev->cow.bitmap = NULL;
1da177e4
LT
712}
713
7d314e34 714static int ubd_open_dev(struct ubd *ubd_dev)
1da177e4
LT
715{
716 struct openflags flags;
717 char **back_ptr;
718 int err, create_cow, *create_ptr;
0bf16bff 719 int fd;
1da177e4 720
7d314e34 721 ubd_dev->openflags = ubd_dev->boot_openflags;
1da177e4 722 create_cow = 0;
7d314e34
PBG
723 create_ptr = (ubd_dev->cow.file != NULL) ? &create_cow : NULL;
724 back_ptr = ubd_dev->no_cow ? NULL : &ubd_dev->cow.file;
0bf16bff
PBG
725
726 fd = open_ubd_file(ubd_dev->file, &ubd_dev->openflags, ubd_dev->shared,
7d314e34
PBG
727 back_ptr, &ubd_dev->cow.bitmap_offset,
728 &ubd_dev->cow.bitmap_len, &ubd_dev->cow.data_offset,
6c29256c 729 create_ptr);
1da177e4 730
0bf16bff
PBG
731 if((fd == -ENOENT) && create_cow){
732 fd = create_cow_file(ubd_dev->file, ubd_dev->cow.file,
7d314e34
PBG
733 ubd_dev->openflags, 1 << 9, PAGE_SIZE,
734 &ubd_dev->cow.bitmap_offset,
735 &ubd_dev->cow.bitmap_len,
736 &ubd_dev->cow.data_offset);
0bf16bff 737 if(fd >= 0){
1da177e4 738 printk(KERN_INFO "Creating \"%s\" as COW file for "
7d314e34 739 "\"%s\"\n", ubd_dev->file, ubd_dev->cow.file);
1da177e4
LT
740 }
741 }
742
0bf16bff 743 if(fd < 0){
7d314e34 744 printk("Failed to open '%s', errno = %d\n", ubd_dev->file,
0bf16bff
PBG
745 -fd);
746 return fd;
1da177e4 747 }
0bf16bff 748 ubd_dev->fd = fd;
1da177e4 749
7d314e34 750 if(ubd_dev->cow.file != NULL){
086fa5ff 751 blk_queue_max_hw_sectors(ubd_dev->queue, 8 * sizeof(long));
f4768ffd 752
1da177e4 753 err = -ENOMEM;
da2486ba 754 ubd_dev->cow.bitmap = vmalloc(ubd_dev->cow.bitmap_len);
7d314e34 755 if(ubd_dev->cow.bitmap == NULL){
1da177e4
LT
756 printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
757 goto error;
758 }
759 flush_tlb_kernel_vm();
760
7d314e34
PBG
761 err = read_cow_bitmap(ubd_dev->fd, ubd_dev->cow.bitmap,
762 ubd_dev->cow.bitmap_offset,
763 ubd_dev->cow.bitmap_len);
1da177e4
LT
764 if(err < 0)
765 goto error;
766
7d314e34 767 flags = ubd_dev->openflags;
1da177e4 768 flags.w = 0;
7d314e34 769 err = open_ubd_file(ubd_dev->cow.file, &flags, ubd_dev->shared, NULL,
6c29256c 770 NULL, NULL, NULL, NULL);
1da177e4 771 if(err < 0) goto error;
7d314e34 772 ubd_dev->cow.fd = err;
1da177e4 773 }
dc764e50 774 return 0;
1da177e4 775 error:
7d314e34 776 os_close_file(ubd_dev->fd);
dc764e50 777 return err;
1da177e4
LT
778}
779
2e3f5251
JD
780static void ubd_device_release(struct device *dev)
781{
8691b97b 782 struct ubd *ubd_dev = dev_get_drvdata(dev);
2e3f5251
JD
783
784 blk_cleanup_queue(ubd_dev->queue);
785 *ubd_dev = ((struct ubd) DEFAULT_UBD);
786}
787
5f75a4f8 788static int ubd_disk_register(int major, u64 size, int unit,
b8831a1d 789 struct gendisk **disk_out)
1da177e4
LT
790{
791 struct gendisk *disk;
1da177e4
LT
792
793 disk = alloc_disk(1 << UBD_SHIFT);
794 if(disk == NULL)
dc764e50 795 return -ENOMEM;
1da177e4
LT
796
797 disk->major = major;
798 disk->first_minor = unit << UBD_SHIFT;
799 disk->fops = &ubd_blops;
800 set_capacity(disk, size / 512);
792dd4fc 801 if (major == UBD_MAJOR)
1da177e4 802 sprintf(disk->disk_name, "ubd%c", 'a' + unit);
ce7b0f46 803 else
1da177e4 804 sprintf(disk->disk_name, "ubd_fake%d", unit);
1da177e4
LT
805
806 /* sysfs register (not for ide fake devices) */
792dd4fc 807 if (major == UBD_MAJOR) {
7d314e34
PBG
808 ubd_devs[unit].pdev.id = unit;
809 ubd_devs[unit].pdev.name = DRIVER_NAME;
2e3f5251 810 ubd_devs[unit].pdev.dev.release = ubd_device_release;
8691b97b 811 dev_set_drvdata(&ubd_devs[unit].pdev.dev, &ubd_devs[unit]);
7d314e34
PBG
812 platform_device_register(&ubd_devs[unit].pdev);
813 disk->driverfs_dev = &ubd_devs[unit].pdev.dev;
1da177e4
LT
814 }
815
7d314e34 816 disk->private_data = &ubd_devs[unit];
62f96cb0 817 disk->queue = ubd_devs[unit].queue;
1da177e4
LT
818 add_disk(disk);
819
820 *disk_out = disk;
821 return 0;
822}
823
824#define ROUND_BLOCK(n) ((n + ((1 << 9) - 1)) & (-1 << 9))
825
f28169d2 826static int ubd_add(int n, char **error_out)
1da177e4 827{
7d314e34 828 struct ubd *ubd_dev = &ubd_devs[n];
f28169d2 829 int err = 0;
1da177e4 830
7d314e34 831 if(ubd_dev->file == NULL)
ec7cf783 832 goto out;
1da177e4 833
7d314e34 834 err = ubd_file_size(ubd_dev, &ubd_dev->size);
f28169d2
JD
835 if(err < 0){
836 *error_out = "Couldn't determine size of device's file";
80c13749 837 goto out;
f28169d2 838 }
1da177e4 839
7d314e34 840 ubd_dev->size = ROUND_BLOCK(ubd_dev->size);
1da177e4 841
a0044bdf 842 INIT_LIST_HEAD(&ubd_dev->restart);
4f40c055 843 sg_init_table(ubd_dev->sg, MAX_SG);
a0044bdf 844
62f96cb0
JD
845 err = -ENOMEM;
846 ubd_dev->queue = blk_init_queue(do_ubd_request, &ubd_dev->lock);
847 if (ubd_dev->queue == NULL) {
848 *error_out = "Failed to initialize device queue";
80c13749 849 goto out;
62f96cb0
JD
850 }
851 ubd_dev->queue->queuedata = ubd_dev;
852
8a78362c 853 blk_queue_max_segments(ubd_dev->queue, MAX_SG);
792dd4fc 854 err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]);
62f96cb0
JD
855 if(err){
856 *error_out = "Failed to register device";
857 goto out_cleanup;
858 }
6c29256c 859
792dd4fc 860 if (fake_major != UBD_MAJOR)
5f75a4f8 861 ubd_disk_register(fake_major, ubd_dev->size, n,
62f96cb0 862 &fake_gendisk[n]);
1da177e4 863
83380cc1
JD
864 /*
865 * Perhaps this should also be under the "if (fake_major)" above
866 * using the fake_disk->disk_name
867 */
1da177e4
LT
868 if (fake_ide)
869 make_ide_entries(ubd_gendisk[n]->disk_name);
870
ec7cf783 871 err = 0;
ec7cf783
JD
872out:
873 return err;
62f96cb0
JD
874
875out_cleanup:
876 blk_cleanup_queue(ubd_dev->queue);
877 goto out;
1da177e4
LT
878}
879
f28169d2 880static int ubd_config(char *str, char **error_out)
1da177e4 881{
e7f6552f 882 int n, ret;
1da177e4 883
f28169d2
JD
884 /* This string is possibly broken up and stored, so it's only
885 * freed if ubd_setup_common fails, or if only general options
886 * were set.
887 */
970d6e3a 888 str = kstrdup(str, GFP_KERNEL);
e7f6552f 889 if (str == NULL) {
f28169d2
JD
890 *error_out = "Failed to allocate memory";
891 return -ENOMEM;
1da177e4 892 }
f28169d2
JD
893
894 ret = ubd_setup_common(str, &n, error_out);
895 if (ret)
e7f6552f 896 goto err_free;
f28169d2 897
e7f6552f
PBG
898 if (n == -1) {
899 ret = 0;
d8d7c28e 900 goto err_free;
1da177e4 901 }
1da177e4 902
dc764e50 903 mutex_lock(&ubd_lock);
f28169d2 904 ret = ubd_add(n, error_out);
e7f6552f 905 if (ret)
7d314e34 906 ubd_devs[n].file = NULL;
dc764e50 907 mutex_unlock(&ubd_lock);
1da177e4 908
e7f6552f 909out:
dc764e50 910 return ret;
e7f6552f
PBG
911
912err_free:
913 kfree(str);
914 goto out;
1da177e4
LT
915}
916
917static int ubd_get_config(char *name, char *str, int size, char **error_out)
918{
7d314e34 919 struct ubd *ubd_dev;
1da177e4
LT
920 int n, len = 0;
921
922 n = parse_unit(&name);
923 if((n >= MAX_DEV) || (n < 0)){
924 *error_out = "ubd_get_config : device number out of range";
dc764e50 925 return -1;
1da177e4
LT
926 }
927
7d314e34 928 ubd_dev = &ubd_devs[n];
d7fb2c38 929 mutex_lock(&ubd_lock);
1da177e4 930
7d314e34 931 if(ubd_dev->file == NULL){
1da177e4
LT
932 CONFIG_CHUNK(str, size, len, "", 1);
933 goto out;
934 }
935
7d314e34 936 CONFIG_CHUNK(str, size, len, ubd_dev->file, 0);
1da177e4 937
7d314e34 938 if(ubd_dev->cow.file != NULL){
1da177e4 939 CONFIG_CHUNK(str, size, len, ",", 0);
7d314e34 940 CONFIG_CHUNK(str, size, len, ubd_dev->cow.file, 1);
1da177e4
LT
941 }
942 else CONFIG_CHUNK(str, size, len, "", 1);
943
944 out:
d7fb2c38 945 mutex_unlock(&ubd_lock);
dc764e50 946 return len;
1da177e4
LT
947}
948
29d56cfe
JD
949static int ubd_id(char **str, int *start_out, int *end_out)
950{
dc764e50 951 int n;
29d56cfe
JD
952
953 n = parse_unit(str);
dc764e50
JD
954 *start_out = 0;
955 *end_out = MAX_DEV - 1;
956 return n;
29d56cfe
JD
957}
958
f28169d2 959static int ubd_remove(int n, char **error_out)
1da177e4 960{
2e3f5251 961 struct gendisk *disk = ubd_gendisk[n];
7d314e34 962 struct ubd *ubd_dev;
29d56cfe 963 int err = -ENODEV;
1da177e4 964
d7fb2c38 965 mutex_lock(&ubd_lock);
1da177e4 966
7d314e34 967 ubd_dev = &ubd_devs[n];
1da177e4 968
7d314e34 969 if(ubd_dev->file == NULL)
29d56cfe 970 goto out;
1da177e4 971
29d56cfe
JD
972 /* you cannot remove a open disk */
973 err = -EBUSY;
7d314e34 974 if(ubd_dev->count > 0)
1da177e4
LT
975 goto out;
976
dc764e50 977 ubd_gendisk[n] = NULL;
b47d2deb
JD
978 if(disk != NULL){
979 del_gendisk(disk);
980 put_disk(disk);
981 }
1da177e4
LT
982
983 if(fake_gendisk[n] != NULL){
984 del_gendisk(fake_gendisk[n]);
985 put_disk(fake_gendisk[n]);
986 fake_gendisk[n] = NULL;
987 }
988
1da177e4 989 err = 0;
2e3f5251 990 platform_device_unregister(&ubd_dev->pdev);
29d56cfe 991out:
d7fb2c38 992 mutex_unlock(&ubd_lock);
29d56cfe 993 return err;
1da177e4
LT
994}
995
f28169d2 996/* All these are called by mconsole in process context and without
b8831a1d 997 * ubd-specific locks. The structure itself is const except for .list.
f28169d2 998 */
1da177e4 999static struct mc_device ubd_mc = {
84f48d4f 1000 .list = LIST_HEAD_INIT(ubd_mc.list),
1da177e4
LT
1001 .name = "ubd",
1002 .config = ubd_config,
dc764e50 1003 .get_config = ubd_get_config,
29d56cfe 1004 .id = ubd_id,
1da177e4
LT
1005 .remove = ubd_remove,
1006};
1007
d8d7c28e 1008static int __init ubd_mc_init(void)
1da177e4
LT
1009{
1010 mconsole_register_dev(&ubd_mc);
1011 return 0;
1012}
1013
1014__initcall(ubd_mc_init);
1015
d8d7c28e
PBG
1016static int __init ubd0_init(void)
1017{
1018 struct ubd *ubd_dev = &ubd_devs[0];
1019
b8831a1d 1020 mutex_lock(&ubd_lock);
d8d7c28e
PBG
1021 if(ubd_dev->file == NULL)
1022 ubd_dev->file = "root_fs";
b8831a1d
JD
1023 mutex_unlock(&ubd_lock);
1024
dc764e50 1025 return 0;
d8d7c28e
PBG
1026}
1027
1028__initcall(ubd0_init);
1029
b8831a1d 1030/* Used in ubd_init, which is an initcall */
3ae5eaec
RK
1031static struct platform_driver ubd_driver = {
1032 .driver = {
1033 .name = DRIVER_NAME,
1034 },
1da177e4
LT
1035};
1036
d8d7c28e 1037static int __init ubd_init(void)
1da177e4 1038{
f28169d2
JD
1039 char *error;
1040 int i, err;
1da177e4 1041
792dd4fc 1042 if (register_blkdev(UBD_MAJOR, "ubd"))
1da177e4
LT
1043 return -1;
1044
792dd4fc 1045 if (fake_major != UBD_MAJOR) {
1da177e4
LT
1046 char name[sizeof("ubd_nnn\0")];
1047
1048 snprintf(name, sizeof(name), "ubd_%d", fake_major);
1da177e4
LT
1049 if (register_blkdev(fake_major, "ubd"))
1050 return -1;
1051 }
3ae5eaec 1052 platform_driver_register(&ubd_driver);
dc764e50 1053 mutex_lock(&ubd_lock);
f28169d2
JD
1054 for (i = 0; i < MAX_DEV; i++){
1055 err = ubd_add(i, &error);
1056 if(err)
1057 printk(KERN_ERR "Failed to initialize ubd device %d :"
1058 "%s\n", i, error);
1059 }
dc764e50 1060 mutex_unlock(&ubd_lock);
1da177e4
LT
1061 return 0;
1062}
1063
1064late_initcall(ubd_init);
1065
d8d7c28e 1066static int __init ubd_driver_init(void){
91acb21f
JD
1067 unsigned long stack;
1068 int err;
1069
1070 /* Set by CONFIG_BLK_DEV_UBD_SYNC or ubd=sync.*/
1071 if(global_openflags.s){
1072 printk(KERN_INFO "ubd: Synchronous mode\n");
1073 /* Letting ubd=sync be like using ubd#s= instead of ubd#= is
1074 * enough. So use anyway the io thread. */
1075 }
1076 stack = alloc_stack(0, 0);
6c29256c 1077 io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
91acb21f
JD
1078 &thread_fd);
1079 if(io_pid < 0){
6c29256c 1080 printk(KERN_ERR
91acb21f
JD
1081 "ubd : Failed to start I/O thread (errno = %d) - "
1082 "falling back to synchronous I/O\n", -io_pid);
1083 io_pid = -1;
dc764e50 1084 return 0;
91acb21f 1085 }
6c29256c 1086 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
7d314e34 1087 IRQF_DISABLED, "ubd", ubd_devs);
91acb21f
JD
1088 if(err != 0)
1089 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
f4c57a78 1090 return 0;
91acb21f
JD
1091}
1092
1093device_initcall(ubd_driver_init);
1094
a625c998 1095static int ubd_open(struct block_device *bdev, fmode_t mode)
1da177e4 1096{
a625c998 1097 struct gendisk *disk = bdev->bd_disk;
7d314e34 1098 struct ubd *ubd_dev = disk->private_data;
1da177e4
LT
1099 int err = 0;
1100
7d314e34
PBG
1101 if(ubd_dev->count == 0){
1102 err = ubd_open_dev(ubd_dev);
1da177e4
LT
1103 if(err){
1104 printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
7d314e34 1105 disk->disk_name, ubd_dev->file, -err);
1da177e4
LT
1106 goto out;
1107 }
1108 }
7d314e34
PBG
1109 ubd_dev->count++;
1110 set_disk_ro(disk, !ubd_dev->openflags.w);
2c49be99
PBG
1111
1112 /* This should no more be needed. And it didn't work anyway to exclude
1113 * read-write remounting of filesystems.*/
a625c998 1114 /*if((mode & FMODE_WRITE) && !ubd_dev->openflags.w){
5f75a4f8 1115 if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev);
1da177e4 1116 err = -EROFS;
2c49be99 1117 }*/
1da177e4 1118 out:
dc764e50 1119 return err;
1da177e4
LT
1120}
1121
a625c998 1122static int ubd_release(struct gendisk *disk, fmode_t mode)
1da177e4 1123{
7d314e34 1124 struct ubd *ubd_dev = disk->private_data;
1da177e4 1125
7d314e34 1126 if(--ubd_dev->count == 0)
5f75a4f8 1127 ubd_close_dev(ubd_dev);
dc764e50 1128 return 0;
1da177e4
LT
1129}
1130
91acb21f
JD
1131static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
1132 __u64 *cow_offset, unsigned long *bitmap,
1133 __u64 bitmap_offset, unsigned long *bitmap_words,
1134 __u64 bitmap_len)
1da177e4 1135{
91acb21f
JD
1136 __u64 sector = io_offset >> 9;
1137 int i, update_bitmap = 0;
1138
1139 for(i = 0; i < length >> 9; i++){
1140 if(cow_mask != NULL)
1141 ubd_set_bit(i, (unsigned char *) cow_mask);
1142 if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
1143 continue;
1da177e4 1144
91acb21f
JD
1145 update_bitmap = 1;
1146 ubd_set_bit(sector + i, (unsigned char *) bitmap);
1147 }
1148
1149 if(!update_bitmap)
1150 return;
1da177e4 1151
91acb21f 1152 *cow_offset = sector / (sizeof(unsigned long) * 8);
1da177e4 1153
91acb21f
JD
1154 /* This takes care of the case where we're exactly at the end of the
1155 * device, and *cow_offset + 1 is off the end. So, just back it up
1156 * by one word. Thanks to Lynn Kerby for the fix and James McMechan
1157 * for the original diagnosis.
1158 */
6d074242
JO
1159 if (*cow_offset == (DIV_ROUND_UP(bitmap_len,
1160 sizeof(unsigned long)) - 1))
91acb21f
JD
1161 (*cow_offset)--;
1162
1163 bitmap_words[0] = bitmap[*cow_offset];
1164 bitmap_words[1] = bitmap[*cow_offset + 1];
1165
1166 *cow_offset *= sizeof(unsigned long);
1167 *cow_offset += bitmap_offset;
1168}
1169
1170static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
1171 __u64 bitmap_offset, __u64 bitmap_len)
1172{
1173 __u64 sector = req->offset >> 9;
1174 int i;
1175
1176 if(req->length > (sizeof(req->sector_mask) * 8) << 9)
1177 panic("Operation too long");
1178
1179 if(req->op == UBD_READ) {
1180 for(i = 0; i < req->length >> 9; i++){
1181 if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
6c29256c 1182 ubd_set_bit(i, (unsigned char *)
91acb21f 1183 &req->sector_mask);
dc764e50 1184 }
91acb21f
JD
1185 }
1186 else cowify_bitmap(req->offset, req->length, &req->sector_mask,
1187 &req->cow_offset, bitmap, bitmap_offset,
1188 req->bitmap_words, bitmap_len);
1da177e4
LT
1189}
1190
62f96cb0 1191/* Called with dev->lock held */
a0044bdf
JD
1192static void prepare_request(struct request *req, struct io_thread_req *io_req,
1193 unsigned long long offset, int page_offset,
1194 int len, struct page *page)
1da177e4
LT
1195{
1196 struct gendisk *disk = req->rq_disk;
7d314e34 1197 struct ubd *ubd_dev = disk->private_data;
91acb21f 1198
62f96cb0 1199 io_req->req = req;
a0044bdf
JD
1200 io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd :
1201 ubd_dev->fd;
7d314e34 1202 io_req->fds[1] = ubd_dev->fd;
91acb21f 1203 io_req->cow_offset = -1;
1da177e4
LT
1204 io_req->offset = offset;
1205 io_req->length = len;
1206 io_req->error = 0;
91acb21f
JD
1207 io_req->sector_mask = 0;
1208
1209 io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
1da177e4 1210 io_req->offsets[0] = 0;
7d314e34 1211 io_req->offsets[1] = ubd_dev->cow.data_offset;
a0044bdf 1212 io_req->buffer = page_address(page) + page_offset;
1da177e4
LT
1213 io_req->sectorsize = 1 << 9;
1214
7d314e34 1215 if(ubd_dev->cow.file != NULL)
a0044bdf
JD
1216 cowify_req(io_req, ubd_dev->cow.bitmap,
1217 ubd_dev->cow.bitmap_offset, ubd_dev->cow.bitmap_len);
91acb21f 1218
1da177e4
LT
1219}
1220
62f96cb0 1221/* Called with dev->lock held */
165125e1 1222static void do_ubd_request(struct request_queue *q)
1da177e4 1223{
2adcec21 1224 struct io_thread_req *io_req;
1da177e4 1225 struct request *req;
f81f2f7c
TH
1226 sector_t sector;
1227 int n;
a0044bdf
JD
1228
1229 while(1){
2a9529a0 1230 struct ubd *dev = q->queuedata;
a0044bdf 1231 if(dev->end_sg == 0){
9934c8c0 1232 struct request *req = blk_fetch_request(q);
a0044bdf
JD
1233 if(req == NULL)
1234 return;
1235
1236 dev->request = req;
a0044bdf
JD
1237 dev->start_sg = 0;
1238 dev->end_sg = blk_rq_map_sg(q, req, dev->sg);
1239 }
1240
1241 req = dev->request;
83096ebf 1242 sector = blk_rq_pos(req);
a0044bdf
JD
1243 while(dev->start_sg < dev->end_sg){
1244 struct scatterlist *sg = &dev->sg[dev->start_sg];
1245
2adcec21 1246 io_req = kmalloc(sizeof(struct io_thread_req),
990c5587 1247 GFP_ATOMIC);
2adcec21
JD
1248 if(io_req == NULL){
1249 if(list_empty(&dev->restart))
1250 list_add(&dev->restart, &restart);
1251 return;
1252 }
1253 prepare_request(req, io_req,
f81f2f7c 1254 (unsigned long long)sector << 9,
45711f1a 1255 sg->offset, sg->length, sg_page(sg));
a0044bdf 1256
f81f2f7c 1257 sector += sg->length >> 9;
a6ea4cce
JD
1258 n = os_write_file(thread_fd, &io_req,
1259 sizeof(struct io_thread_req *));
2adcec21 1260 if(n != sizeof(struct io_thread_req *)){
a0044bdf
JD
1261 if(n != -EAGAIN)
1262 printk("write to io thread failed, "
1263 "errno = %d\n", -n);
1264 else if(list_empty(&dev->restart))
1265 list_add(&dev->restart, &restart);
12429bf9 1266 kfree(io_req);
a0044bdf
JD
1267 return;
1268 }
1269
a0044bdf 1270 dev->start_sg++;
1da177e4 1271 }
a0044bdf
JD
1272 dev->end_sg = 0;
1273 dev->request = NULL;
1da177e4
LT
1274 }
1275}
1276
a885c8c4
CH
1277static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1278{
7d314e34 1279 struct ubd *ubd_dev = bdev->bd_disk->private_data;
a885c8c4
CH
1280
1281 geo->heads = 128;
1282 geo->sectors = 32;
7d314e34 1283 geo->cylinders = ubd_dev->size / (128 * 32 * 512);
a885c8c4
CH
1284 return 0;
1285}
1286
a625c998 1287static int ubd_ioctl(struct block_device *bdev, fmode_t mode,
1da177e4
LT
1288 unsigned int cmd, unsigned long arg)
1289{
a625c998 1290 struct ubd *ubd_dev = bdev->bd_disk->private_data;
73855e13 1291 u16 ubd_id[ATA_ID_WORDS];
1da177e4
LT
1292
1293 switch (cmd) {
1da177e4 1294 struct cdrom_volctrl volume;
1da177e4 1295 case HDIO_GET_IDENTITY:
73855e13
BZ
1296 memset(&ubd_id, 0, ATA_ID_WORDS * 2);
1297 ubd_id[ATA_ID_CYLS] = ubd_dev->size / (128 * 32 * 512);
1298 ubd_id[ATA_ID_HEADS] = 128;
1299 ubd_id[ATA_ID_SECTORS] = 32;
1da177e4
LT
1300 if(copy_to_user((char __user *) arg, (char *) &ubd_id,
1301 sizeof(ubd_id)))
dc764e50
JD
1302 return -EFAULT;
1303 return 0;
b8831a1d 1304
1da177e4
LT
1305 case CDROMVOLREAD:
1306 if(copy_from_user(&volume, (char __user *) arg, sizeof(volume)))
dc764e50 1307 return -EFAULT;
1da177e4
LT
1308 volume.channel0 = 255;
1309 volume.channel1 = 255;
1310 volume.channel2 = 255;
1311 volume.channel3 = 255;
1312 if(copy_to_user((char __user *) arg, &volume, sizeof(volume)))
dc764e50
JD
1313 return -EFAULT;
1314 return 0;
1da177e4 1315 }
dc764e50 1316 return -EINVAL;
1da177e4
LT
1317}
1318
91acb21f 1319static int update_bitmap(struct io_thread_req *req)
1da177e4 1320{
91acb21f 1321 int n;
1da177e4 1322
91acb21f 1323 if(req->cow_offset == -1)
dc764e50 1324 return 0;
1da177e4 1325
91acb21f
JD
1326 n = os_seek_file(req->fds[1], req->cow_offset);
1327 if(n < 0){
1328 printk("do_io - bitmap lseek failed : err = %d\n", -n);
dc764e50 1329 return 1;
91acb21f 1330 }
1da177e4 1331
a6ea4cce
JD
1332 n = os_write_file(req->fds[1], &req->bitmap_words,
1333 sizeof(req->bitmap_words));
91acb21f
JD
1334 if(n != sizeof(req->bitmap_words)){
1335 printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
1336 req->fds[1]);
dc764e50 1337 return 1;
91acb21f 1338 }
1da177e4 1339
dc764e50 1340 return 0;
91acb21f 1341}
1da177e4 1342
5dc62b1b 1343static void do_io(struct io_thread_req *req)
91acb21f
JD
1344{
1345 char *buf;
1346 unsigned long len;
1347 int n, nsectors, start, end, bit;
1348 int err;
1349 __u64 off;
1350
1351 nsectors = req->length / req->sectorsize;
1352 start = 0;
1353 do {
1354 bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
1355 end = start;
1356 while((end < nsectors) &&
1357 (ubd_test_bit(end, (unsigned char *)
1358 &req->sector_mask) == bit))
1359 end++;
1360
1361 off = req->offset + req->offsets[bit] +
1362 start * req->sectorsize;
1363 len = (end - start) * req->sectorsize;
1364 buf = &req->buffer[start * req->sectorsize];
1365
1366 err = os_seek_file(req->fds[bit], off);
1367 if(err < 0){
1368 printk("do_io - lseek failed : err = %d\n", -err);
1369 req->error = 1;
1370 return;
1371 }
1372 if(req->op == UBD_READ){
1373 n = 0;
1374 do {
1375 buf = &buf[n];
1376 len -= n;
a6ea4cce 1377 n = os_read_file(req->fds[bit], buf, len);
91acb21f
JD
1378 if (n < 0) {
1379 printk("do_io - read failed, err = %d "
1380 "fd = %d\n", -n, req->fds[bit]);
1381 req->error = 1;
1382 return;
1383 }
1384 } while((n < len) && (n != 0));
1385 if (n < len) memset(&buf[n], 0, len - n);
1386 } else {
a6ea4cce 1387 n = os_write_file(req->fds[bit], buf, len);
91acb21f
JD
1388 if(n != len){
1389 printk("do_io - write failed err = %d "
1390 "fd = %d\n", -n, req->fds[bit]);
1391 req->error = 1;
1392 return;
1393 }
1394 }
1395
1396 start = end;
1397 } while(start < nsectors);
1da177e4 1398
91acb21f 1399 req->error = update_bitmap(req);
1da177e4 1400}
91acb21f
JD
1401
1402/* Changed in start_io_thread, which is serialized by being called only
1403 * from ubd_init, which is an initcall.
1404 */
1405int kernel_fd = -1;
1406
d8d7c28e
PBG
1407/* Only changed by the io thread. XXX: currently unused. */
1408static int io_count = 0;
91acb21f
JD
1409
1410int io_thread(void *arg)
1411{
2adcec21 1412 struct io_thread_req *req;
91acb21f
JD
1413 int n;
1414
1415 ignore_sigwinch_sig();
1416 while(1){
a6ea4cce 1417 n = os_read_file(kernel_fd, &req,
2adcec21
JD
1418 sizeof(struct io_thread_req *));
1419 if(n != sizeof(struct io_thread_req *)){
91acb21f
JD
1420 if(n < 0)
1421 printk("io_thread - read failed, fd = %d, "
1422 "err = %d\n", kernel_fd, -n);
1423 else {
1424 printk("io_thread - short read, fd = %d, "
1425 "length = %d\n", kernel_fd, n);
1426 }
1427 continue;
1428 }
1429 io_count++;
2adcec21 1430 do_io(req);
a6ea4cce 1431 n = os_write_file(kernel_fd, &req,
2adcec21
JD
1432 sizeof(struct io_thread_req *));
1433 if(n != sizeof(struct io_thread_req *))
91acb21f
JD
1434 printk("io_thread - write failed, fd = %d, err = %d\n",
1435 kernel_fd, -n);
1436 }
91acb21f 1437
1b57e9c2
JD
1438 return 0;
1439}