[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