summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjdike <jdike>2003-08-07 18:55:22 +0000
committerjdike <jdike>2003-08-07 18:55:22 +0000
commit3ba5545d81d0399c1a374607849230ca4d58b95b (patch)
treef4ee3a92461937a2a6fe3f7bf6b315da266bed47
parentc49a00ae94432d7b205051b4a699d0a47afc2899 (diff)
downloaduml-history-3ba5545d81d0399c1a374607849230ca4d58b95b.tar.gz
Added the start of a standalone COW driver.
Cleaned up the code a bit to make it more separable.
-rw-r--r--arch/um/config_block.in6
-rw-r--r--arch/um/drivers/Makefile6
-rw-r--r--arch/um/drivers/cow.h12
-rw-r--r--arch/um/drivers/cow_user.c13
-rw-r--r--arch/um/drivers/ubd_user.c4
-rw-r--r--include/linux/blk.h9
6 files changed, 41 insertions, 9 deletions
diff --git a/arch/um/config_block.in b/arch/um/config_block.in
index 419bb71..18122a4 100644
--- a/arch/um/config_block.in
+++ b/arch/um/config_block.in
@@ -3,6 +3,12 @@ comment 'Block Devices'
bool 'Virtual block device' CONFIG_BLK_DEV_UBD
dep_bool ' Always do synchronous disk IO for UBD' CONFIG_BLK_DEV_UBD_SYNC $CONFIG_BLK_DEV_UBD
+bool 'COW device' CONFIG_COW
+
+if [ "$CONFIG_BLK_DEV_UBD" = "y" -o "$CONFIG_COW" = "y" ] ; then
+ define_bool CONFIG_COW_COMMON y
+fi
+
tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index 06f8a92..4b4b3aa 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
+# Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com)
# Licensed under the GPL
#
@@ -18,7 +18,7 @@ pcap-objs := pcap_kern.o pcap_user.o -lpcap -L/usr/lib
net-objs := net_kern.o net_user.o
mconsole-objs := mconsole_kern.o mconsole_user.o
hostaudio-objs := hostaudio_kern.o hostaudio_user.o
-ubd-objs := ubd_kern.o ubd_user.o cow_user.o
+ubd-objs := ubd_kern.o ubd_user.o
port-objs := port_kern.o port_user.o
harddog-objs := harddog_kern.o harddog_user.o
@@ -43,6 +43,8 @@ obj-$(CONFIG_PTY_CHAN) += pty.o
obj-$(CONFIG_TTY_CHAN) += tty.o
obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
obj-$(CONFIG_UML_WATCHDOG) += harddog.o
+obj-$(CONFIG_COW) += cow_kern.o
+obj-$(CONFIG_COW_COMMON) += cow_user.o
CFLAGS_pcap_user.o = -I/usr/include/pcap
diff --git a/arch/um/drivers/cow.h b/arch/um/drivers/cow.h
index e354d28..662ac5c 100644
--- a/arch/um/drivers/cow.h
+++ b/arch/um/drivers/cow.h
@@ -16,11 +16,17 @@
extern int init_cow_file(int fd, char *cow_file, char *backing_file,
int sectorsize, int *bitmap_offset_out,
unsigned long *bitmap_len_out, int *data_offset_out);
-extern int read_cow_header(int fd, __u32 *magic_out, char **backing_file_out,
- time_t *mtime_out, __u64 *size_out,
- int *sectorsize_out, int *bitmap_offset_out);
+
+extern int file_reader(__u64 offset, char *buf, int len, void *arg);
+extern int read_cow_header(int (*reader)(__u64, char *, int, void *),
+ void *arg, __u32 *magic_out,
+ char **backing_file_out, time_t *mtime_out,
+ __u64 *size_out, int *sectorsize_out,
+ int *bitmap_offset_out);
+
extern int write_cow_header(char *cow_file, int fd, char *backing_file,
int sectorsize, long long *size);
+
extern void cow_sizes(__u64 size, int sectorsize, int bitmap_offset,
unsigned long *bitmap_len_out, int *data_offset_out);
diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c
index d3ed767..675a716 100644
--- a/arch/um/drivers/cow_user.c
+++ b/arch/um/drivers/cow_user.c
@@ -165,7 +165,15 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
return(err);
}
-int read_cow_header(int fd, __u32 *magic_out, char **backing_file_out,
+int file_reader(__u64 offset, char *buf, int len, void *arg)
+{
+ int fd = *((int *) arg);
+
+ return(pread(fd, buf, len, offset));
+}
+
+int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
+ __u32 *magic_out, char **backing_file_out,
time_t *mtime_out, __u64 *size_out,
int *sectorsize_out, int *bitmap_offset_out)
{
@@ -180,7 +188,7 @@ int read_cow_header(int fd, __u32 *magic_out, char **backing_file_out,
return(-ENOMEM);
}
err = -EINVAL;
- n = read(fd, header, sizeof(*header));
+ n = (*reader)(0, (char *) header, sizeof(*header), arg);
if(n < offsetof(typeof(header->v1), backing_file)){
cow_printf("read_cow_header - short header\n");
goto out;
@@ -193,6 +201,7 @@ int read_cow_header(int fd, __u32 *magic_out, char **backing_file_out,
else if(magic == ntohl(COW_MAGIC)){
version = ntohl(header->v1.version);
}
+ /* No error printed because the non-COW case comes through here */
else goto out;
*magic_out = COW_MAGIC;
diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
index 81b8437..ba7d5b5 100644
--- a/arch/um/drivers/ubd_user.c
+++ b/arch/um/drivers/ubd_user.c
@@ -126,8 +126,8 @@ int open_ubd_file(char *file, struct openflags *openflags,
if(backing_file_out == NULL) return(fd);
- err = read_cow_header(fd, &magic, &backing_file, &mtime, &size,
- &sectorsize, bitmap_offset_out);
+ err = read_cow_header(file_reader, &fd, &magic, &backing_file, &mtime,
+ &size, &sectorsize, bitmap_offset_out);
if(err && (*backing_file_out != NULL)){
printk("Failed to read COW header from COW file \"%s\", "
"errno = %d\n", file, err);
diff --git a/include/linux/blk.h b/include/linux/blk.h
index f90d557..f16bcb4 100644
--- a/include/linux/blk.h
+++ b/include/linux/blk.h
@@ -329,6 +329,15 @@ static void floppy_off(unsigned int nr);
#define DEVICE_ON(device)
#define DEVICE_OFF(device)
+#elif (MAJOR_NR == COW_MAJOR)
+
+#define DEVICE_NAME "COW device"
+#define DEVICE_INTR do_cow
+#define DEVICE_REQUEST do_cow_request
+#define DEVICE_NR(device) (MINOR(device) >> COW_SHIFT)
+#define DEVICE_ON(device)
+#define DEVICE_OFF(device)
+
#endif /* MAJOR_NR == whatever */
/* provide DEVICE_xxx defaults, if not explicitly defined