summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjdike <jdike>2003-02-06 18:37:38 +0000
committerjdike <jdike>2003-02-06 18:37:38 +0000
commitbc04c4f93dcf904ab404e617be9d16f09511bed3 (patch)
tree23776bfac2a84112ec2f1e0d1ed9fe02501b4014
parent2df74f657f45752ab734dcaf7f8abc31f2cd3e1d (diff)
downloaduml-history-bc04c4f93dcf904ab404e617be9d16f09511bed3.tar.gz
Applied a bunch of cleanups from James McMechan.
-rw-r--r--arch/um/drivers/ubd_kern.c176
1 files changed, 99 insertions, 77 deletions
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 382c062..6aa336e 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -75,7 +75,7 @@ static struct hd_struct ubd_part[MAX_MINOR] =
static request_queue_t *ubd_queue;
/* Protected by ubd_lock */
-static int fake_major = 0;
+static int fake_major = MAJOR_NR;
static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED;
@@ -132,8 +132,7 @@ struct ubd {
__u64 size;
struct openflags boot_openflags;
struct openflags openflags;
- devfs_handle_t real;
- devfs_handle_t fake;
+ devfs_handle_t devfs;
struct cow cow;
};
@@ -153,8 +152,7 @@ struct ubd {
.size = -1, \
.boot_openflags = OPEN_FLAGS, \
.openflags = OPEN_FLAGS, \
- .real = NULL, \
- .fake = NULL, \
+ .devfs = NULL, \
.cow = DEFAULT_COW, \
}
@@ -162,8 +160,10 @@ struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
static int ubd0_init(void)
{
- if(ubd_dev[0].file == NULL)
- ubd_dev[0].file = "root_fs";
+ struct ubd *dev = &ubd_dev[0];
+
+ if(dev->file == NULL)
+ dev->file = "root_fs";
return(0);
}
@@ -238,19 +238,39 @@ __uml_help(fake_ide_setup,
" Create ide0 entries that map onto ubd devices.\n\n"
);
+static int parse_unit(char **ptr)
+{
+ char *str = *ptr, *end;
+ int n = -1;
+
+ if(isdigit(*str)) {
+ n = simple_strtoul(str, &end, 0);
+ if(end == str)
+ return(-1);
+ *ptr = end;
+ }
+ else if (('a' <= *str) && (*str <= 'h')) {
+ n = *str - 'a';
+ str++;
+ *ptr = str;
+ }
+ return(n);
+}
+
static int ubd_setup_common(char *str, int *index_out)
{
struct openflags flags = global_openflags;
+ struct ubd *dev;
char *backing_file;
int n, err;
if(index_out) *index_out = -1;
- n = *str++;
+ n = *str;
if(n == '='){
- static int fake_major_allowed = 1;
char *end;
int major;
+ str++;
if(!strcmp(str, "sync")){
global_openflags.s = 1;
return(0);
@@ -264,14 +284,13 @@ static int ubd_setup_common(char *str, int *index_out)
err = 1;
spin_lock(&ubd_lock);
- if(!fake_major_allowed){
+ if(fake_major != MAJOR_NR){
printk(KERN_ERR "Can't assign a fake major twice\n");
goto out1;
}
fake_gendisk.major = major;
fake_major = major;
- fake_major_allowed = 0;
printk(KERN_INFO "Setting extra ubd major number to %d\n",
major);
@@ -281,25 +300,24 @@ static int ubd_setup_common(char *str, int *index_out)
return(err);
}
- if(n < '0'){
- printk(KERN_ERR "ubd_setup : index out of range\n"); }
-
- if((n >= '0') && (n <= '9')) n -= '0';
- else if((n >= 'a') && (n <= 'z')) n -= 'a';
- else {
- printk(KERN_ERR "ubd_setup : device syntax invalid\n");
+ n = parse_unit(&str);
+ if(n < 0){
+ printk(KERN_ERR "ubd_setup : couldn't parse unit number "
+ "'%s'\n", str);
return(1);
}
+
if(n >= MAX_DEV){
- printk(KERN_ERR "ubd_setup : index out of range "
- "(%d devices)\n", MAX_DEV);
+ printk(KERN_ERR "ubd_setup : index %d out of range "
+ "(%d devices)\n", n, MAX_DEV);
return(1);
}
err = 1;
spin_lock(&ubd_lock);
- if(ubd_dev[n].file != NULL){
+ dev = &ubd_dev[n];
+ if(dev->file != NULL){
printk(KERN_ERR "ubd_setup : device already configured\n");
goto out2;
}
@@ -325,11 +343,11 @@ static int ubd_setup_common(char *str, int *index_out)
*backing_file = '\0';
backing_file++;
}
- ubd_dev[n].file = str;
- if(ubd_is_dir(ubd_dev[n].file))
- ubd_dev[n].is_dir = 1;
- ubd_dev[n].cow.file = backing_file;
- ubd_dev[n].boot_openflags = flags;
+ dev->file = str;
+ if(ubd_is_dir(dev->file))
+ dev->is_dir = 1;
+ dev->cow.file = backing_file;
+ dev->boot_openflags = flags;
out2:
spin_unlock(&ubd_lock);
return(err);
@@ -443,7 +461,6 @@ __uml_exitcall(kill_io_thread);
/* Initialized in an initcall, and unchanged thereafter */
devfs_handle_t ubd_dir_handle;
-devfs_handle_t ubd_fake_dir_handle;
static int ubd_add(int n)
{
@@ -459,18 +476,10 @@ static int ubd_add(int n)
goto out;
sprintf(name, "%d", n);
- dev->real = devfs_register(ubd_dir_handle, name, DEVFS_FL_REMOVABLE,
- MAJOR_NR, n << UBD_SHIFT, S_IFBLK |
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
- &ubd_blops, NULL);
-
- if(fake_major != 0)
- dev->fake = devfs_register(ubd_fake_dir_handle, name,
- DEVFS_FL_REMOVABLE, fake_major,
- n << UBD_SHIFT,
- S_IFBLK | S_IRUSR | S_IWUSR |
- S_IRGRP | S_IWGRP, &ubd_blops,
- NULL);
+ dev->devfs = devfs_register(ubd_dir_handle, name, DEVFS_FL_REMOVABLE,
+ MAJOR_NR, n << UBD_SHIFT, S_IFBLK |
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+ &ubd_blops, NULL);
if(!strcmp(ubd_gendisk.major_name, "ubd"))
sprintf(dev_name, "%s%d", ubd_gendisk.major_name, n);
@@ -509,54 +518,63 @@ static int ubd_config(char *str)
return(err);
}
-static int ubd_get_config(char *dev, char *str, int size, char **error_out)
+static int ubd_get_config(char *name, char *str, int size, char **error_out)
{
- struct ubd *ubd;
+ struct ubd *dev;
char *end;
- int major, n = 0;
+ int n, len = 0;
- major = simple_strtoul(dev, &end, 0);
- if((*end != '\0') || (end == dev)){
- *error_out = "ubd_get_config : didn't parse major number";
+ n = simple_strtoul(name, &end, 0);
+ if((*end != '\0') || (end == name)){
+ *error_out = "ubd_get_config : didn't parse device number";
return(-1);
}
- if((major >= MAX_DEV) || (major < 0)){
- *error_out = "ubd_get_config : major number out of range";
+ if((n >= MAX_DEV) || (n < 0)){
+ *error_out = "ubd_get_config : device number out of range";
return(-1);
}
- ubd = &ubd_dev[major];
+ dev = &ubd_dev[n];
spin_lock(&ubd_lock);
- if(ubd->file == NULL){
- CONFIG_CHUNK(str, size, n, "", 1);
+ if(dev->file == NULL){
+ CONFIG_CHUNK(str, size, len, "", 1);
goto out;
}
- CONFIG_CHUNK(str, size, n, ubd->file, 0);
+ CONFIG_CHUNK(str, size, len, dev->file, 0);
- if(ubd->cow.file != NULL){
- CONFIG_CHUNK(str, size, n, ",", 0);
- CONFIG_CHUNK(str, size, n, ubd->cow.file, 1);
+ if(dev->cow.file != NULL){
+ CONFIG_CHUNK(str, size, len, ",", 0);
+ CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
}
- else CONFIG_CHUNK(str, size, n, "", 1);
+ else CONFIG_CHUNK(str, size, len, "", 1);
out:
spin_unlock(&ubd_lock);
- return(n);
+ return(len);
}
static int ubd_remove(char *str)
{
struct ubd *dev;
- int n, err;
+ int n, err = -ENODEV;
+
+ if(isdigit(*str)){
+ char *end;
+ n = simple_strtoul(str, &end, 0);
+ if ((*end != '\0') || (end == str))
+ return(err);
+ }
+ else if (('a' <= *str) && (*str <= 'h'))
+ n = *str - 'a';
+ else
+ return(err); /* it should be a number 0-7/a-h */
+
+ if((n < 0) || (n >= MAX_DEV))
+ return(err);
- if(!isdigit(*str))
- return(-1);
- n = *str - '0';
- if(n >= MAX_DEV)
- return(-1);
dev = &ubd_dev[n];
spin_lock(&ubd_lock);
@@ -566,10 +584,9 @@ static int ubd_remove(char *str)
err = -1;
if(dev->count > 0)
goto out;
- if(dev->real != NULL)
- devfs_unregister(dev->real);
- if(dev->fake != NULL)
- devfs_unregister(dev->fake);
+ if(dev->devfs != NULL)
+ devfs_unregister(dev->devfs);
+
*dev = ((struct ubd) DEFAULT_UBD);
err = 0;
out:
@@ -617,16 +634,22 @@ int ubd_init(void)
INIT_ELV(ubd_queue, &ubd_queue->elevator);
add_gendisk(&ubd_gendisk);
- if (fake_major != 0){
- char name[sizeof("ubd_nnn\0")];
-
- snprintf(name, sizeof(name), "ubd_%d", fake_major);
- ubd_fake_dir_handle = devfs_mk_dir(NULL, name, NULL);
- if(devfs_register_blkdev(fake_major, "ubd", &ubd_blops)) {
- printk(KERN_ERR "ubd: unable to get major %d\n",
- fake_major);
- return -1;
+ if (fake_major != MAJOR_NR){
+ /* major number 0 is used to auto select */
+ err = devfs_register_blkdev(fake_major, "fake", &ubd_blops);
+ if(fake_major == 0){
+ /* auto device number case */
+ fake_major = err;
+ if(err == 0)
+ return(-ENODEV);
+ }
+ else if (err){
+ /* not auto so normal error */
+ printk(KERN_ERR "ubd: error %d getting major %d\n",
+ err, fake_major);
+ return(-ENODEV);
}
+
blk_dev[fake_major].queue = ubd_get_queue;
read_ahead[fake_major] = 8; /* 8 sector (4kB) read-ahead */
blksize_size[fake_major] = blk_sizes;
@@ -673,7 +696,7 @@ static void ubd_close(struct ubd *dev)
static int ubd_open_dev(struct ubd *dev)
{
struct openflags flags;
- int err, n, create_cow, *create_ptr;
+ int err, create_cow, *create_ptr;
create_cow = 0;
create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
@@ -682,7 +705,6 @@ static int ubd_open_dev(struct ubd *dev)
&dev->cow.data_offset, create_ptr);
if((dev->fd == -ENOENT) && create_cow){
- n = dev - ubd_dev;
dev->fd = create_cow_file(dev->file, dev->cow.file,
dev->openflags, 1 << 9,
&dev->cow.bitmap_offset,