summaryrefslogtreecommitdiff
path: root/arch/um/drivers/ubd_kern.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/drivers/ubd_kern.c')
-rw-r--r--arch/um/drivers/ubd_kern.c81
1 files changed, 44 insertions, 37 deletions
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 73f9652b2ee9..101efd26d467 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -117,6 +117,7 @@ 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);
+static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
#define MAX_DEV (8)
@@ -125,6 +126,7 @@ static struct block_device_operations ubd_blops = {
.open = ubd_open,
.release = ubd_release,
.ioctl = ubd_ioctl,
+ .getgeo = ubd_getgeo,
};
/* Protected by the queue_lock */
@@ -1058,10 +1060,19 @@ static void do_ubd_request(request_queue_t *q)
}
}
+static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+ struct ubd *dev = bdev->bd_disk->private_data;
+
+ geo->heads = 128;
+ geo->sectors = 32;
+ geo->cylinders = dev->size / (128 * 32 * 512);
+ return 0;
+}
+
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,
@@ -1070,16 +1081,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
};
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,
@@ -1101,31 +1103,33 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
return(-EINVAL);
}
-static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
+static int path_requires_switch(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);
+ if(from_cmdline == NULL)
+ return 0;
+ if(!strcmp(from_cmdline, from_cow))
+ return 0;
err = os_stat_file(from_cmdline, &buf1);
if(err < 0){
printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
- return(1);
+ return 0;
}
err = os_stat_file(from_cow, &buf2);
if(err < 0){
printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
- return(1);
+ return 1;
}
if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
- return(1);
+ return 0;
printk("Backing file mismatch - \"%s\" requested,\n"
"\"%s\" specified in COW header of \"%s\"\n",
from_cmdline, from_cow, cow);
- return(0);
+ return 1;
}
static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
@@ -1187,18 +1191,19 @@ int open_ubd_file(char *file, struct openflags *openflags,
unsigned long long size;
__u32 version, align;
char *backing_file;
- int fd, err, sectorsize, same, mode = 0644;
+ int fd, err, sectorsize, asked_switch, mode = 0644;
fd = os_open_file(file, *openflags, mode);
- if(fd < 0){
- if((fd == -ENOENT) && (create_cow_out != NULL))
+ if (fd < 0) {
+ if ((fd == -ENOENT) && (create_cow_out != NULL))
*create_cow_out = 1;
- if(!openflags->w ||
- ((fd != -EROFS) && (fd != -EACCES))) return(fd);
+ if (!openflags->w ||
+ ((fd != -EROFS) && (fd != -EACCES)))
+ return fd;
openflags->w = 0;
fd = os_open_file(file, *openflags, mode);
- if(fd < 0)
- return(fd);
+ if (fd < 0)
+ return fd;
}
err = os_lock_file(fd, openflags->w);
@@ -1207,7 +1212,9 @@ int open_ubd_file(char *file, struct openflags *openflags,
goto out_close;
}
- if(backing_file_out == NULL) return(fd);
+ /* Succesful return case! */
+ if(backing_file_out == NULL)
+ return(fd);
err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
&size, &sectorsize, &align, bitmap_offset_out);
@@ -1216,34 +1223,34 @@ int open_ubd_file(char *file, struct openflags *openflags,
"errno = %d\n", file, -err);
goto out_close;
}
- if(err) return(fd);
-
- if(backing_file_out == NULL) return(fd);
+ if(err)
+ return(fd);
- same = same_backing_files(*backing_file_out, backing_file, file);
+ asked_switch = path_requires_switch(*backing_file_out, backing_file, file);
- if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
+ /* Allow switching only if no mismatch. */
+ if (asked_switch && !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){
+ if (err) {
printk("Switch failed, errno = %d\n", -err);
- return(err);
+ goto out_close;
}
- }
- else {
+ } else {
*backing_file_out = backing_file;
err = backing_file_mismatch(*backing_file_out, size, mtime);
- if(err) goto out_close;
+ if (err)
+ goto out_close;
}
cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
bitmap_len_out, data_offset_out);
- return(fd);
+ return fd;
out_close:
os_close_file(fd);
- return(err);
+ return err;
}
int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,