summaryrefslogtreecommitdiffstats
path: root/arch/um/drivers
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2011-11-02 13:17:27 +0100
committerRichard Weinberger <richard@nod.at>2011-11-02 14:15:42 +0100
commit8535639810e578960233ad39def3ac2157b0c3ec (patch)
tree519778b447082e802b42c2d6720475ca1cc7c96e /arch/um/drivers
parent0d65ede0a605d6252acc5c8a9c536c4cd0211f3c (diff)
downloadop-kernel-dev-8535639810e578960233ad39def3ac2157b0c3ec.zip
op-kernel-dev-8535639810e578960233ad39def3ac2157b0c3ec.tar.gz
um: fix ubd cow size
ubd_file_size() cannot use ubd_dev->cow.file because at this time ubd_dev->cow.file is not initialized. Therefore, ubd_file_size() will always report a wrong disk size when COW files are used. Reading from /dev/ubd* would crash the kernel. We have to read the correct disk size from the COW file's backing file. Signed-off-by: Richard Weinberger <richard@nod.at> CC: stable@kernel.org
Diffstat (limited to 'arch/um/drivers')
-rw-r--r--arch/um/drivers/ubd_kern.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index b3c8545..944453a 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -511,8 +511,37 @@ __uml_exitcall(kill_io_thread);
static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
{
char *file;
+ int fd;
+ int err;
+
+ __u32 version;
+ __u32 align;
+ char *backing_file;
+ time_t mtime;
+ unsigned long long size;
+ int sector_size;
+ int bitmap_offset;
+
+ if (ubd_dev->file && ubd_dev->cow.file) {
+ file = ubd_dev->cow.file;
+
+ goto out;
+ }
- file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file;
+ fd = os_open_file(ubd_dev->file, global_openflags, 0);
+ if (fd < 0)
+ return fd;
+
+ err = read_cow_header(file_reader, &fd, &version, &backing_file, \
+ &mtime, &size, &sector_size, &align, &bitmap_offset);
+ os_close_file(fd);
+
+ if(err == -EINVAL)
+ file = ubd_dev->file;
+ else
+ file = backing_file;
+
+out:
return os_file_size(file, size_out);
}
OpenPOWER on IntegriCloud