diff options
author | Jeff Dike <jdike@addtoit.com> | 2007-05-06 17:51:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-07 15:13:00 -0400 |
commit | b47d2debf229469c78af4145ee7ad35a0f21b67f (patch) | |
tree | 6bca064260d56701b799282b40586277278996b4 /arch | |
parent | 1d94cda04eb82feb87c932ac3d4aef1e9dc78a43 (diff) |
uml: handle block device hotplug errors
If a disk fails to open, i.e. its host file doesn't exist, it won't be
removable because the hot-unplug code checks the existence of its gendisk.
This won't exist because it is only allocated for successfully opened disks.
Thus, a typo on the command line can result in a unusable and unfixable disk.
This is fixed by freeing the gendisk if it's there, but not letting that
affect the removal.
Signed-off-by: Jeff Dike <jdike@linux.intel.com>
Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/um/drivers/ubd_kern.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 8bd9204ac1ab..53c36d1770c5 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
@@ -788,14 +788,12 @@ static int ubd_id(char **str, int *start_out, int *end_out) | |||
788 | 788 | ||
789 | static int ubd_remove(int n, char **error_out) | 789 | static int ubd_remove(int n, char **error_out) |
790 | { | 790 | { |
791 | struct gendisk *disk; | ||
791 | struct ubd *ubd_dev; | 792 | struct ubd *ubd_dev; |
792 | int err = -ENODEV; | 793 | int err = -ENODEV; |
793 | 794 | ||
794 | mutex_lock(&ubd_lock); | 795 | mutex_lock(&ubd_lock); |
795 | 796 | ||
796 | if(ubd_gendisk[n] == NULL) | ||
797 | goto out; | ||
798 | |||
799 | ubd_dev = &ubd_devs[n]; | 797 | ubd_dev = &ubd_devs[n]; |
800 | 798 | ||
801 | if(ubd_dev->file == NULL) | 799 | if(ubd_dev->file == NULL) |
@@ -806,9 +804,12 @@ static int ubd_remove(int n, char **error_out) | |||
806 | if(ubd_dev->count > 0) | 804 | if(ubd_dev->count > 0) |
807 | goto out; | 805 | goto out; |
808 | 806 | ||
809 | del_gendisk(ubd_gendisk[n]); | 807 | disk = ubd_gendisk[n]; |
810 | put_disk(ubd_gendisk[n]); | 808 | ubd_gendisk[n] = NULL; |
811 | ubd_gendisk[n] = NULL; | 809 | if(disk != NULL){ |
810 | del_gendisk(disk); | ||
811 | put_disk(disk); | ||
812 | } | ||
812 | 813 | ||
813 | if(fake_gendisk[n] != NULL){ | 814 | if(fake_gendisk[n] != NULL){ |
814 | del_gendisk(fake_gendisk[n]); | 815 | del_gendisk(fake_gendisk[n]); |