diff options
author | jdike <jdike> | 2003-02-06 18:37:38 +0000 |
---|---|---|
committer | jdike <jdike> | 2003-02-06 18:37:38 +0000 |
commit | bc04c4f93dcf904ab404e617be9d16f09511bed3 (patch) | |
tree | 23776bfac2a84112ec2f1e0d1ed9fe02501b4014 | |
parent | 2df74f657f45752ab734dcaf7f8abc31f2cd3e1d (diff) | |
download | uml-history-bc04c4f93dcf904ab404e617be9d16f09511bed3.tar.gz |
Applied a bunch of cleanups from James McMechan.
-rw-r--r-- | arch/um/drivers/ubd_kern.c | 176 |
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, |