diff options
author | Shaun Ruffell <sruffell@digium.com> | 2010-12-07 14:20:38 +0000 |
---|---|---|
committer | Shaun Ruffell <sruffell@digium.com> | 2010-12-07 14:20:38 +0000 |
commit | c230f2a285c5952c530c2a985a7cecee87bb64c6 (patch) | |
tree | 06fa48c848957ec800614b16f2ce18685e2ec8d9 /drivers/dahdi | |
parent | 7817b1354fe8c7194b11a552c739de171346d60e (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')
-rw-r--r-- | drivers/dahdi/dahdi-base.c | 11 |
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; |