Commit 6c29256c authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds

[PATCH] uml: allow ubd devices to be shared in a cluster

This adds a 'c' option to the ubd switch which turns off host file locking so
that the device can be shared, as with a cluster.  There's also some
whitespace cleanup while I was in this file.
Signed-off-by: default avatarJeff Dike <jdike@addtoit.com>
Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent cf9165a5
/* /*
* Copyright (C) 2000 Jeff Dike (jdike@karaya.com) * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
...@@ -71,7 +71,7 @@ struct io_thread_req { ...@@ -71,7 +71,7 @@ struct io_thread_req {
int error; int error;
}; };
extern int open_ubd_file(char *file, struct openflags *openflags, extern int open_ubd_file(char *file, struct openflags *openflags, int shared,
char **backing_file_out, int *bitmap_offset_out, char **backing_file_out, int *bitmap_offset_out,
unsigned long *bitmap_len_out, int *data_offset_out, unsigned long *bitmap_len_out, int *data_offset_out,
int *create_cow_out); int *create_cow_out);
...@@ -137,7 +137,7 @@ static int fake_major = MAJOR_NR; ...@@ -137,7 +137,7 @@ static int fake_major = MAJOR_NR;
static struct gendisk *ubd_gendisk[MAX_DEV]; static struct gendisk *ubd_gendisk[MAX_DEV];
static struct gendisk *fake_gendisk[MAX_DEV]; static struct gendisk *fake_gendisk[MAX_DEV];
#ifdef CONFIG_BLK_DEV_UBD_SYNC #ifdef CONFIG_BLK_DEV_UBD_SYNC
#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \ #define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
.cl = 1 }) .cl = 1 })
...@@ -168,6 +168,7 @@ struct ubd { ...@@ -168,6 +168,7 @@ struct ubd {
__u64 size; __u64 size;
struct openflags boot_openflags; struct openflags boot_openflags;
struct openflags openflags; struct openflags openflags;
int shared;
int no_cow; int no_cow;
struct cow cow; struct cow cow;
struct platform_device pdev; struct platform_device pdev;
...@@ -189,6 +190,7 @@ struct ubd { ...@@ -189,6 +190,7 @@ struct ubd {
.boot_openflags = OPEN_FLAGS, \ .boot_openflags = OPEN_FLAGS, \
.openflags = OPEN_FLAGS, \ .openflags = OPEN_FLAGS, \
.no_cow = 0, \ .no_cow = 0, \
.shared = 0, \
.cow = DEFAULT_COW, \ .cow = DEFAULT_COW, \
} }
...@@ -305,7 +307,7 @@ static int ubd_setup_common(char *str, int *index_out) ...@@ -305,7 +307,7 @@ static int ubd_setup_common(char *str, int *index_out)
} }
major = simple_strtoul(str, &end, 0); major = simple_strtoul(str, &end, 0);
if((*end != '\0') || (end == str)){ if((*end != '\0') || (end == str)){
printk(KERN_ERR printk(KERN_ERR
"ubd_setup : didn't parse major number\n"); "ubd_setup : didn't parse major number\n");
return(1); return(1);
} }
...@@ -316,7 +318,7 @@ static int ubd_setup_common(char *str, int *index_out) ...@@ -316,7 +318,7 @@ static int ubd_setup_common(char *str, int *index_out)
printk(KERN_ERR "Can't assign a fake major twice\n"); printk(KERN_ERR "Can't assign a fake major twice\n");
goto out1; goto out1;
} }
fake_major = major; fake_major = major;
printk(KERN_INFO "Setting extra ubd major number to %d\n", printk(KERN_INFO "Setting extra ubd major number to %d\n",
...@@ -351,7 +353,7 @@ static int ubd_setup_common(char *str, int *index_out) ...@@ -351,7 +353,7 @@ static int ubd_setup_common(char *str, int *index_out)
if (index_out) if (index_out)
*index_out = n; *index_out = n;
for (i = 0; i < 4; i++) { for (i = 0; i < sizeof("rscd="); i++) {
switch (*str) { switch (*str) {
case 'r': case 'r':
flags.w = 0; flags.w = 0;
...@@ -362,11 +364,14 @@ static int ubd_setup_common(char *str, int *index_out) ...@@ -362,11 +364,14 @@ static int ubd_setup_common(char *str, int *index_out)
case 'd': case 'd':
dev->no_cow = 1; dev->no_cow = 1;
break; break;
case 'c':
dev->shared = 1;
break;
case '=': case '=':
str++; str++;
goto break_loop; goto break_loop;
default: default:
printk(KERN_ERR "ubd_setup : Expected '=' or flag letter (r,s or d)\n"); printk(KERN_ERR "ubd_setup : Expected '=' or flag letter (r, s, c, or d)\n");
goto out; goto out;
} }
str++; str++;
...@@ -515,7 +520,7 @@ static void ubd_handler(void) ...@@ -515,7 +520,7 @@ static void ubd_handler(void)
spin_unlock(&ubd_io_lock); spin_unlock(&ubd_io_lock);
return; return;
} }
ubd_finish(rq, req.error); ubd_finish(rq, req.error);
reactivate_fd(thread_fd, UBD_IRQ); reactivate_fd(thread_fd, UBD_IRQ);
do_ubd_request(ubd_queue); do_ubd_request(ubd_queue);
...@@ -532,7 +537,7 @@ static int io_pid = -1; ...@@ -532,7 +537,7 @@ static int io_pid = -1;
void kill_io_thread(void) void kill_io_thread(void)
{ {
if(io_pid != -1) if(io_pid != -1)
os_kill_process(io_pid, 1); os_kill_process(io_pid, 1);
} }
...@@ -567,14 +572,15 @@ static int ubd_open_dev(struct ubd *dev) ...@@ -567,14 +572,15 @@ static int ubd_open_dev(struct ubd *dev)
create_cow = 0; create_cow = 0;
create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL; create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
back_ptr = dev->no_cow ? NULL : &dev->cow.file; back_ptr = dev->no_cow ? NULL : &dev->cow.file;
dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr, dev->fd = open_ubd_file(dev->file, &dev->openflags, dev->shared,
&dev->cow.bitmap_offset, &dev->cow.bitmap_len, back_ptr, &dev->cow.bitmap_offset,
&dev->cow.data_offset, create_ptr); &dev->cow.bitmap_len, &dev->cow.data_offset,
create_ptr);
if((dev->fd == -ENOENT) && create_cow){ if((dev->fd == -ENOENT) && create_cow){
dev->fd = create_cow_file(dev->file, dev->cow.file, dev->fd = create_cow_file(dev->file, dev->cow.file,
dev->openflags, 1 << 9, PAGE_SIZE, dev->openflags, 1 << 9, PAGE_SIZE,
&dev->cow.bitmap_offset, &dev->cow.bitmap_offset,
&dev->cow.bitmap_len, &dev->cow.bitmap_len,
&dev->cow.data_offset); &dev->cow.data_offset);
if(dev->fd >= 0){ if(dev->fd >= 0){
...@@ -598,16 +604,16 @@ static int ubd_open_dev(struct ubd *dev) ...@@ -598,16 +604,16 @@ static int ubd_open_dev(struct ubd *dev)
} }
flush_tlb_kernel_vm(); flush_tlb_kernel_vm();
err = read_cow_bitmap(dev->fd, dev->cow.bitmap, err = read_cow_bitmap(dev->fd, dev->cow.bitmap,
dev->cow.bitmap_offset, dev->cow.bitmap_offset,
dev->cow.bitmap_len); dev->cow.bitmap_len);
if(err < 0) if(err < 0)
goto error; goto error;
flags = dev->openflags; flags = dev->openflags;
flags.w = 0; flags.w = 0;
err = open_ubd_file(dev->cow.file, &flags, NULL, NULL, NULL, err = open_ubd_file(dev->cow.file, &flags, dev->shared, NULL,
NULL, NULL); NULL, NULL, NULL, NULL);
if(err < 0) goto error; if(err < 0) goto error;
dev->cow.fd = err; dev->cow.fd = err;
} }
...@@ -685,11 +691,11 @@ static int ubd_add(int n) ...@@ -685,11 +691,11 @@ static int ubd_add(int n)
dev->size = ROUND_BLOCK(dev->size); dev->size = ROUND_BLOCK(dev->size);
err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]); err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
if(err) if(err)
goto out_close; goto out_close;
if(fake_major != MAJOR_NR) if(fake_major != MAJOR_NR)
ubd_new_disk(fake_major, dev->size, n, ubd_new_disk(fake_major, dev->size, n,
&fake_gendisk[n]); &fake_gendisk[n]);
/* perhaps this should also be under the "if (fake_major)" above */ /* perhaps this should also be under the "if (fake_major)" above */
...@@ -854,7 +860,7 @@ int ubd_init(void) ...@@ -854,7 +860,7 @@ int ubd_init(void)
return -1; return -1;
} }
platform_driver_register(&ubd_driver); platform_driver_register(&ubd_driver);
for (i = 0; i < MAX_DEV; i++) for (i = 0; i < MAX_DEV; i++)
ubd_add(i); ubd_add(i);
return 0; return 0;
} }
...@@ -872,16 +878,16 @@ int ubd_driver_init(void){ ...@@ -872,16 +878,16 @@ int ubd_driver_init(void){
* enough. So use anyway the io thread. */ * enough. So use anyway the io thread. */
} }
stack = alloc_stack(0, 0); stack = alloc_stack(0, 0);
io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *), io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
&thread_fd); &thread_fd);
if(io_pid < 0){ if(io_pid < 0){
printk(KERN_ERR printk(KERN_ERR
"ubd : Failed to start I/O thread (errno = %d) - " "ubd : Failed to start I/O thread (errno = %d) - "
"falling back to synchronous I/O\n", -io_pid); "falling back to synchronous I/O\n", -io_pid);
io_pid = -1; io_pid = -1;
return(0); return(0);
} }
err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
SA_INTERRUPT, "ubd", ubd_dev); SA_INTERRUPT, "ubd", ubd_dev);
if(err != 0) if(err != 0)
printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err); printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
...@@ -978,7 +984,7 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, ...@@ -978,7 +984,7 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
if(req->op == UBD_READ) { if(req->op == UBD_READ) {
for(i = 0; i < req->length >> 9; i++){ for(i = 0; i < req->length >> 9; i++){
if(ubd_test_bit(sector + i, (unsigned char *) bitmap)) if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
ubd_set_bit(i, (unsigned char *) ubd_set_bit(i, (unsigned char *)
&req->sector_mask); &req->sector_mask);
} }
} }
...@@ -999,7 +1005,7 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req) ...@@ -999,7 +1005,7 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
/* This should be impossible now */ /* This should be impossible now */
if((rq_data_dir(req) == WRITE) && !dev->openflags.w){ if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
printk("Write attempted on readonly ubd device %s\n", printk("Write attempted on readonly ubd device %s\n",
disk->disk_name); disk->disk_name);
end_request(req, 0); end_request(req, 0);
return(1); return(1);
...@@ -1182,7 +1188,7 @@ int read_cow_bitmap(int fd, void *buf, int offset, int len) ...@@ -1182,7 +1188,7 @@ int read_cow_bitmap(int fd, void *buf, int offset, int len)
return(0); return(0);
} }
int open_ubd_file(char *file, struct openflags *openflags, int open_ubd_file(char *file, struct openflags *openflags, int shared,
char **backing_file_out, int *bitmap_offset_out, char **backing_file_out, int *bitmap_offset_out,
unsigned long *bitmap_len_out, int *data_offset_out, unsigned long *bitmap_len_out, int *data_offset_out,
int *create_cow_out) int *create_cow_out)
...@@ -1206,10 +1212,14 @@ int open_ubd_file(char *file, struct openflags *openflags, ...@@ -1206,10 +1212,14 @@ int open_ubd_file(char *file, struct openflags *openflags,
return fd; return fd;
} }
err = os_lock_file(fd, openflags->w); if(shared)
if(err < 0){ printk("Not locking \"%s\" on the host\n", file);
printk("Failed to lock '%s', err = %d\n", file, -err); else {
goto out_close; err = os_lock_file(fd, openflags->w);
if(err < 0){
printk("Failed to lock '%s', err = %d\n", file, -err);
goto out_close;
}
} }
/* Succesful return case! */ /* Succesful return case! */
...@@ -1260,7 +1270,7 @@ int create_cow_file(char *cow_file, char *backing_file, struct openflags flags, ...@@ -1260,7 +1270,7 @@ int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
int err, fd; int err, fd;
flags.c = 1; flags.c = 1;
fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL); fd = open_ubd_file(cow_file, &flags, 0, NULL, NULL, NULL, NULL, NULL);
if(fd < 0){ if(fd < 0){
err = fd; err = fd;
printk("Open of COW file '%s' failed, errno = %d\n", cow_file, printk("Open of COW file '%s' failed, errno = %d\n", cow_file,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment