summaryrefslogtreecommitdiff
path: root/drivers/dahdi/dahdi-base.c
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2010-12-07 14:20:38 +0000
committerShaun Ruffell <sruffell@digium.com>2010-12-07 14:20:38 +0000
commitc230f2a285c5952c530c2a985a7cecee87bb64c6 (patch)
tree06fa48c848957ec800614b16f2ce18685e2ec8d9 /drivers/dahdi/dahdi-base.c
parent7817b1354fe8c7194b11a552c739de171346d60e (diff)
dahdi: Prevent unloadable module on failed open.
If chan->span->ops->open() fails then the reference count of the module implementing the board driver will not be decremented. The result is a module that would always be "in use" and unloadable. This change makes sure to release that reference when open failed. (closes issue #18422) Reported by: avarvit Signed-off-by: Shaun Ruffell <sruffell@digium.com> Acked-by: Angelos Varvitsiotis <avarvit@admin.grnet.gr> git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9510 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/dahdi-base.c')
-rw-r--r--drivers/dahdi/dahdi-base.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c
index 60a070e..a292619 100644
--- a/drivers/dahdi/dahdi-base.c
+++ b/drivers/dahdi/dahdi-base.c
@@ -2756,6 +2756,7 @@ static int dahdi_specchan_open(struct file *file)
res = -EBUSY;
else if (!test_and_set_bit(DAHDI_FLAGBIT_OPEN, &chan->flags)) {
unsigned long flags;
+ const struct dahdi_span_ops *ops;
res = initialize_channel(chan);
if (res) {
/* Reallocbufs must have failed */
@@ -2763,13 +2764,17 @@ static int dahdi_specchan_open(struct file *file)
return res;
}
spin_lock_irqsave(&chan->lock, flags);
+ ops = chan->span->ops;
if (is_pseudo_chan(chan))
chan->flags |= DAHDI_FLAG_AUDIO;
if (chan->span) {
- if (!try_module_get(chan->span->ops->owner))
+ if (!try_module_get(ops->owner)) {
res = -ENXIO;
- else if (chan->span->ops->open)
- res = chan->span->ops->open(chan);
+ } else if (ops->open) {
+ res = ops->open(chan);
+ if (res)
+ module_put(ops->owner);
+ }
}
if (!res) {
chan->file = file;