diff options
author | Jeff Mahoney <jeffm@suse.com> | 2006-06-26 03:27:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 12:58:35 -0400 |
commit | 10da4f795f965f22039aa2930b6f80964aad3ee5 (patch) | |
tree | 6f4bfd27cdcdad15b53df997476fae539383bf4a /drivers/md/dm.c | |
parent | 7ec75f254742766eb729f1d1024a5b4e6692fc5f (diff) |
[PATCH] dm: add module ref counting
The reference counting on dm-mod is zero if no mapped devices are open. This
is incorrect, and can lead to an oops if the module is unloaded while mapped
devices exist.
This patch claims a reference to the module whenever a device is created, and
drops it again when the device is freed.
Devices must be removed before dm-mod is unloaded.
[akpm: too late for 2.6.17 - suitable for 2.6.17.x after it has settled]
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r-- | drivers/md/dm.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index a5cc4c8462f3..29af584ae838 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -852,6 +852,9 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent) | |||
852 | return NULL; | 852 | return NULL; |
853 | } | 853 | } |
854 | 854 | ||
855 | if (!try_module_get(THIS_MODULE)) | ||
856 | goto bad0; | ||
857 | |||
855 | /* get a minor number for the dev */ | 858 | /* get a minor number for the dev */ |
856 | r = persistent ? specific_minor(md, minor) : next_free_minor(md, &minor); | 859 | r = persistent ? specific_minor(md, minor) : next_free_minor(md, &minor); |
857 | if (r < 0) | 860 | if (r < 0) |
@@ -918,6 +921,8 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent) | |||
918 | blk_cleanup_queue(md->queue); | 921 | blk_cleanup_queue(md->queue); |
919 | free_minor(minor); | 922 | free_minor(minor); |
920 | bad1: | 923 | bad1: |
924 | module_put(THIS_MODULE); | ||
925 | bad0: | ||
921 | kfree(md); | 926 | kfree(md); |
922 | return NULL; | 927 | return NULL; |
923 | } | 928 | } |
@@ -941,6 +946,7 @@ static void free_dev(struct mapped_device *md) | |||
941 | 946 | ||
942 | put_disk(md->disk); | 947 | put_disk(md->disk); |
943 | blk_cleanup_queue(md->queue); | 948 | blk_cleanup_queue(md->queue); |
949 | module_put(THIS_MODULE); | ||
944 | kfree(md); | 950 | kfree(md); |
945 | } | 951 | } |
946 | 952 | ||