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
This commit is contained in:
Shaun Ruffell 2010-12-07 14:20:38 +00:00
parent 8b43a66913
commit f7925643de

View File

@ -2756,6 +2756,7 @@ static int dahdi_specchan_open(struct file *file)
res = -EBUSY; res = -EBUSY;
else if (!test_and_set_bit(DAHDI_FLAGBIT_OPEN, &chan->flags)) { else if (!test_and_set_bit(DAHDI_FLAGBIT_OPEN, &chan->flags)) {
unsigned long flags; unsigned long flags;
const struct dahdi_span_ops *ops;
res = initialize_channel(chan); res = initialize_channel(chan);
if (res) { if (res) {
/* Reallocbufs must have failed */ /* Reallocbufs must have failed */
@ -2763,13 +2764,17 @@ static int dahdi_specchan_open(struct file *file)
return res; return res;
} }
spin_lock_irqsave(&chan->lock, flags); spin_lock_irqsave(&chan->lock, flags);
ops = chan->span->ops;
if (is_pseudo_chan(chan)) if (is_pseudo_chan(chan))
chan->flags |= DAHDI_FLAG_AUDIO; chan->flags |= DAHDI_FLAG_AUDIO;
if (chan->span) { if (chan->span) {
if (!try_module_get(chan->span->ops->owner)) if (!try_module_get(ops->owner)) {
res = -ENXIO; res = -ENXIO;
else if (chan->span->ops->open) } else if (ops->open) {
res = chan->span->ops->open(chan); res = ops->open(chan);
if (res)
module_put(ops->owner);
}
} }
if (!res) { if (!res) {
chan->file = file; chan->file = file;