diff options
| -rw-r--r-- | block/genhd.c | 31 | ||||
| -rw-r--r-- | drivers/base/map.c | 21 | ||||
| -rw-r--r-- | fs/char_dev.c | 17 | ||||
| -rw-r--r-- | include/linux/kobj_map.h | 4 |
4 files changed, 38 insertions, 35 deletions
diff --git a/block/genhd.c b/block/genhd.c index db57546a709d..64510fd88621 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
| @@ -15,12 +15,13 @@ | |||
| 15 | #include <linux/kmod.h> | 15 | #include <linux/kmod.h> |
| 16 | #include <linux/kobj_map.h> | 16 | #include <linux/kobj_map.h> |
| 17 | #include <linux/buffer_head.h> | 17 | #include <linux/buffer_head.h> |
| 18 | #include <linux/mutex.h> | ||
| 18 | 19 | ||
| 19 | #define MAX_PROBE_HASH 255 /* random */ | 20 | #define MAX_PROBE_HASH 255 /* random */ |
| 20 | 21 | ||
| 21 | static struct subsystem block_subsys; | 22 | static struct subsystem block_subsys; |
| 22 | 23 | ||
| 23 | static DECLARE_MUTEX(block_subsys_sem); | 24 | static DEFINE_MUTEX(block_subsys_lock); |
| 24 | 25 | ||
| 25 | /* | 26 | /* |
| 26 | * Can be deleted altogether. Later. | 27 | * Can be deleted altogether. Later. |
| @@ -46,7 +47,7 @@ struct blkdev_info { | |||
| 46 | /* | 47 | /* |
| 47 | * iterate over a list of blkdev_info structures. allows | 48 | * iterate over a list of blkdev_info structures. allows |
| 48 | * the major_names array to be iterated over from outside this file | 49 | * the major_names array to be iterated over from outside this file |
| 49 | * must be called with the block_subsys_sem held | 50 | * must be called with the block_subsys_lock held |
| 50 | */ | 51 | */ |
| 51 | void *get_next_blkdev(void *dev) | 52 | void *get_next_blkdev(void *dev) |
| 52 | { | 53 | { |
| @@ -85,20 +86,20 @@ out: | |||
| 85 | 86 | ||
| 86 | void *acquire_blkdev_list(void) | 87 | void *acquire_blkdev_list(void) |
| 87 | { | 88 | { |
| 88 | down(&block_subsys_sem); | 89 | mutex_lock(&block_subsys_lock); |
| 89 | return get_next_blkdev(NULL); | 90 | return get_next_blkdev(NULL); |
| 90 | } | 91 | } |
| 91 | 92 | ||
| 92 | void release_blkdev_list(void *dev) | 93 | void release_blkdev_list(void *dev) |
| 93 | { | 94 | { |
| 94 | up(&block_subsys_sem); | 95 | mutex_unlock(&block_subsys_lock); |
| 95 | kfree(dev); | 96 | kfree(dev); |
| 96 | } | 97 | } |
| 97 | 98 | ||
| 98 | 99 | ||
| 99 | /* | 100 | /* |
| 100 | * Count the number of records in the blkdev_list. | 101 | * Count the number of records in the blkdev_list. |
| 101 | * must be called with the block_subsys_sem held | 102 | * must be called with the block_subsys_lock held |
| 102 | */ | 103 | */ |
| 103 | int count_blkdev_list(void) | 104 | int count_blkdev_list(void) |
| 104 | { | 105 | { |
| @@ -118,7 +119,7 @@ int count_blkdev_list(void) | |||
| 118 | /* | 119 | /* |
| 119 | * extract the major and name values from a blkdev_info struct | 120 | * extract the major and name values from a blkdev_info struct |
| 120 | * passed in as a void to *dev. Must be called with | 121 | * passed in as a void to *dev. Must be called with |
| 121 | * block_subsys_sem held | 122 | * block_subsys_lock held |
| 122 | */ | 123 | */ |
| 123 | int get_blkdev_info(void *dev, int *major, char **name) | 124 | int get_blkdev_info(void *dev, int *major, char **name) |
| 124 | { | 125 | { |
| @@ -138,7 +139,7 @@ int register_blkdev(unsigned int major, const char *name) | |||
| 138 | struct blk_major_name **n, *p; | 139 | struct blk_major_name **n, *p; |
| 139 | int index, ret = 0; | 140 | int index, ret = 0; |
| 140 | 141 | ||
| 141 | down(&block_subsys_sem); | 142 | mutex_lock(&block_subsys_lock); |
| 142 | 143 | ||
| 143 | /* temporary */ | 144 | /* temporary */ |
| 144 | if (major == 0) { | 145 | if (major == 0) { |
| @@ -183,7 +184,7 @@ int register_blkdev(unsigned int major, const char *name) | |||
| 183 | kfree(p); | 184 | kfree(p); |
| 184 | } | 185 | } |
| 185 | out: | 186 | out: |
| 186 | up(&block_subsys_sem); | 187 | mutex_unlock(&block_subsys_lock); |
| 187 | return ret; | 188 | return ret; |
| 188 | } | 189 | } |
| 189 | 190 | ||
| @@ -197,7 +198,7 @@ int unregister_blkdev(unsigned int major, const char *name) | |||
| 197 | int index = major_to_index(major); | 198 | int index = major_to_index(major); |
| 198 | int ret = 0; | 199 | int ret = 0; |
| 199 | 200 | ||
| 200 | down(&block_subsys_sem); | 201 | mutex_lock(&block_subsys_lock); |
| 201 | for (n = &major_names[index]; *n; n = &(*n)->next) | 202 | for (n = &major_names[index]; *n; n = &(*n)->next) |
| 202 | if ((*n)->major == major) | 203 | if ((*n)->major == major) |
| 203 | break; | 204 | break; |
| @@ -207,7 +208,7 @@ int unregister_blkdev(unsigned int major, const char *name) | |||
| 207 | p = *n; | 208 | p = *n; |
| 208 | *n = p->next; | 209 | *n = p->next; |
| 209 | } | 210 | } |
| 210 | up(&block_subsys_sem); | 211 | mutex_unlock(&block_subsys_lock); |
| 211 | kfree(p); | 212 | kfree(p); |
| 212 | 213 | ||
| 213 | return ret; | 214 | return ret; |
| @@ -301,7 +302,7 @@ static void *part_start(struct seq_file *part, loff_t *pos) | |||
| 301 | struct list_head *p; | 302 | struct list_head *p; |
| 302 | loff_t l = *pos; | 303 | loff_t l = *pos; |
| 303 | 304 | ||
| 304 | down(&block_subsys_sem); | 305 | mutex_lock(&block_subsys_lock); |
| 305 | list_for_each(p, &block_subsys.kset.list) | 306 | list_for_each(p, &block_subsys.kset.list) |
| 306 | if (!l--) | 307 | if (!l--) |
| 307 | return list_entry(p, struct gendisk, kobj.entry); | 308 | return list_entry(p, struct gendisk, kobj.entry); |
| @@ -318,7 +319,7 @@ static void *part_next(struct seq_file *part, void *v, loff_t *pos) | |||
| 318 | 319 | ||
| 319 | static void part_stop(struct seq_file *part, void *v) | 320 | static void part_stop(struct seq_file *part, void *v) |
| 320 | { | 321 | { |
| 321 | up(&block_subsys_sem); | 322 | mutex_unlock(&block_subsys_lock); |
| 322 | } | 323 | } |
| 323 | 324 | ||
| 324 | static int show_partition(struct seq_file *part, void *v) | 325 | static int show_partition(struct seq_file *part, void *v) |
| @@ -377,7 +378,7 @@ static struct kobject *base_probe(dev_t dev, int *part, void *data) | |||
| 377 | 378 | ||
| 378 | static int __init genhd_device_init(void) | 379 | static int __init genhd_device_init(void) |
| 379 | { | 380 | { |
| 380 | bdev_map = kobj_map_init(base_probe, &block_subsys_sem); | 381 | bdev_map = kobj_map_init(base_probe, &block_subsys_lock); |
| 381 | blk_dev_init(); | 382 | blk_dev_init(); |
| 382 | subsystem_register(&block_subsys); | 383 | subsystem_register(&block_subsys); |
| 383 | return 0; | 384 | return 0; |
| @@ -611,7 +612,7 @@ static void *diskstats_start(struct seq_file *part, loff_t *pos) | |||
| 611 | loff_t k = *pos; | 612 | loff_t k = *pos; |
| 612 | struct list_head *p; | 613 | struct list_head *p; |
| 613 | 614 | ||
| 614 | down(&block_subsys_sem); | 615 | mutex_lock(&block_subsys_lock); |
| 615 | list_for_each(p, &block_subsys.kset.list) | 616 | list_for_each(p, &block_subsys.kset.list) |
| 616 | if (!k--) | 617 | if (!k--) |
| 617 | return list_entry(p, struct gendisk, kobj.entry); | 618 | return list_entry(p, struct gendisk, kobj.entry); |
| @@ -628,7 +629,7 @@ static void *diskstats_next(struct seq_file *part, void *v, loff_t *pos) | |||
| 628 | 629 | ||
| 629 | static void diskstats_stop(struct seq_file *part, void *v) | 630 | static void diskstats_stop(struct seq_file *part, void *v) |
| 630 | { | 631 | { |
| 631 | up(&block_subsys_sem); | 632 | mutex_unlock(&block_subsys_lock); |
| 632 | } | 633 | } |
| 633 | 634 | ||
| 634 | static int diskstats_show(struct seq_file *s, void *v) | 635 | static int diskstats_show(struct seq_file *s, void *v) |
diff --git a/drivers/base/map.c b/drivers/base/map.c index b449dae6f0d3..e87017f36853 100644 --- a/drivers/base/map.c +++ b/drivers/base/map.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
| 14 | #include <linux/mutex.h> | ||
| 14 | #include <linux/kdev_t.h> | 15 | #include <linux/kdev_t.h> |
| 15 | #include <linux/kobject.h> | 16 | #include <linux/kobject.h> |
| 16 | #include <linux/kobj_map.h> | 17 | #include <linux/kobj_map.h> |
| @@ -25,7 +26,7 @@ struct kobj_map { | |||
| 25 | int (*lock)(dev_t, void *); | 26 | int (*lock)(dev_t, void *); |
| 26 | void *data; | 27 | void *data; |
| 27 | } *probes[255]; | 28 | } *probes[255]; |
| 28 | struct semaphore *sem; | 29 | struct mutex *lock; |
| 29 | }; | 30 | }; |
| 30 | 31 | ||
| 31 | int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, | 32 | int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, |
| @@ -53,7 +54,7 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, | |||
| 53 | p->range = range; | 54 | p->range = range; |
| 54 | p->data = data; | 55 | p->data = data; |
| 55 | } | 56 | } |
| 56 | down(domain->sem); | 57 | mutex_lock(domain->lock); |
| 57 | for (i = 0, p -= n; i < n; i++, p++, index++) { | 58 | for (i = 0, p -= n; i < n; i++, p++, index++) { |
| 58 | struct probe **s = &domain->probes[index % 255]; | 59 | struct probe **s = &domain->probes[index % 255]; |
| 59 | while (*s && (*s)->range < range) | 60 | while (*s && (*s)->range < range) |
| @@ -61,7 +62,7 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, | |||
| 61 | p->next = *s; | 62 | p->next = *s; |
| 62 | *s = p; | 63 | *s = p; |
| 63 | } | 64 | } |
| 64 | up(domain->sem); | 65 | mutex_unlock(domain->lock); |
| 65 | return 0; | 66 | return 0; |
| 66 | } | 67 | } |
| 67 | 68 | ||
| @@ -75,7 +76,7 @@ void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range) | |||
| 75 | if (n > 255) | 76 | if (n > 255) |
| 76 | n = 255; | 77 | n = 255; |
| 77 | 78 | ||
| 78 | down(domain->sem); | 79 | mutex_lock(domain->lock); |
| 79 | for (i = 0; i < n; i++, index++) { | 80 | for (i = 0; i < n; i++, index++) { |
| 80 | struct probe **s; | 81 | struct probe **s; |
| 81 | for (s = &domain->probes[index % 255]; *s; s = &(*s)->next) { | 82 | for (s = &domain->probes[index % 255]; *s; s = &(*s)->next) { |
| @@ -88,7 +89,7 @@ void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range) | |||
| 88 | } | 89 | } |
| 89 | } | 90 | } |
| 90 | } | 91 | } |
| 91 | up(domain->sem); | 92 | mutex_unlock(domain->lock); |
| 92 | kfree(found); | 93 | kfree(found); |
| 93 | } | 94 | } |
| 94 | 95 | ||
| @@ -99,7 +100,7 @@ struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index) | |||
| 99 | unsigned long best = ~0UL; | 100 | unsigned long best = ~0UL; |
| 100 | 101 | ||
| 101 | retry: | 102 | retry: |
| 102 | down(domain->sem); | 103 | mutex_lock(domain->lock); |
| 103 | for (p = domain->probes[MAJOR(dev) % 255]; p; p = p->next) { | 104 | for (p = domain->probes[MAJOR(dev) % 255]; p; p = p->next) { |
| 104 | struct kobject *(*probe)(dev_t, int *, void *); | 105 | struct kobject *(*probe)(dev_t, int *, void *); |
| 105 | struct module *owner; | 106 | struct module *owner; |
| @@ -120,7 +121,7 @@ retry: | |||
| 120 | module_put(owner); | 121 | module_put(owner); |
| 121 | continue; | 122 | continue; |
| 122 | } | 123 | } |
| 123 | up(domain->sem); | 124 | mutex_unlock(domain->lock); |
| 124 | kobj = probe(dev, index, data); | 125 | kobj = probe(dev, index, data); |
| 125 | /* Currently ->owner protects _only_ ->probe() itself. */ | 126 | /* Currently ->owner protects _only_ ->probe() itself. */ |
| 126 | module_put(owner); | 127 | module_put(owner); |
| @@ -128,11 +129,11 @@ retry: | |||
| 128 | return kobj; | 129 | return kobj; |
| 129 | goto retry; | 130 | goto retry; |
| 130 | } | 131 | } |
| 131 | up(domain->sem); | 132 | mutex_unlock(domain->lock); |
| 132 | return NULL; | 133 | return NULL; |
| 133 | } | 134 | } |
| 134 | 135 | ||
| 135 | struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct semaphore *sem) | 136 | struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct mutex *lock) |
| 136 | { | 137 | { |
| 137 | struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL); | 138 | struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL); |
| 138 | struct probe *base = kzalloc(sizeof(*base), GFP_KERNEL); | 139 | struct probe *base = kzalloc(sizeof(*base), GFP_KERNEL); |
| @@ -149,6 +150,6 @@ struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct semaphore *sem) | |||
| 149 | base->get = base_probe; | 150 | base->get = base_probe; |
| 150 | for (i = 0; i < 255; i++) | 151 | for (i = 0; i < 255; i++) |
| 151 | p->probes[i] = base; | 152 | p->probes[i] = base; |
| 152 | p->sem = sem; | 153 | p->lock = lock; |
| 153 | return p; | 154 | return p; |
| 154 | } | 155 | } |
diff --git a/fs/char_dev.c b/fs/char_dev.c index 21195c481637..5c36345c9bf7 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/kobject.h> | 19 | #include <linux/kobject.h> |
| 20 | #include <linux/kobj_map.h> | 20 | #include <linux/kobj_map.h> |
| 21 | #include <linux/cdev.h> | 21 | #include <linux/cdev.h> |
| 22 | #include <linux/mutex.h> | ||
| 22 | 23 | ||
| 23 | #ifdef CONFIG_KMOD | 24 | #ifdef CONFIG_KMOD |
| 24 | #include <linux/kmod.h> | 25 | #include <linux/kmod.h> |
| @@ -28,7 +29,7 @@ static struct kobj_map *cdev_map; | |||
| 28 | 29 | ||
| 29 | #define MAX_PROBE_HASH 255 /* random */ | 30 | #define MAX_PROBE_HASH 255 /* random */ |
| 30 | 31 | ||
| 31 | static DECLARE_MUTEX(chrdevs_lock); | 32 | static DEFINE_MUTEX(chrdevs_lock); |
| 32 | 33 | ||
| 33 | static struct char_device_struct { | 34 | static struct char_device_struct { |
| 34 | struct char_device_struct *next; | 35 | struct char_device_struct *next; |
| @@ -88,13 +89,13 @@ out: | |||
| 88 | 89 | ||
| 89 | void *acquire_chrdev_list(void) | 90 | void *acquire_chrdev_list(void) |
| 90 | { | 91 | { |
| 91 | down(&chrdevs_lock); | 92 | mutex_lock(&chrdevs_lock); |
| 92 | return get_next_chrdev(NULL); | 93 | return get_next_chrdev(NULL); |
| 93 | } | 94 | } |
| 94 | 95 | ||
| 95 | void release_chrdev_list(void *dev) | 96 | void release_chrdev_list(void *dev) |
| 96 | { | 97 | { |
| 97 | up(&chrdevs_lock); | 98 | mutex_unlock(&chrdevs_lock); |
| 98 | kfree(dev); | 99 | kfree(dev); |
| 99 | } | 100 | } |
| 100 | 101 | ||
| @@ -151,7 +152,7 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor, | |||
| 151 | 152 | ||
| 152 | memset(cd, 0, sizeof(struct char_device_struct)); | 153 | memset(cd, 0, sizeof(struct char_device_struct)); |
| 153 | 154 | ||
| 154 | down(&chrdevs_lock); | 155 | mutex_lock(&chrdevs_lock); |
| 155 | 156 | ||
| 156 | /* temporary */ | 157 | /* temporary */ |
| 157 | if (major == 0) { | 158 | if (major == 0) { |
| @@ -186,10 +187,10 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor, | |||
| 186 | } | 187 | } |
| 187 | cd->next = *cp; | 188 | cd->next = *cp; |
| 188 | *cp = cd; | 189 | *cp = cd; |
| 189 | up(&chrdevs_lock); | 190 | mutex_unlock(&chrdevs_lock); |
| 190 | return cd; | 191 | return cd; |
| 191 | out: | 192 | out: |
| 192 | up(&chrdevs_lock); | 193 | mutex_unlock(&chrdevs_lock); |
| 193 | kfree(cd); | 194 | kfree(cd); |
| 194 | return ERR_PTR(ret); | 195 | return ERR_PTR(ret); |
| 195 | } | 196 | } |
| @@ -200,7 +201,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct) | |||
| 200 | struct char_device_struct *cd = NULL, **cp; | 201 | struct char_device_struct *cd = NULL, **cp; |
| 201 | int i = major_to_index(major); | 202 | int i = major_to_index(major); |
| 202 | 203 | ||
| 203 | down(&chrdevs_lock); | 204 | mutex_lock(&chrdevs_lock); |
| 204 | for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next) | 205 | for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next) |
| 205 | if ((*cp)->major == major && | 206 | if ((*cp)->major == major && |
| 206 | (*cp)->baseminor == baseminor && | 207 | (*cp)->baseminor == baseminor && |
| @@ -210,7 +211,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct) | |||
| 210 | cd = *cp; | 211 | cd = *cp; |
| 211 | *cp = cd->next; | 212 | *cp = cd->next; |
| 212 | } | 213 | } |
| 213 | up(&chrdevs_lock); | 214 | mutex_unlock(&chrdevs_lock); |
| 214 | return cd; | 215 | return cd; |
| 215 | } | 216 | } |
| 216 | 217 | ||
diff --git a/include/linux/kobj_map.h b/include/linux/kobj_map.h index cbe7d8008042..bafe178a381f 100644 --- a/include/linux/kobj_map.h +++ b/include/linux/kobj_map.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | #ifdef __KERNEL__ | 1 | #ifdef __KERNEL__ |
| 2 | 2 | ||
| 3 | #include <asm/semaphore.h> | 3 | #include <linux/mutex.h> |
| 4 | 4 | ||
| 5 | typedef struct kobject *kobj_probe_t(dev_t, int *, void *); | 5 | typedef struct kobject *kobj_probe_t(dev_t, int *, void *); |
| 6 | struct kobj_map; | 6 | struct kobj_map; |
| @@ -9,6 +9,6 @@ int kobj_map(struct kobj_map *, dev_t, unsigned long, struct module *, | |||
| 9 | kobj_probe_t *, int (*)(dev_t, void *), void *); | 9 | kobj_probe_t *, int (*)(dev_t, void *), void *); |
| 10 | void kobj_unmap(struct kobj_map *, dev_t, unsigned long); | 10 | void kobj_unmap(struct kobj_map *, dev_t, unsigned long); |
| 11 | struct kobject *kobj_lookup(struct kobj_map *, dev_t, int *); | 11 | struct kobject *kobj_lookup(struct kobj_map *, dev_t, int *); |
| 12 | struct kobj_map *kobj_map_init(kobj_probe_t *, struct semaphore *); | 12 | struct kobj_map *kobj_map_init(kobj_probe_t *, struct mutex *); |
| 13 | 13 | ||
| 14 | #endif | 14 | #endif |
