um: fix ubd cow size
Richard Weinberger [Wed, 2 Nov 2011 12:17:27 +0000 (13:17 +0100)]
commit 8535639810e578960233ad39def3ac2157b0c3ec upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

arch/um/drivers/ubd_kern.c

index 620f5b7..0491e40 100644 (file)
@@ -513,8 +513,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);
 }