cgroup: add seq_file forward declaration for struct cftype
[deliverable/linux.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
805f11a0 44enum ubd_req { UBD_READ, UBD_WRITE, UBD_FLUSH };
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 89static int ubd_open(struct block_device *bdev, fmode_t mode);
db2a144b 90static void ubd_release(struct gendisk *disk, fmode_t mode);
a625c998 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;
805f11a0 869 blk_queue_flush(ubd_dev->queue, REQ_FLUSH);
62f96cb0 870
8a78362c 871 blk_queue_max_segments(ubd_dev->queue, MAX_SG);
792dd4fc 872 err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]);
62f96cb0
JD
873 if(err){
874 *error_out = "Failed to register device";
875 goto out_cleanup;
876 }
6c29256c 877
792dd4fc 878 if (fake_major != UBD_MAJOR)
5f75a4f8 879 ubd_disk_register(fake_major, ubd_dev->size, n,
62f96cb0 880 &fake_gendisk[n]);
1da177e4 881
83380cc1
JD
882 /*
883 * Perhaps this should also be under the "if (fake_major)" above
884 * using the fake_disk->disk_name
885 */
1da177e4
LT
886 if (fake_ide)
887 make_ide_entries(ubd_gendisk[n]->disk_name);
888
ec7cf783 889 err = 0;
ec7cf783
JD
890out:
891 return err;
62f96cb0
JD
892
893out_cleanup:
894 blk_cleanup_queue(ubd_dev->queue);
895 goto out;
1da177e4
LT
896}
897
f28169d2 898static int ubd_config(char *str, char **error_out)
1da177e4 899{
e7f6552f 900 int n, ret;
1da177e4 901
f28169d2
JD
902 /* This string is possibly broken up and stored, so it's only
903 * freed if ubd_setup_common fails, or if only general options
904 * were set.
905 */
970d6e3a 906 str = kstrdup(str, GFP_KERNEL);
e7f6552f 907 if (str == NULL) {
f28169d2
JD
908 *error_out = "Failed to allocate memory";
909 return -ENOMEM;
1da177e4 910 }
f28169d2
JD
911
912 ret = ubd_setup_common(str, &n, error_out);
913 if (ret)
e7f6552f 914 goto err_free;
f28169d2 915
e7f6552f
PBG
916 if (n == -1) {
917 ret = 0;
d8d7c28e 918 goto err_free;
1da177e4 919 }
1da177e4 920
dc764e50 921 mutex_lock(&ubd_lock);
f28169d2 922 ret = ubd_add(n, error_out);
e7f6552f 923 if (ret)
7d314e34 924 ubd_devs[n].file = NULL;
dc764e50 925 mutex_unlock(&ubd_lock);
1da177e4 926
e7f6552f 927out:
dc764e50 928 return ret;
e7f6552f
PBG
929
930err_free:
931 kfree(str);
932 goto out;
1da177e4
LT
933}
934
935static int ubd_get_config(char *name, char *str, int size, char **error_out)
936{
7d314e34 937 struct ubd *ubd_dev;
1da177e4
LT
938 int n, len = 0;
939
940 n = parse_unit(&name);
941 if((n >= MAX_DEV) || (n < 0)){
942 *error_out = "ubd_get_config : device number out of range";
dc764e50 943 return -1;
1da177e4
LT
944 }
945
7d314e34 946 ubd_dev = &ubd_devs[n];
d7fb2c38 947 mutex_lock(&ubd_lock);
1da177e4 948
7d314e34 949 if(ubd_dev->file == NULL){
1da177e4
LT
950 CONFIG_CHUNK(str, size, len, "", 1);
951 goto out;
952 }
953
7d314e34 954 CONFIG_CHUNK(str, size, len, ubd_dev->file, 0);
1da177e4 955
7d314e34 956 if(ubd_dev->cow.file != NULL){
1da177e4 957 CONFIG_CHUNK(str, size, len, ",", 0);
7d314e34 958 CONFIG_CHUNK(str, size, len, ubd_dev->cow.file, 1);
1da177e4
LT
959 }
960 else CONFIG_CHUNK(str, size, len, "", 1);
961
962 out:
d7fb2c38 963 mutex_unlock(&ubd_lock);
dc764e50 964 return len;
1da177e4
LT
965}
966
29d56cfe
JD
967static int ubd_id(char **str, int *start_out, int *end_out)
968{
dc764e50 969 int n;
29d56cfe
JD
970
971 n = parse_unit(str);
dc764e50
JD
972 *start_out = 0;
973 *end_out = MAX_DEV - 1;
974 return n;
29d56cfe
JD
975}
976
f28169d2 977static int ubd_remove(int n, char **error_out)
1da177e4 978{
2e3f5251 979 struct gendisk *disk = ubd_gendisk[n];
7d314e34 980 struct ubd *ubd_dev;
29d56cfe 981 int err = -ENODEV;
1da177e4 982
d7fb2c38 983 mutex_lock(&ubd_lock);
1da177e4 984
7d314e34 985 ubd_dev = &ubd_devs[n];
1da177e4 986
7d314e34 987 if(ubd_dev->file == NULL)
29d56cfe 988 goto out;
1da177e4 989
29d56cfe
JD
990 /* you cannot remove a open disk */
991 err = -EBUSY;
7d314e34 992 if(ubd_dev->count > 0)
1da177e4
LT
993 goto out;
994
dc764e50 995 ubd_gendisk[n] = NULL;
b47d2deb
JD
996 if(disk != NULL){
997 del_gendisk(disk);
998 put_disk(disk);
999 }
1da177e4
LT
1000
1001 if(fake_gendisk[n] != NULL){
1002 del_gendisk(fake_gendisk[n]);
1003 put_disk(fake_gendisk[n]);
1004 fake_gendisk[n] = NULL;
1005 }
1006
1da177e4 1007 err = 0;
2e3f5251 1008 platform_device_unregister(&ubd_dev->pdev);
29d56cfe 1009out:
d7fb2c38 1010 mutex_unlock(&ubd_lock);
29d56cfe 1011 return err;
1da177e4
LT
1012}
1013
f28169d2 1014/* All these are called by mconsole in process context and without
b8831a1d 1015 * ubd-specific locks. The structure itself is const except for .list.
f28169d2 1016 */
1da177e4 1017static struct mc_device ubd_mc = {
84f48d4f 1018 .list = LIST_HEAD_INIT(ubd_mc.list),
1da177e4
LT
1019 .name = "ubd",
1020 .config = ubd_config,
dc764e50 1021 .get_config = ubd_get_config,
29d56cfe 1022 .id = ubd_id,
1da177e4
LT
1023 .remove = ubd_remove,
1024};
1025
d8d7c28e 1026static int __init ubd_mc_init(void)
1da177e4
LT
1027{
1028 mconsole_register_dev(&ubd_mc);
1029 return 0;
1030}
1031
1032__initcall(ubd_mc_init);
1033
d8d7c28e
PBG
1034static int __init ubd0_init(void)
1035{
1036 struct ubd *ubd_dev = &ubd_devs[0];
1037
b8831a1d 1038 mutex_lock(&ubd_lock);
d8d7c28e
PBG
1039 if(ubd_dev->file == NULL)
1040 ubd_dev->file = "root_fs";
b8831a1d
JD
1041 mutex_unlock(&ubd_lock);
1042
dc764e50 1043 return 0;
d8d7c28e
PBG
1044}
1045
1046__initcall(ubd0_init);
1047
b8831a1d 1048/* Used in ubd_init, which is an initcall */
3ae5eaec
RK
1049static struct platform_driver ubd_driver = {
1050 .driver = {
1051 .name = DRIVER_NAME,
1052 },
1da177e4
LT
1053};
1054
d8d7c28e 1055static int __init ubd_init(void)
1da177e4 1056{
f28169d2
JD
1057 char *error;
1058 int i, err;
1da177e4 1059
792dd4fc 1060 if (register_blkdev(UBD_MAJOR, "ubd"))
1da177e4
LT
1061 return -1;
1062
792dd4fc 1063 if (fake_major != UBD_MAJOR) {
1da177e4
LT
1064 char name[sizeof("ubd_nnn\0")];
1065
1066 snprintf(name, sizeof(name), "ubd_%d", fake_major);
1da177e4
LT
1067 if (register_blkdev(fake_major, "ubd"))
1068 return -1;
1069 }
3ae5eaec 1070 platform_driver_register(&ubd_driver);
dc764e50 1071 mutex_lock(&ubd_lock);
f28169d2
JD
1072 for (i = 0; i < MAX_DEV; i++){
1073 err = ubd_add(i, &error);
1074 if(err)
1075 printk(KERN_ERR "Failed to initialize ubd device %d :"
1076 "%s\n", i, error);
1077 }
dc764e50 1078 mutex_unlock(&ubd_lock);
1da177e4
LT
1079 return 0;
1080}
1081
1082late_initcall(ubd_init);
1083
d8d7c28e 1084static int __init ubd_driver_init(void){
91acb21f
JD
1085 unsigned long stack;
1086 int err;
1087
1088 /* Set by CONFIG_BLK_DEV_UBD_SYNC or ubd=sync.*/
1089 if(global_openflags.s){
1090 printk(KERN_INFO "ubd: Synchronous mode\n");
1091 /* Letting ubd=sync be like using ubd#s= instead of ubd#= is
1092 * enough. So use anyway the io thread. */
1093 }
1094 stack = alloc_stack(0, 0);
6c29256c 1095 io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
91acb21f
JD
1096 &thread_fd);
1097 if(io_pid < 0){
6c29256c 1098 printk(KERN_ERR
91acb21f
JD
1099 "ubd : Failed to start I/O thread (errno = %d) - "
1100 "falling back to synchronous I/O\n", -io_pid);
1101 io_pid = -1;
dc764e50 1102 return 0;
91acb21f 1103 }
6c29256c 1104 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
c0b79a90 1105 0, "ubd", ubd_devs);
91acb21f
JD
1106 if(err != 0)
1107 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
f4c57a78 1108 return 0;
91acb21f
JD
1109}
1110
1111device_initcall(ubd_driver_init);
1112
a625c998 1113static int ubd_open(struct block_device *bdev, fmode_t mode)
1da177e4 1114{
a625c998 1115 struct gendisk *disk = bdev->bd_disk;
7d314e34 1116 struct ubd *ubd_dev = disk->private_data;
1da177e4
LT
1117 int err = 0;
1118
9a181c58 1119 mutex_lock(&ubd_mutex);
7d314e34
PBG
1120 if(ubd_dev->count == 0){
1121 err = ubd_open_dev(ubd_dev);
1da177e4
LT
1122 if(err){
1123 printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
7d314e34 1124 disk->disk_name, ubd_dev->file, -err);
1da177e4
LT
1125 goto out;
1126 }
1127 }
7d314e34
PBG
1128 ubd_dev->count++;
1129 set_disk_ro(disk, !ubd_dev->openflags.w);
2c49be99
PBG
1130
1131 /* This should no more be needed. And it didn't work anyway to exclude
1132 * read-write remounting of filesystems.*/
a625c998 1133 /*if((mode & FMODE_WRITE) && !ubd_dev->openflags.w){
5f75a4f8 1134 if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev);
1da177e4 1135 err = -EROFS;
2c49be99 1136 }*/
6e9624b8 1137out:
9a181c58 1138 mutex_unlock(&ubd_mutex);
dc764e50 1139 return err;
1da177e4
LT
1140}
1141
db2a144b 1142static void ubd_release(struct gendisk *disk, fmode_t mode)
1da177e4 1143{
7d314e34 1144 struct ubd *ubd_dev = disk->private_data;
1da177e4 1145
9a181c58 1146 mutex_lock(&ubd_mutex);
7d314e34 1147 if(--ubd_dev->count == 0)
5f75a4f8 1148 ubd_close_dev(ubd_dev);
9a181c58 1149 mutex_unlock(&ubd_mutex);
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
805f11a0
RW
1242/* Called with dev->lock held */
1243static void prepare_flush_request(struct request *req,
1244 struct io_thread_req *io_req)
1245{
1246 struct gendisk *disk = req->rq_disk;
1247 struct ubd *ubd_dev = disk->private_data;
1248
1249 io_req->req = req;
1250 io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd :
1251 ubd_dev->fd;
1252 io_req->op = UBD_FLUSH;
1253}
1254
bc1d72e7
RW
1255static bool submit_request(struct io_thread_req *io_req, struct ubd *dev)
1256{
1257 int n = os_write_file(thread_fd, &io_req,
1258 sizeof(io_req));
1259 if (n != sizeof(io_req)) {
1260 if (n != -EAGAIN)
1261 printk("write to io thread failed, "
1262 "errno = %d\n", -n);
1263 else if (list_empty(&dev->restart))
1264 list_add(&dev->restart, &restart);
1265
1266 kfree(io_req);
1267 return false;
1268 }
1269 return true;
1270}
1271
62f96cb0 1272/* Called with dev->lock held */
165125e1 1273static void do_ubd_request(struct request_queue *q)
1da177e4 1274{
2adcec21 1275 struct io_thread_req *io_req;
1da177e4 1276 struct request *req;
a0044bdf
JD
1277
1278 while(1){
2a9529a0 1279 struct ubd *dev = q->queuedata;
2a236122 1280 if(dev->request == NULL){
9934c8c0 1281 struct request *req = blk_fetch_request(q);
a0044bdf
JD
1282 if(req == NULL)
1283 return;
1284
1285 dev->request = req;
47526903 1286 dev->rq_pos = blk_rq_pos(req);
a0044bdf
JD
1287 dev->start_sg = 0;
1288 dev->end_sg = blk_rq_map_sg(q, req, dev->sg);
1289 }
1290
1291 req = dev->request;
805f11a0
RW
1292
1293 if (req->cmd_flags & REQ_FLUSH) {
1294 io_req = kmalloc(sizeof(struct io_thread_req),
1295 GFP_ATOMIC);
1296 if (io_req == NULL) {
1297 if (list_empty(&dev->restart))
1298 list_add(&dev->restart, &restart);
1299 return;
1300 }
1301 prepare_flush_request(req, io_req);
2a236122
TK
1302 if (submit_request(io_req, dev) == false)
1303 return;
805f11a0
RW
1304 }
1305
a0044bdf
JD
1306 while(dev->start_sg < dev->end_sg){
1307 struct scatterlist *sg = &dev->sg[dev->start_sg];
1308
2adcec21 1309 io_req = kmalloc(sizeof(struct io_thread_req),
990c5587 1310 GFP_ATOMIC);
2adcec21
JD
1311 if(io_req == NULL){
1312 if(list_empty(&dev->restart))
1313 list_add(&dev->restart, &restart);
1314 return;
1315 }
1316 prepare_request(req, io_req,
47526903 1317 (unsigned long long)dev->rq_pos << 9,
45711f1a 1318 sg->offset, sg->length, sg_page(sg));
a0044bdf 1319
bc1d72e7 1320 if (submit_request(io_req, dev) == false)
a0044bdf 1321 return;
a0044bdf 1322
47526903 1323 dev->rq_pos += sg->length >> 9;
a0044bdf 1324 dev->start_sg++;
1da177e4 1325 }
a0044bdf
JD
1326 dev->end_sg = 0;
1327 dev->request = NULL;
1da177e4
LT
1328 }
1329}
1330
a885c8c4
CH
1331static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1332{
7d314e34 1333 struct ubd *ubd_dev = bdev->bd_disk->private_data;
a885c8c4
CH
1334
1335 geo->heads = 128;
1336 geo->sectors = 32;
7d314e34 1337 geo->cylinders = ubd_dev->size / (128 * 32 * 512);
a885c8c4
CH
1338 return 0;
1339}
1340
a625c998 1341static int ubd_ioctl(struct block_device *bdev, fmode_t mode,
1da177e4
LT
1342 unsigned int cmd, unsigned long arg)
1343{
a625c998 1344 struct ubd *ubd_dev = bdev->bd_disk->private_data;
73855e13 1345 u16 ubd_id[ATA_ID_WORDS];
1da177e4
LT
1346
1347 switch (cmd) {
1da177e4 1348 struct cdrom_volctrl volume;
1da177e4 1349 case HDIO_GET_IDENTITY:
73855e13
BZ
1350 memset(&ubd_id, 0, ATA_ID_WORDS * 2);
1351 ubd_id[ATA_ID_CYLS] = ubd_dev->size / (128 * 32 * 512);
1352 ubd_id[ATA_ID_HEADS] = 128;
1353 ubd_id[ATA_ID_SECTORS] = 32;
1da177e4
LT
1354 if(copy_to_user((char __user *) arg, (char *) &ubd_id,
1355 sizeof(ubd_id)))
dc764e50
JD
1356 return -EFAULT;
1357 return 0;
b8831a1d 1358
1da177e4
LT
1359 case CDROMVOLREAD:
1360 if(copy_from_user(&volume, (char __user *) arg, sizeof(volume)))
dc764e50 1361 return -EFAULT;
1da177e4
LT
1362 volume.channel0 = 255;
1363 volume.channel1 = 255;
1364 volume.channel2 = 255;
1365 volume.channel3 = 255;
1366 if(copy_to_user((char __user *) arg, &volume, sizeof(volume)))
dc764e50
JD
1367 return -EFAULT;
1368 return 0;
1da177e4 1369 }
dc764e50 1370 return -EINVAL;
1da177e4
LT
1371}
1372
91acb21f 1373static int update_bitmap(struct io_thread_req *req)
1da177e4 1374{
91acb21f 1375 int n;
1da177e4 1376
91acb21f 1377 if(req->cow_offset == -1)
dc764e50 1378 return 0;
1da177e4 1379
91acb21f
JD
1380 n = os_seek_file(req->fds[1], req->cow_offset);
1381 if(n < 0){
1382 printk("do_io - bitmap lseek failed : err = %d\n", -n);
dc764e50 1383 return 1;
91acb21f 1384 }
1da177e4 1385
a6ea4cce
JD
1386 n = os_write_file(req->fds[1], &req->bitmap_words,
1387 sizeof(req->bitmap_words));
91acb21f
JD
1388 if(n != sizeof(req->bitmap_words)){
1389 printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
1390 req->fds[1]);
dc764e50 1391 return 1;
91acb21f 1392 }
1da177e4 1393
dc764e50 1394 return 0;
91acb21f 1395}
1da177e4 1396
5dc62b1b 1397static void do_io(struct io_thread_req *req)
91acb21f
JD
1398{
1399 char *buf;
1400 unsigned long len;
1401 int n, nsectors, start, end, bit;
1402 int err;
1403 __u64 off;
1404
805f11a0
RW
1405 if (req->op == UBD_FLUSH) {
1406 /* fds[0] is always either the rw image or our cow file */
1407 n = os_sync_file(req->fds[0]);
1408 if (n != 0) {
1409 printk("do_io - sync failed err = %d "
1410 "fd = %d\n", -n, req->fds[0]);
1411 req->error = 1;
1412 }
1413 return;
1414 }
1415
91acb21f
JD
1416 nsectors = req->length / req->sectorsize;
1417 start = 0;
1418 do {
1419 bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
1420 end = start;
1421 while((end < nsectors) &&
1422 (ubd_test_bit(end, (unsigned char *)
1423 &req->sector_mask) == bit))
1424 end++;
1425
1426 off = req->offset + req->offsets[bit] +
1427 start * req->sectorsize;
1428 len = (end - start) * req->sectorsize;
1429 buf = &req->buffer[start * req->sectorsize];
1430
1431 err = os_seek_file(req->fds[bit], off);
1432 if(err < 0){
1433 printk("do_io - lseek failed : err = %d\n", -err);
1434 req->error = 1;
1435 return;
1436 }
1437 if(req->op == UBD_READ){
1438 n = 0;
1439 do {
1440 buf = &buf[n];
1441 len -= n;
a6ea4cce 1442 n = os_read_file(req->fds[bit], buf, len);
91acb21f
JD
1443 if (n < 0) {
1444 printk("do_io - read failed, err = %d "
1445 "fd = %d\n", -n, req->fds[bit]);
1446 req->error = 1;
1447 return;
1448 }
1449 } while((n < len) && (n != 0));
1450 if (n < len) memset(&buf[n], 0, len - n);
1451 } else {
a6ea4cce 1452 n = os_write_file(req->fds[bit], buf, len);
91acb21f
JD
1453 if(n != len){
1454 printk("do_io - write failed err = %d "
1455 "fd = %d\n", -n, req->fds[bit]);
1456 req->error = 1;
1457 return;
1458 }
1459 }
1460
1461 start = end;
1462 } while(start < nsectors);
1da177e4 1463
91acb21f 1464 req->error = update_bitmap(req);
1da177e4 1465}
91acb21f
JD
1466
1467/* Changed in start_io_thread, which is serialized by being called only
1468 * from ubd_init, which is an initcall.
1469 */
1470int kernel_fd = -1;
1471
d8d7c28e
PBG
1472/* Only changed by the io thread. XXX: currently unused. */
1473static int io_count = 0;
91acb21f
JD
1474
1475int io_thread(void *arg)
1476{
2adcec21 1477 struct io_thread_req *req;
91acb21f
JD
1478 int n;
1479
91d44ff8
RW
1480 os_fix_helper_signals();
1481
91acb21f 1482 while(1){
a6ea4cce 1483 n = os_read_file(kernel_fd, &req,
2adcec21
JD
1484 sizeof(struct io_thread_req *));
1485 if(n != sizeof(struct io_thread_req *)){
91acb21f
JD
1486 if(n < 0)
1487 printk("io_thread - read failed, fd = %d, "
1488 "err = %d\n", kernel_fd, -n);
1489 else {
1490 printk("io_thread - short read, fd = %d, "
1491 "length = %d\n", kernel_fd, n);
1492 }
1493 continue;
1494 }
1495 io_count++;
2adcec21 1496 do_io(req);
a6ea4cce 1497 n = os_write_file(kernel_fd, &req,
2adcec21
JD
1498 sizeof(struct io_thread_req *));
1499 if(n != sizeof(struct io_thread_req *))
91acb21f
JD
1500 printk("io_thread - write failed, fd = %d, err = %d\n",
1501 kernel_fd, -n);
1502 }
91acb21f 1503
1b57e9c2
JD
1504 return 0;
1505}
This page took 1.29464 seconds and 5 git commands to generate.