/* 
 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
 * Licensed under the GPL
 */

/* 2001-09-28...2002-04-17
 * Partition stuff by James_McMechan@hotmail.com
 * old style ubd by setting UBD_SHIFT to 0
 * 2002-09-27...2002-10-18 massive tinkering for 2.5
 * partitions have changed in 2.5
 * 2003-01-29 more tinkering for 2.5.59-1
 * This should now address the sysfs problems and has
 * the symlink for devfs to allow for booting with
 * the common /dev/ubd/discX/... names rather than
 * only /dev/ubdN/discN this version also has lots of
 * clean ups preparing for ubd-many.
 * James McMechan
 */

#define MAJOR_NR UBD_MAJOR
#define UBD_SHIFT 4

#include "linux/config.h"
#include "linux/module.h"
#include "linux/blkdev.h"
#include "linux/hdreg.h"
#include "linux/init.h"
#include "linux/devfs_fs_kernel.h"
#include "linux/cdrom.h"
#include "linux/proc_fs.h"
#include "linux/ctype.h"
#include "linux/capability.h"
#include "linux/mm.h"
#include "linux/vmalloc.h"
#include "linux/blkpg.h"
#include "linux/genhd.h"
#include "linux/spinlock.h"
#include "asm/segment.h"
#include "asm/uaccess.h"
#include "asm/irq.h"
#include "asm/types.h"
#include "asm/tlbflush.h"
#include "user_util.h"
#include "mem_user.h"
#include "kern_util.h"
#include "kern.h"
#include "mconsole_kern.h"
#include "init.h"
#include "irq_user.h"
#include "irq_kern.h"
#include "ubd_user.h"
#include "2_5compat.h"
#include "os.h"
#include "mem.h"
#include "mem_kern.h"
#include "cow.h"

enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };

struct io_thread_req {
	enum ubd_req op;
	int fds[2];
	unsigned long offsets[2];
	unsigned long long offset;
	unsigned long length;
	char *buffer;
	int sectorsize;
	unsigned long sector_mask;
	unsigned long long cow_offset;
	unsigned long bitmap_words[2];
	int map_fd;
	unsigned long long map_offset;
	int error;
};

extern int open_ubd_file(char *file, struct openflags *openflags,
			 char **backing_file_out, int *bitmap_offset_out,
			 unsigned long *bitmap_len_out, int *data_offset_out,
			 int *create_cow_out);
extern int create_cow_file(char *cow_file, char *backing_file,
			   struct openflags flags, int sectorsize,
			   int alignment, int *bitmap_offset_out,
			   unsigned long *bitmap_len_out,
			   int *data_offset_out);
extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
extern void do_io(struct io_thread_req *req);

static inline int ubd_test_bit(__u64 bit, unsigned char *data)
{
	__u64 n;
	int bits, off;

	bits = sizeof(data[0]) * 8;
	n = bit / bits;
	off = bit % bits;
	return((data[n] & (1 << off)) != 0);
}

static inline void ubd_set_bit(__u64 bit, unsigned char *data)
{
	__u64 n;
	int bits, off;

	bits = sizeof(data[0]) * 8;
	n = bit / bits;
	off = bit % bits;
	data[n] |= (1 << off);
}
/*End stuff from ubd_user.h*/

#define DRIVER_NAME "uml-blkdev"

static DEFINE_SPINLOCK(ubd_io_lock);
static DEFINE_SPINLOCK(ubd_lock);

static void (*do_ubd)(void);

static int ubd_open(struct inode * inode, struct file * filp);
static int ubd_release(struct inode * inode, struct file * file);
static int ubd_ioctl(struct inode * inode, struct file * file,
		     unsigned int cmd, unsigned long arg);

#define MAX_DEV (8)

/* Changed in early boot */
static int ubd_do_mmap = 0;
#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE

static struct block_device_operations ubd_blops = {
        .owner		= THIS_MODULE,
        .open		= ubd_open,
        .release	= ubd_release,
        .ioctl		= ubd_ioctl,
};

/* Protected by the queue_lock */
static request_queue_t *ubd_queue;

/* Protected by ubd_lock */
static int fake_major = MAJOR_NR;

static struct gendisk *ubd_gendisk[MAX_DEV];
static struct gendisk *fake_gendisk[MAX_DEV];
 
#ifdef CONFIG_BLK_DEV_UBD_SYNC
#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
					 .cl = 1 })
#else
#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 0, .c = 0, \
					 .cl = 1 })
#endif

/* Not protected - changed only in ubd_setup_common and then only to
 * to enable O_SYNC.
 */
static struct openflags global_openflags = OPEN_FLAGS;

struct cow {
	char *file;
	int fd;
	unsigned long *bitmap;
	unsigned long bitmap_len;
	int bitmap_offset;
        int data_offset;
};

struct ubd {
	char *file;
	int count;
	int fd;
	__u64 size;
	struct openflags boot_openflags;
	struct openflags openflags;
	int no_cow;
	struct cow cow;
	struct platform_device pdev;

	int map_writes;
	int map_reads;
	int nomap_writes;
	int nomap_reads;
	int write_maps;
};

#define DEFAULT_COW { \
	.file =			NULL, \
        .fd =			-1, \
        .bitmap =		NULL, \
	.bitmap_offset =	0, \
        .data_offset =		0, \
}

#define DEFAULT_UBD { \
	.file = 		NULL, \
	.count =		0, \
	.fd =			-1, \
	.size =			-1, \
	.boot_openflags =	OPEN_FLAGS, \
	.openflags =		OPEN_FLAGS, \
        .no_cow =               0, \
        .cow =			DEFAULT_COW, \
	.map_writes		= 0, \
	.map_reads		= 0, \
	.nomap_writes		= 0, \
	.nomap_reads		= 0, \
	.write_maps		= 0, \
}

struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };

static int ubd0_init(void)
{
	struct ubd *dev = &ubd_dev[0];

	if(dev->file == NULL)
		dev->file = "root_fs";
	return(0);
}

__initcall(ubd0_init);

/* Only changed by fake_ide_setup which is a setup */
static int fake_ide = 0;
static struct proc_dir_entry *proc_ide_root = NULL;
static struct proc_dir_entry *proc_ide = NULL;

static void make_proc_ide(void)
{
	proc_ide_root = proc_mkdir("ide", NULL);
	proc_ide = proc_mkdir("ide0", proc_ide_root);
}

static int proc_ide_read_media(char *page, char **start, off_t off, int count,
			       int *eof, void *data)
{
	int len;

	strcpy(page, "disk\n");
	len = strlen("disk\n");
	len -= off;
	if (len < count){
		*eof = 1;
		if (len <= 0) return 0;
	}
	else len = count;
	*start = page + off;
	return len;
}

static void make_ide_entries(char *dev_name)
{
	struct proc_dir_entry *dir, *ent;
	char name[64];

	if(proc_ide_root == NULL) make_proc_ide();

	dir = proc_mkdir(dev_name, proc_ide);
	if(!dir) return;

	ent = create_proc_entry("media", S_IFREG|S_IRUGO, dir);
	if(!ent) return;
	ent->nlink = 1;
	ent->data = NULL;
	ent->read_proc = proc_ide_read_media;
	ent->write_proc = NULL;
	sprintf(name,"ide0/%s", dev_name);
	proc_symlink(dev_name, proc_ide_root, name);
}

static int fake_ide_setup(char *str)
{
	fake_ide = 1;
	return(1);
}

__setup("fake_ide", fake_ide_setup);

__uml_help(fake_ide_setup,
"fake_ide\n"
"    Create ide0 entries that map onto ubd devices.\n\n"
);

static int parse_unit(char **ptr)
{
	char *str = *ptr, *end;
	int n = -1;

	if(isdigit(*str)) {
		n = simple_strtoul(str, &end, 0);
		if(end == str)
			return(-1);
		*ptr = end;
	}
	else if (('a' <= *str) && (*str <= 'h')) {
		n = *str - 'a';
		str++;
		*ptr = str;
	}
	return(n);
}

static int ubd_setup_common(char *str, int *index_out)
{
	struct ubd *dev;
	struct openflags flags = global_openflags;
	char *backing_file;
	int n, err, i;

	if(index_out) *index_out = -1;
	n = *str;
	if(n == '='){
		char *end;
		int major;

		str++;
		if(!strcmp(str, "mmap")){
			CHOOSE_MODE(printk("mmap not supported by the ubd "
					   "driver in tt mode\n"),
				    ubd_do_mmap = 1);
			return(0);
		}

		if(!strcmp(str, "sync")){
			global_openflags = of_sync(global_openflags);
			return(0);
		}
		major = simple_strtoul(str, &end, 0);
		if((*end != '\0') || (end == str)){
			printk(KERN_ERR 
			       "ubd_setup : didn't parse major number\n");
			return(1);
		}

		err = 1;
 		spin_lock(&ubd_lock);
 		if(fake_major != MAJOR_NR){
 			printk(KERN_ERR "Can't assign a fake major twice\n");
 			goto out1;
 		}
 
 		fake_major = major;

		printk(KERN_INFO "Setting extra ubd major number to %d\n",
		       major);
 		err = 0;
 	out1:
 		spin_unlock(&ubd_lock);
		return(err);
	}

	n = parse_unit(&str);
	if(n < 0){
		printk(KERN_ERR "ubd_setup : couldn't parse unit number "
		       "'%s'\n", str);
		return(1);
	}
	if(n >= MAX_DEV){
		printk(KERN_ERR "ubd_setup : index %d out of range "
		       "(%d devices, from 0 to %d)\n", n, MAX_DEV, MAX_DEV - 1);
		return(1);
	}

	err = 1;
	spin_lock(&ubd_lock);

	dev = &ubd_dev[n];
	if(dev->file != NULL){
		printk(KERN_ERR "ubd_setup : device already configured\n");
		goto out;
	}

	if (index_out)
		*index_out = n;

	for (i = 0; i < 4; i++) {
		switch (*str) {
		case 'r':
			flags.w = 0;
			break;
		case 's':
			flags.s = 1;
			break;
		case 'd':
			dev->no_cow = 1;
			break;
		case '=':
			str++;
			goto break_loop;
		default:
			printk(KERN_ERR "ubd_setup : Expected '=' or flag letter (r,s or d)\n");
			goto out;
		}
		str++;
	}

        if (*str == '=')
		printk(KERN_ERR "ubd_setup : Too many flags specified\n");
        else
		printk(KERN_ERR "ubd_setup : Expected '='\n");
	goto out;

break_loop:
	err = 0;
	backing_file = strchr(str, ',');

	if (!backing_file) {
		backing_file = strchr(str, ':');
	}

	if(backing_file){
		if(dev->no_cow)
			printk(KERN_ERR "Can't specify both 'd' and a "
			       "cow file\n");
		else {
			*backing_file = '\0';
			backing_file++;
		}
	}
	dev->file = str;
	dev->cow.file = backing_file;
	dev->boot_openflags = flags;
out:
	spin_unlock(&ubd_lock);
	return(err);
}

static int ubd_setup(char *str)
{
	ubd_setup_common(str, NULL);
	return(1);
}

__setup("ubd", ubd_setup);
__uml_help(ubd_setup,
"ubd<n><flags>=<filename>[(:|,)<filename2>]\n"
"    This is used to associate a device with a file in the underlying\n"
"    filesystem. When specifying two filenames, the first one is the\n"
"    COW name and the second is the backing file name. As separator you can\n"
"    use either a ':' or a ',': the first one allows writing things like;\n"
"	ubd0=~/Uml/root_cow:~/Uml/root_backing_file\n"
"    while with a ',' the shell would not expand the 2nd '~'.\n"
"    When using only one filename, UML will detect whether to thread it like\n"
"    a COW file or a backing file. To override this detection, add the 'd'\n"
"    flag:\n"
"	ubd0d=BackingFile\n"
"    Usually, there is a filesystem in the file, but \n"
"    that's not required. Swap devices containing swap files can be\n"
"    specified like this. Also, a file which doesn't contain a\n"
"    filesystem can have its contents read in the virtual \n"
"    machine by running 'dd' on the device. <n> must be in the range\n"
"    0 to 7. Appending an 'r' to the number will cause that device\n"
"    to be mounted read-only. For example ubd1r=./ext_fs. Appending\n"
"    an 's' will cause data to be written to disk on the host immediately.\n\n"
);

static int udb_setup(char *str)
{
	printk("udb%s specified on command line is almost certainly a ubd -> "
	       "udb TYPO\n", str);
	return(1);
}

__setup("udb", udb_setup);
__uml_help(udb_setup,
"udb\n"
"    This option is here solely to catch ubd -> udb typos, which can be\n\n"
"    to impossible to catch visually unless you specifically look for\n\n"
"    them.  The only result of any option starting with 'udb' is an error\n\n"
"    in the boot output.\n\n"
);

static int fakehd_set = 0;
static int fakehd(char *str)
{
	printk(KERN_INFO "fakehd : Changing ubd name to \"hd\".\n");
	fakehd_set = 1;
	return 1;
}

__setup("fakehd", fakehd);
__uml_help(fakehd,
"fakehd\n"
"    Change the ubd device name to \"hd\".\n\n"
);

static void do_ubd_request(request_queue_t * q);

/* Only changed by ubd_init, which is an initcall. */
int thread_fd = -1;

/* Changed by ubd_handler, which is serialized because interrupts only
 * happen on CPU 0.
 */
int intr_count = 0;

/* call ubd_finish if you need to serialize */
static void __ubd_finish(struct request *req, int error)
{
	int nsect;

	if(error){
		end_request(req, 0);
		return;
	}
	nsect = req->current_nr_sectors;
	req->sector += nsect;
	req->buffer += nsect << 9;
	req->errors = 0;
	req->nr_sectors -= nsect;
	req->current_nr_sectors = 0;
	end_request(req, 1);
}

static inline void ubd_finish(struct request *req, int error)
{
 	spin_lock(&ubd_io_lock);
	__ubd_finish(req, error);
	spin_unlock(&ubd_io_lock);
}

/* Called without ubd_io_lock held */
static void ubd_handler(void)
{
	struct io_thread_req req;
	struct request *rq = elv_next_request(ubd_queue);
	int n, err;

	do_ubd = NULL;
	intr_count++;
	n = os_read_file(thread_fd, &req, sizeof(req));
	if(n != sizeof(req)){
		printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
		       "err = %d\n", os_getpid(), -n);
		spin_lock(&ubd_io_lock);
		end_request(rq, 0);
		spin_unlock(&ubd_io_lock);
		return;
	}
        
	if((req.op != UBD_MMAP) &&
	   ((req.offset != ((__u64) (rq->sector)) << 9) ||
	    (req.length != (rq->current_nr_sectors) << 9)))
		panic("I/O op mismatch");
	
	if(req.map_fd != -1){
		err = physmem_subst_mapping(req.buffer, req.map_fd,
					    req.map_offset, 1);
		if(err)
			printk("ubd_handler - physmem_subst_mapping failed, "
			       "err = %d\n", -err);
	}

	ubd_finish(rq, req.error);
	reactivate_fd(thread_fd, UBD_IRQ);	
	do_ubd_request(ubd_queue);
}

static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused)
{
	ubd_handler();
	return(IRQ_HANDLED);
}

/* Only changed by ubd_init, which is an initcall. */
static int io_pid = -1;

void kill_io_thread(void)
{
	if(io_pid != -1) 
		os_kill_process(io_pid, 1);
}

__uml_exitcall(kill_io_thread);

static int ubd_file_size(struct ubd *dev, __u64 *size_out)
{
	char *file;

	file = dev->cow.file ? dev->cow.file : dev->file;
	return(os_file_size(file, size_out));
}

static void ubd_close(struct ubd *dev)
{
	if(ubd_do_mmap)
		physmem_forget_descriptor(dev->fd);
	os_close_file(dev->fd);
	if(dev->cow.file == NULL)
		return;

	if(ubd_do_mmap)
		physmem_forget_descriptor(dev->cow.fd);
	os_close_file(dev->cow.fd);
	vfree(dev->cow.bitmap);
	dev->cow.bitmap = NULL;
}

static int ubd_open_dev(struct ubd *dev)
{
	struct openflags flags;
	char **back_ptr;
	int err, create_cow, *create_ptr;

	dev->openflags = dev->boot_openflags;
	create_cow = 0;
	create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
	back_ptr = dev->no_cow ? NULL : &dev->cow.file;
	dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr,
				&dev->cow.bitmap_offset, &dev->cow.bitmap_len, 
				&dev->cow.data_offset, create_ptr);

	if((dev->fd == -ENOENT) && create_cow){
		dev->fd = create_cow_file(dev->file, dev->cow.file, 
					  dev->openflags, 1 << 9, PAGE_SIZE,
					  &dev->cow.bitmap_offset, 
					  &dev->cow.bitmap_len,
					  &dev->cow.data_offset);
		if(dev->fd >= 0){
			printk(KERN_INFO "Creating \"%s\" as COW file for "
			       "\"%s\"\n", dev->file, dev->cow.file);
		}
	}

	if(dev->fd < 0){
		printk("Failed to open '%s', errno = %d\n", dev->file,
		       -dev->fd);
		return(dev->fd);
	}

	if(dev->cow.file != NULL){
		err = -ENOMEM;
		dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
		if(dev->cow.bitmap == NULL){
			printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
			goto error;
		}
		flush_tlb_kernel_vm();

		err = read_cow_bitmap(dev->fd, dev->cow.bitmap, 
				      dev->cow.bitmap_offset, 
				      dev->cow.bitmap_len);
		if(err < 0)
			goto error;

		flags = dev->openflags;
		flags.w = 0;
		err = open_ubd_file(dev->cow.file, &flags, NULL, NULL, NULL, 
				    NULL, NULL);
		if(err < 0) goto error;
		dev->cow.fd = err;
	}
	return(0);
 error:
	os_close_file(dev->fd);
	return(err);
}

static int ubd_new_disk(int major, u64 size, int unit,
			struct gendisk **disk_out)
			
{
	struct gendisk *disk;
	char from[sizeof("ubd/nnnnn\0")], to[sizeof("discnnnnn/disc\0")];
	int err;

	disk = alloc_disk(1 << UBD_SHIFT);
	if(disk == NULL)
		return(-ENOMEM);

	disk->major = major;
	disk->first_minor = unit << UBD_SHIFT;
	disk->fops = &ubd_blops;
	set_capacity(disk, size / 512);
	if(major == MAJOR_NR){
		sprintf(disk->disk_name, "ubd%c", 'a' + unit);
		sprintf(disk->devfs_name, "ubd/disc%d", unit);
		sprintf(from, "ubd/%d", unit);
		sprintf(to, "disc%d/disc", unit);
		err = devfs_mk_symlink(from, to);
		if(err)
			printk("ubd_new_disk failed to make link from %s to "
			       "%s, error = %d\n", from, to, err);
	}
	else {
		sprintf(disk->disk_name, "ubd_fake%d", unit);
		sprintf(disk->devfs_name, "ubd_fake/disc%d", unit);
	}

	/* sysfs register (not for ide fake devices) */
	if (major == MAJOR_NR) {
		ubd_dev[unit].pdev.id   = unit;
		ubd_dev[unit].pdev.name = DRIVER_NAME;
		platform_device_register(&ubd_dev[unit].pdev);
		disk->driverfs_dev = &ubd_dev[unit].pdev.dev;
	}

	disk->private_data = &ubd_dev[unit];
	disk->queue = ubd_queue;
	add_disk(disk);

	*disk_out = disk;
	return 0;
}

#define ROUND_BLOCK(n) ((n + ((1 << 9) - 1)) & (-1 << 9))

static int ubd_add(int n)
{
	struct ubd *dev = &ubd_dev[n];
	int err;

	if(dev->file == NULL)
		return(-ENODEV);

	if (ubd_open_dev(dev))
		return(-ENODEV);

	err = ubd_file_size(dev, &dev->size);
	if(err < 0)
		return(err);

	dev->size = ROUND_BLOCK(dev->size);

	err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
	if(err) 
		return(err);
 
	if(fake_major != MAJOR_NR)
		ubd_new_disk(fake_major, dev->size, n, 
			     &fake_gendisk[n]);

	/* perhaps this should also be under the "if (fake_major)" above */
	/* using the fake_disk->disk_name and also the fakehd_set name */
	if (fake_ide)
		make_ide_entries(ubd_gendisk[n]->disk_name);

	ubd_close(dev);
	return 0;
}

static int ubd_config(char *str)
{
	int n, err;

	str = uml_strdup(str);
	if(str == NULL){
		printk(KERN_ERR "ubd_config failed to strdup string\n");
		return(1);
	}
	err = ubd_setup_common(str, &n);
	if(err){
		kfree(str);
		return(-1);
	}
	if(n == -1) return(0);

 	spin_lock(&ubd_lock);
	err = ubd_add(n);
	if(err)
		ubd_dev[n].file = NULL;
 	spin_unlock(&ubd_lock);

	return(err);
}

static int ubd_get_config(char *name, char *str, int size, char **error_out)
{
	struct ubd *dev;
	int n, len = 0;

	n = parse_unit(&name);
	if((n >= MAX_DEV) || (n < 0)){
		*error_out = "ubd_get_config : device number out of range";
		return(-1);
	}

	dev = &ubd_dev[n];
	spin_lock(&ubd_lock);

	if(dev->file == NULL){
		CONFIG_CHUNK(str, size, len, "", 1);
		goto out;
	}

	CONFIG_CHUNK(str, size, len, dev->file, 0);

	if(dev->cow.file != NULL){
		CONFIG_CHUNK(str, size, len, ",", 0);
		CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
	}
	else CONFIG_CHUNK(str, size, len, "", 1);

 out:
	spin_unlock(&ubd_lock);
	return(len);
}

static int ubd_remove(char *str)
{
	struct ubd *dev;
	int n, err = -ENODEV;

	n = parse_unit(&str);

	if((n < 0) || (n >= MAX_DEV))
		return(err);

	dev = &ubd_dev[n];
	if(dev->count > 0)
		return(-EBUSY);	/* you cannot remove a open disk */

	err = 0;
 	spin_lock(&ubd_lock);

	if(ubd_gendisk[n] == NULL)
		goto out;

	del_gendisk(ubd_gendisk[n]);
	put_disk(ubd_gendisk[n]);
	ubd_gendisk[n] = NULL;

	if(fake_gendisk[n] != NULL){
		del_gendisk(fake_gendisk[n]);
		put_disk(fake_gendisk[n]);
		fake_gendisk[n] = NULL;
	}

	platform_device_unregister(&dev->pdev);
	*dev = ((struct ubd) DEFAULT_UBD);
	err = 0;
 out:
 	spin_unlock(&ubd_lock);
	return(err);
}

static struct mc_device ubd_mc = {
	.name		= "ubd",
	.config		= ubd_config,
 	.get_config	= ubd_get_config,
	.remove		= ubd_remove,
};

static int ubd_mc_init(void)
{
	mconsole_register_dev(&ubd_mc);
	return 0;
}

__initcall(ubd_mc_init);

static struct device_driver ubd_driver = {
	.name  = DRIVER_NAME,
	.bus   = &platform_bus_type,
};

int ubd_init(void)
{
        int i;

	devfs_mk_dir("ubd");
	if (register_blkdev(MAJOR_NR, "ubd"))
		return -1;

	ubd_queue = blk_init_queue(do_ubd_request, &ubd_io_lock);
	if (!ubd_queue) {
		unregister_blkdev(MAJOR_NR, "ubd");
		return -1;
	}
		
	if (fake_major != MAJOR_NR) {
		char name[sizeof("ubd_nnn\0")];

		snprintf(name, sizeof(name), "ubd_%d", fake_major);
		devfs_mk_dir(name);
		if (register_blkdev(fake_major, "ubd"))
			return -1;
	}
	driver_register(&ubd_driver);
	for (i = 0; i < MAX_DEV; i++) 
		ubd_add(i);
	return 0;
}

late_initcall(ubd_init);

int ubd_driver_init(void){
	unsigned long stack;
	int err;

	/* Set by CONFIG_BLK_DEV_UBD_SYNC or ubd=sync.*/
	if(global_openflags.s){
		printk(KERN_INFO "ubd: Synchronous mode\n");
		/* Letting ubd=sync be like using ubd#s= instead of ubd#= is
		 * enough. So use anyway the io thread. */
	}
	stack = alloc_stack(0, 0);
	io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *), 
				 &thread_fd);
	if(io_pid < 0){
		printk(KERN_ERR 
		       "ubd : Failed to start I/O thread (errno = %d) - "
		       "falling back to synchronous I/O\n", -io_pid);
		io_pid = -1;
		return(0);
	}
	err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, 
			     SA_INTERRUPT, "ubd", ubd_dev);
	if(err != 0)
		printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
	return(err);
}

device_initcall(ubd_driver_init);

static int ubd_open(struct inode *inode, struct file *filp)
{
	struct gendisk *disk = inode->i_bdev->bd_disk;
	struct ubd *dev = disk->private_data;
	int err = 0;

	if(dev->count == 0){
		err = ubd_open_dev(dev);
		if(err){
			printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
			       disk->disk_name, dev->file, -err);
			goto out;
		}
	}
	dev->count++;
	if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
	        if(--dev->count == 0) ubd_close(dev);
	        err = -EROFS;
	}
 out:
	return(err);
}

static int ubd_release(struct inode * inode, struct file * file)
{
	struct gendisk *disk = inode->i_bdev->bd_disk;
	struct ubd *dev = disk->private_data;

	if(--dev->count == 0)
		ubd_close(dev);
	return(0);
}

static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
			  __u64 *cow_offset, unsigned long *bitmap,
			  __u64 bitmap_offset, unsigned long *bitmap_words,
			  __u64 bitmap_len)
{
	__u64 sector = io_offset >> 9;
	int i, update_bitmap = 0;

	for(i = 0; i < length >> 9; i++){
		if(cow_mask != NULL)
			ubd_set_bit(i, (unsigned char *) cow_mask);
		if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
			continue;

		update_bitmap = 1;
		ubd_set_bit(sector + i, (unsigned char *) bitmap);
	}

	if(!update_bitmap)
		return;

	*cow_offset = sector / (sizeof(unsigned long) * 8);

	/* This takes care of the case where we're exactly at the end of the
	 * device, and *cow_offset + 1 is off the end.  So, just back it up
	 * by one word.  Thanks to Lynn Kerby for the fix and James McMechan
	 * for the original diagnosis.
	 */
	if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) /
			   sizeof(unsigned long) - 1))
		(*cow_offset)--;

	bitmap_words[0] = bitmap[*cow_offset];
	bitmap_words[1] = bitmap[*cow_offset + 1];

	*cow_offset *= sizeof(unsigned long);
	*cow_offset += bitmap_offset;
}

static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
		       __u64 bitmap_offset, __u64 bitmap_len)
{
	__u64 sector = req->offset >> 9;
	int i;

	if(req->length > (sizeof(req->sector_mask) * 8) << 9)
		panic("Operation too long");

	if(req->op == UBD_READ) {
		for(i = 0; i < req->length >> 9; i++){
			if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
				ubd_set_bit(i, (unsigned char *) 
					    &req->sector_mask);
                }
	}
	else cowify_bitmap(req->offset, req->length, &req->sector_mask,
			   &req->cow_offset, bitmap, bitmap_offset,
			   req->bitmap_words, bitmap_len);
}

static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset)
{
	__u64 sector;
	unsigned char *bitmap;
	int bit, i;

	/* mmap must have been requested on the command line */
	if(!ubd_do_mmap)
		return(-1);

	/* The buffer must be page aligned */
	if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0)
		return(-1);

	/* The request must be a page long */
	if((req->current_nr_sectors << 9) != PAGE_SIZE)
		return(-1);

	if(dev->cow.file == NULL)
		return(dev->fd);

	sector = offset >> 9;
	bitmap = (unsigned char *) dev->cow.bitmap;
	bit = ubd_test_bit(sector, bitmap);

	for(i = 1; i < req->current_nr_sectors; i++){
		if(ubd_test_bit(sector + i, bitmap) != bit)
			return(-1);
	}

	if(bit || (rq_data_dir(req) == WRITE))
		offset += dev->cow.data_offset;

	/* The data on disk must be page aligned */
	if((offset % UBD_MMAP_BLOCK_SIZE) != 0)
		return(-1);

	return(bit ? dev->fd : dev->cow.fd);
}

static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset,
				struct request *req,
				struct io_thread_req *io_req)
{
	int err;

	if(rq_data_dir(req) == WRITE){
		/* Writes are almost no-ops since the new data is already in the
		 * host page cache
		 */
		dev->map_writes++;
		if(dev->cow.file != NULL)
			cowify_bitmap(io_req->offset, io_req->length,
				      &io_req->sector_mask, &io_req->cow_offset,
				      dev->cow.bitmap, dev->cow.bitmap_offset,
				      io_req->bitmap_words,
				      dev->cow.bitmap_len);
	}
	else {
		int w;

		if((dev->cow.file != NULL) && (fd == dev->cow.fd))
			w = 0;
		else w = dev->openflags.w;

		if((dev->cow.file != NULL) && (fd == dev->fd))
			offset += dev->cow.data_offset;

		err = physmem_subst_mapping(req->buffer, fd, offset, w);
		if(err){
			printk("physmem_subst_mapping failed, err = %d\n",
			       -err);
			return(1);
		}
		dev->map_reads++;
	}
	io_req->op = UBD_MMAP;
	io_req->buffer = req->buffer;
	return(0);
}

/* Called with ubd_io_lock held */
static int prepare_request(struct request *req, struct io_thread_req *io_req)
{
	struct gendisk *disk = req->rq_disk;
	struct ubd *dev = disk->private_data;
	__u64 offset;
	int len, fd;

	if(req->rq_status == RQ_INACTIVE) return(1);

	if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
		printk("Write attempted on readonly ubd device %s\n", 
		       disk->disk_name);
		end_request(req, 0);
		return(1);
	}

	offset = ((__u64) req->sector) << 9;
	len = req->current_nr_sectors << 9;

	io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
	io_req->fds[1] = dev->fd;
	io_req->map_fd = -1;
	io_req->cow_offset = -1;
	io_req->offset = offset;
	io_req->length = len;
	io_req->error = 0;
	io_req->sector_mask = 0;

	fd = mmap_fd(req, dev, io_req->offset);
	if(fd > 0){
		/* If mmapping is otherwise OK, but the first access to the
		 * page is a write, then it's not mapped in yet.  So we have
		 * to write the data to disk first, then we can map the disk
		 * page in and continue normally from there.
		 */
		if((rq_data_dir(req) == WRITE) && !is_remapped(req->buffer)){
			io_req->map_fd = dev->fd;
			io_req->map_offset = io_req->offset +
				dev->cow.data_offset;
			dev->write_maps++;
		}
		else return(prepare_mmap_request(dev, fd, io_req->offset, req,
						 io_req));
	}

	if(rq_data_dir(req) == READ)
		dev->nomap_reads++;
	else dev->nomap_writes++;

	io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
	io_req->offsets[0] = 0;
	io_req->offsets[1] = dev->cow.data_offset;
	io_req->buffer = req->buffer;
	io_req->sectorsize = 1 << 9;

	if(dev->cow.file != NULL)
		cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset,
			   dev->cow.bitmap_len);

	return(0);
}

/* Called with ubd_io_lock held */
static void do_ubd_request(request_queue_t *q)
{
	struct io_thread_req io_req;
	struct request *req;
	int err, n;

	if(thread_fd == -1){
		while((req = elv_next_request(q)) != NULL){
			err = prepare_request(req, &io_req);
			if(!err){
				do_io(&io_req);
				__ubd_finish(req, io_req.error);
			}
		}
	}
	else {
		if(do_ubd || (req = elv_next_request(q)) == NULL)
			return;
		err = prepare_request(req, &io_req);
		if(!err){
			do_ubd = ubd_handler;
			n = os_write_file(thread_fd, (char *) &io_req,
					 sizeof(io_req));
			if(n != sizeof(io_req))
				printk("write to io thread failed, "
				       "errno = %d\n", -n);
		}
	}
}

static int ubd_ioctl(struct inode * inode, struct file * file,
		     unsigned int cmd, unsigned long arg)
{
	struct hd_geometry __user *loc = (struct hd_geometry __user *) arg;
	struct ubd *dev = inode->i_bdev->bd_disk->private_data;
	struct hd_driveid ubd_id = {
		.cyls		= 0,
		.heads		= 128,
		.sectors	= 32,
	};

	switch (cmd) {
	        struct hd_geometry g;
		struct cdrom_volctrl volume;
	case HDIO_GETGEO:
		if(!loc) return(-EINVAL);
		g.heads = 128;
		g.sectors = 32;
		g.cylinders = dev->size / (128 * 32 * 512);
		g.start = get_start_sect(inode->i_bdev);
		return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);

	case HDIO_GET_IDENTITY:
		ubd_id.cyls = dev->size / (128 * 32 * 512);
		if(copy_to_user((char __user *) arg, (char *) &ubd_id,
				 sizeof(ubd_id)))
			return(-EFAULT);
		return(0);
		
	case CDROMVOLREAD:
		if(copy_from_user(&volume, (char __user *) arg, sizeof(volume)))
			return(-EFAULT);
		volume.channel0 = 255;
		volume.channel1 = 255;
		volume.channel2 = 255;
		volume.channel3 = 255;
		if(copy_to_user((char __user *) arg, &volume, sizeof(volume)))
			return(-EFAULT);
		return(0);
	}
	return(-EINVAL);
}

static int ubd_check_remapped(int fd, unsigned long address, int is_write,
			      __u64 offset)
{
	__u64 bitmap_offset;
	unsigned long new_bitmap[2];
	int i, err, n;

	/* If it's not a write access, we can't do anything about it */
	if(!is_write)
		return(0);

	/* We have a write */
	for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){
		struct ubd *dev = &ubd_dev[i];

		if((dev->fd != fd) && (dev->cow.fd != fd))
			continue;

		/* It's a write to a ubd device */

		if(!dev->openflags.w){
			/* It's a write access on a read-only device - probably
			 * shouldn't happen.  If the kernel is trying to change
			 * something with no intention of writing it back out,
			 * then this message will clue us in that this needs
			 * fixing
			 */
			printk("Write access to mapped page from readonly ubd "
			       "device %d\n", i);
			return(0);
		}

		/* It's a write to a writeable ubd device - it must be COWed
		 * because, otherwise, the page would have been mapped in
		 * writeable
		 */

		if(!dev->cow.file)
			panic("Write fault on writeable non-COW ubd device %d",
			      i);

		/* It should also be an access to the backing file since the
		 * COW pages should be mapped in read-write
		 */

		if(fd == dev->fd)
			panic("Write fault on a backing page of ubd "
			      "device %d\n", i);

		/* So, we do the write, copying the backing data to the COW
		 * file...
		 */

		err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
		if(err < 0)
			panic("Couldn't seek to %lld in COW file of ubd "
			      "device %d, err = %d",
			      offset + dev->cow.data_offset, i, -err);

		n = os_write_file(dev->fd, (void *) address, PAGE_SIZE);
		if(n != PAGE_SIZE)
			panic("Couldn't copy data to COW file of ubd "
			      "device %d, err = %d", i, -n);

		/* ... updating the COW bitmap... */

		cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset,
			      dev->cow.bitmap, dev->cow.bitmap_offset,
			      new_bitmap, dev->cow.bitmap_len);

		err = os_seek_file(dev->fd, bitmap_offset);
		if(err < 0)
			panic("Couldn't seek to %lld in COW file of ubd "
			      "device %d, err = %d", bitmap_offset, i, -err);

		n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap));
		if(n != sizeof(new_bitmap))
			panic("Couldn't update bitmap  of ubd device %d, "
			      "err = %d", i, -n);

		/* Maybe we can map the COW page in, and maybe we can't.  If
		 * it is a pre-V3 COW file, we can't, since the alignment will
		 * be wrong.  If it is a V3 or later COW file which has been
		 * moved to a system with a larger page size, then maybe we
		 * can't, depending on the exact location of the page.
		 */

		offset += dev->cow.data_offset;

		/* Remove the remapping, putting the original anonymous page
		 * back.  If the COW file can be mapped in, that is done.
		 * Otherwise, the COW page is read in.
		 */

		if(!physmem_remove_mapping((void *) address))
			panic("Address 0x%lx not remapped by ubd device %d",
			      address, i);
		if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
			physmem_subst_mapping((void *) address, dev->fd,
					      offset, 1);
		else {
			err = os_seek_file(dev->fd, offset);
			if(err < 0)
				panic("Couldn't seek to %lld in COW file of "
				      "ubd device %d, err = %d", offset, i,
				      -err);

			n = os_read_file(dev->fd, (void *) address, PAGE_SIZE);
			if(n != PAGE_SIZE)
				panic("Failed to read page from offset %llx of "
				      "COW file of ubd device %d, err = %d",
				      offset, i, -n);
		}

		return(1);
	}

	/* It's not a write on a ubd device */
	return(0);
}

static struct remapper ubd_remapper = {
	.list	= LIST_HEAD_INIT(ubd_remapper.list),
	.proc	= ubd_check_remapped,
};

static int ubd_remapper_setup(void)
{
	if(ubd_do_mmap)
		register_remapper(&ubd_remapper);

	return(0);
}

__initcall(ubd_remapper_setup);

static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
{
	struct uml_stat buf1, buf2;
	int err;

	if(from_cmdline == NULL) return(1);
	if(!strcmp(from_cmdline, from_cow)) return(1);

	err = os_stat_file(from_cmdline, &buf1);
	if(err < 0){
		printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
		return(1);
	}
	err = os_stat_file(from_cow, &buf2);
	if(err < 0){
		printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
		return(1);
	}
	if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
		return(1);

	printk("Backing file mismatch - \"%s\" requested,\n"
	       "\"%s\" specified in COW header of \"%s\"\n",
	       from_cmdline, from_cow, cow);
	return(0);
}

static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
{
	unsigned long modtime;
	long long actual;
	int err;

	err = os_file_modtime(file, &modtime);
	if(err < 0){
		printk("Failed to get modification time of backing file "
		       "\"%s\", err = %d\n", file, -err);
		return(err);
	}

	err = os_file_size(file, &actual);
	if(err < 0){
		printk("Failed to get size of backing file \"%s\", "
		       "err = %d\n", file, -err);
		return(err);
	}

  	if(actual != size){
		/*__u64 can be a long on AMD64 and with %lu GCC complains; so
		 * the typecast.*/
		printk("Size mismatch (%llu vs %llu) of COW header vs backing "
		       "file\n", (unsigned long long) size, actual);
		return(-EINVAL);
	}
	if(modtime != mtime){
		printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
		       "file\n", mtime, modtime);
		return(-EINVAL);
	}
	return(0);
}

int read_cow_bitmap(int fd, void *buf, int offset, int len)
{
	int err;

	err = os_seek_file(fd, offset);
	if(err < 0)
		return(err);

	err = os_read_file(fd, buf, len);
	if(err < 0)
		return(err);

	return(0);
}

int open_ubd_file(char *file, struct openflags *openflags,
		  char **backing_file_out, int *bitmap_offset_out,
		  unsigned long *bitmap_len_out, int *data_offset_out,
		  int *create_cow_out)
{
	time_t mtime;
	unsigned long long size;
	__u32 version, align;
	char *backing_file;
	int fd, err, sectorsize, same, mode = 0644;

	fd = os_open_file(file, *openflags, mode);
	if(fd < 0){
		if((fd == -ENOENT) && (create_cow_out != NULL))
			*create_cow_out = 1;
                if(!openflags->w ||
                   ((fd != -EROFS) && (fd != -EACCES))) return(fd);
		openflags->w = 0;
		fd = os_open_file(file, *openflags, mode);
		if(fd < 0)
			return(fd);
        }

	err = os_lock_file(fd, openflags->w);
	if(err < 0){
		printk("Failed to lock '%s', err = %d\n", file, -err);
		goto out_close;
	}

	if(backing_file_out == NULL) return(fd);

	err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
			      &size, &sectorsize, &align, bitmap_offset_out);
	if(err && (*backing_file_out != NULL)){
		printk("Failed to read COW header from COW file \"%s\", "
		       "errno = %d\n", file, -err);
		goto out_close;
	}
	if(err) return(fd);

	if(backing_file_out == NULL) return(fd);

	same = same_backing_files(*backing_file_out, backing_file, file);

	if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
		printk("Switching backing file to '%s'\n", *backing_file_out);
		err = write_cow_header(file, fd, *backing_file_out,
				       sectorsize, align, &size);
		if(err){
			printk("Switch failed, errno = %d\n", -err);
			return(err);
		}
	}
	else {
		*backing_file_out = backing_file;
		err = backing_file_mismatch(*backing_file_out, size, mtime);
		if(err) goto out_close;
	}

	cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
		  bitmap_len_out, data_offset_out);

        return(fd);
 out_close:
	os_close_file(fd);
	return(err);
}

int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
		    int sectorsize, int alignment, int *bitmap_offset_out,
		    unsigned long *bitmap_len_out, int *data_offset_out)
{
	int err, fd;

	flags.c = 1;
	fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
	if(fd < 0){
		err = fd;
		printk("Open of COW file '%s' failed, errno = %d\n", cow_file,
		       -err);
		goto out;
	}

	err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
			    bitmap_offset_out, bitmap_len_out,
			    data_offset_out);
	if(!err)
		return(fd);
	os_close_file(fd);
 out:
	return(err);
}

static int update_bitmap(struct io_thread_req *req)
{
	int n;

	if(req->cow_offset == -1)
		return(0);

	n = os_seek_file(req->fds[1], req->cow_offset);
	if(n < 0){
		printk("do_io - bitmap lseek failed : err = %d\n", -n);
		return(1);
	}

	n = os_write_file(req->fds[1], &req->bitmap_words,
		          sizeof(req->bitmap_words));
	if(n != sizeof(req->bitmap_words)){
		printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
		       req->fds[1]);
		return(1);
	}

	return(0);
}

void do_io(struct io_thread_req *req)
{
	char *buf;
	unsigned long len;
	int n, nsectors, start, end, bit;
	int err;
	__u64 off;

	if(req->op == UBD_MMAP){
		/* Touch the page to force the host to do any necessary IO to
		 * get it into memory
		 */
		n = *((volatile int *) req->buffer);
		req->error = update_bitmap(req);
		return;
	}

	nsectors = req->length / req->sectorsize;
	start = 0;
	do {
		bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
		end = start;
		while((end < nsectors) &&
		      (ubd_test_bit(end, (unsigned char *)
				    &req->sector_mask) == bit))
			end++;

		off = req->offset + req->offsets[bit] +
			start * req->sectorsize;
		len = (end - start) * req->sectorsize;
		buf = &req->buffer[start * req->sectorsize];

		err = os_seek_file(req->fds[bit], off);
		if(err < 0){
			printk("do_io - lseek failed : err = %d\n", -err);
			req->error = 1;
			return;
		}
		if(req->op == UBD_READ){
			n = 0;
			do {
				buf = &buf[n];
				len -= n;
				n = os_read_file(req->fds[bit], buf, len);
				if (n < 0) {
					printk("do_io - read failed, err = %d "
					       "fd = %d\n", -n, req->fds[bit]);
					req->error = 1;
					return;
				}
			} while((n < len) && (n != 0));
			if (n < len) memset(&buf[n], 0, len - n);
		}
		else {
			n = os_write_file(req->fds[bit], buf, len);
			if(n != len){
				printk("do_io - write failed err = %d "
				       "fd = %d\n", -n, req->fds[bit]);
				req->error = 1;
				return;
			}
		}

		start = end;
	} while(start < nsectors);

	req->error = update_bitmap(req);
}

/* Changed in start_io_thread, which is serialized by being called only
 * from ubd_init, which is an initcall.
 */
int kernel_fd = -1;

/* Only changed by the io thread */
int io_count = 0;

int io_thread(void *arg)
{
	struct io_thread_req req;
	int n;

	ignore_sigwinch_sig();
	while(1){
		n = os_read_file(kernel_fd, &req, sizeof(req));
		if(n != sizeof(req)){
			if(n < 0)
				printk("io_thread - read failed, fd = %d, "
				       "err = %d\n", kernel_fd, -n);
			else {
				printk("io_thread - short read, fd = %d, "
				       "length = %d\n", kernel_fd, n);
			}
			continue;
		}
		io_count++;
		do_io(&req);
		n = os_write_file(kernel_fd, &req, sizeof(req));
		if(n != sizeof(req))
			printk("io_thread - write failed, fd = %d, err = %d\n",
			       kernel_fd, -n);
	}
}

/*
 * Overrides for Emacs so that we follow Linus's tabbing style.
 * Emacs will notice this stuff at the end of the file and automatically
 * adjust the settings for this buffer only.  This must remain at the end
 * of the file.
 * ---------------------------------------------------------------------------
 * Local variables:
 * c-file-style: "linux"
 * End:
 */
