[svn-commits] mattf: branch 1.4 r4183 - in /branches/1.4: ./ kernel/
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Sat Apr 19 16:54:03 CDT 2008
Author: mattf
Date: Sat Apr 19 16:54:03 2008
New Revision: 4183
URL: http://svn.digium.com/view/zaptel?view=rev&rev=4183
Log:
Partial fix for #9379. Fixes potential race condition in open and close routines for zaptel devices
Modified:
branches/1.4/ (props changed)
branches/1.4/kernel/zaptel-base.c
branches/1.4/kernel/zaptel.h
Propchange: branches/1.4/
------------------------------------------------------------------------------
svnmerge-integrated = /branches/1.4:1-4181
Modified: branches/1.4/kernel/zaptel-base.c
URL: http://svn.digium.com/view/zaptel/branches/1.4/kernel/zaptel-base.c?view=diff&rev=4183&r1=4182&r2=4183
==============================================================================
--- branches/1.4/kernel/zaptel-base.c (original)
+++ branches/1.4/kernel/zaptel-base.c Sat Apr 19 16:54:03 2008
@@ -2461,18 +2461,20 @@
if (chans[unit] && chans[unit]->sig) {
/* Make sure we're not already open, a net device, or a slave device */
- if (chans[unit]->flags & ZT_FLAG_OPEN)
- res = -EBUSY;
- else if (chans[unit]->flags & ZT_FLAG_NETDEV)
+ if (chans[unit]->flags & ZT_FLAG_NETDEV)
res = -EBUSY;
else if (chans[unit]->master != chans[unit])
res = -EBUSY;
else if ((chans[unit]->sig & __ZT_SIG_DACS) == __ZT_SIG_DACS)
res = -EBUSY;
- else {
+ else if (!test_and_set_bit(ZT_FLAGBIT_OPEN, &chans[unit]->flags)) {
unsigned long flags;
- /* Assume everything is going to be okay */
res = initialize_channel(chans[unit]);
+ if (res) {
+ /* Reallocbufs must have failed */
+ clear_bit(ZT_FLAGBIT_OPEN, &chans[unit]->flags);
+ return res;
+ }
spin_lock_irqsave(&chans[unit]->lock, flags);
if (chans[unit]->flags & ZT_FLAG_PSEUDO)
chans[unit]->flags |= ZT_FLAG_AUDIO;
@@ -2485,13 +2487,14 @@
if (inc)
MOD_INC_USE_COUNT;
#endif
- chans[unit]->flags |= ZT_FLAG_OPEN;
spin_unlock_irqrestore(&chans[unit]->lock, flags);
} else {
spin_unlock_irqrestore(&chans[unit]->lock, flags);
close_channel(chans[unit]);
- }
- }
+ clear_bit(ZT_FLAGBIT_OPEN, &chans[unit]->flags);
+ }
+ } else
+ res = -EBUSY;
} else
res = -ENXIO;
return res;
@@ -2500,15 +2503,18 @@
static int zt_specchan_release(struct inode *node, struct file *file, int unit)
{
int res=0;
+ unsigned long flags;
+
if (chans[unit]) {
- unsigned long flags;
+ /* Chan lock protects contents against potentially non atomic accesses.
+ * So if the pointer setting is not atomic, we should protect */
spin_lock_irqsave(&chans[unit]->lock, flags);
- chans[unit]->flags &= ~ZT_FLAG_OPEN;
+ chans[unit]->file = NULL;
spin_unlock_irqrestore(&chans[unit]->lock, flags);
- chans[unit]->file = NULL;
close_channel(chans[unit]);
if (chans[unit]->span && chans[unit]->span->close)
res = chans[unit]->span->close(chans[unit]);
+ clear_bit(ZT_FLAGBIT_OPEN, &chans[unit]->flags);
} else
res = -ENXIO;
#ifndef LINUX26
Modified: branches/1.4/kernel/zaptel.h
URL: http://svn.digium.com/view/zaptel/branches/1.4/kernel/zaptel.h?view=diff&rev=4183&r1=4182&r2=4183
==============================================================================
--- branches/1.4/kernel/zaptel.h (original)
+++ branches/1.4/kernel/zaptel.h Sat Apr 19 16:54:03 2008
@@ -1318,7 +1318,7 @@
/* Specified by zaptel */
int channo; /* Zaptel Channel number */
int chanpos;
- int flags;
+ unsigned long flags;
long rxp1;
long rxp2;
long rxp3;
@@ -1529,7 +1529,6 @@
ZT_RXSIG_INITIAL
} zt_rxsig_t;
-
/* Span flags */
#define ZT_FLAG_REGISTERED (1 << 0)
#define ZT_FLAG_RUNNING (1 << 1)
@@ -1555,6 +1554,30 @@
#define ZT_FLAG_SIGFREEZE (1 << 16) /* Freeze signalling */
#define ZT_FLAG_NOSTDTXRX (1 << 17) /* Do NOT do standard transmit and receive on every interrupt */
#define ZT_FLAG_LOOPED (1 << 18) /* Loopback the receive data from the channel to the transmit */
+
+/* This is a redefinition of the flags from above to allow use of the kernel atomic bit testing and changing routines.
+ * See the above descriptions for ZT_FLAG_.... for documentation about function. */
+enum {
+ ZT_FLAGBIT_REGISTERED = 0,
+ ZT_FLAGBIT_RUNNING = 1,
+ ZT_FLAGBIT_RBS = 12,
+ ZT_FLAGBIT_DTMFDECODE = 2,
+ ZT_FLAGBIT_MFDECODE = 3,
+ ZT_FLAGBIT_ECHOCANCEL = 4,
+ ZT_FLAGBIT_HDLC = 5,
+ ZT_FLAGBIT_NETDEV = 6,
+ ZT_FLAGBIT_PSEUDO = 7,
+ ZT_FLAGBIT_CLEAR = 8,
+ ZT_FLAGBIT_AUDIO = 9,
+ ZT_FLAGBIT_OPEN = 10,
+ ZT_FLAGBIT_FCS = 11,
+ ZT_FLAGBIT_LINEAR = 13,
+ ZT_FLAGBIT_PPP = 14,
+ ZT_FLAGBIT_T1PPP = 15,
+ ZT_FLAGBIT_SIGFREEZE = 16,
+ ZT_FLAGBIT_NOSTDTXRX = 17,
+ ZT_FLAGBIT_LOOPED = 18,
+};
struct zt_span {
spinlock_t lock;
More information about the svn-commits
mailing list