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