aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2013-03-05 01:09:04 -0500
committerDavid S. Miller <davem@davemloft.net>2013-03-06 02:47:04 -0500
commita4ed2e737cb73e4405a3649f8aef7619b99fecae (patch)
tree6cc188dc7dd206790023fb360af4b1a886611855 /net
parent0305d0689efd35b4c9f88bb560c104ed118d2277 (diff)
net/irda: Fix port open counts
Saving the port count bump is unsafe. If the tty is hung up while this open was blocking, the port count is zeroed. Explicitly check if the tty was hung up while blocking, and correct the port count if not. Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/irda/ircomm/ircomm_tty.c14
1 files changed, 5 insertions, 9 deletions
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 9a5fd3c3e530..1721dc7e4315 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -280,7 +280,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
280 struct tty_port *port = &self->port; 280 struct tty_port *port = &self->port;
281 DECLARE_WAITQUEUE(wait, current); 281 DECLARE_WAITQUEUE(wait, current);
282 int retval; 282 int retval;
283 int do_clocal = 0, extra_count = 0; 283 int do_clocal = 0;
284 unsigned long flags; 284 unsigned long flags;
285 285
286 IRDA_DEBUG(2, "%s()\n", __func__ ); 286 IRDA_DEBUG(2, "%s()\n", __func__ );
@@ -315,10 +315,8 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
315 __FILE__, __LINE__, tty->driver->name, port->count); 315 __FILE__, __LINE__, tty->driver->name, port->count);
316 316
317 spin_lock_irqsave(&port->lock, flags); 317 spin_lock_irqsave(&port->lock, flags);
318 if (!tty_hung_up_p(filp)) { 318 if (!tty_hung_up_p(filp))
319 extra_count = 1;
320 port->count--; 319 port->count--;
321 }
322 spin_unlock_irqrestore(&port->lock, flags); 320 spin_unlock_irqrestore(&port->lock, flags);
323 port->blocked_open++; 321 port->blocked_open++;
324 322
@@ -361,12 +359,10 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
361 __set_current_state(TASK_RUNNING); 359 __set_current_state(TASK_RUNNING);
362 remove_wait_queue(&port->open_wait, &wait); 360 remove_wait_queue(&port->open_wait, &wait);
363 361
364 if (extra_count) { 362 spin_lock_irqsave(&port->lock, flags);
365 /* ++ is not atomic, so this should be protected - Jean II */ 363 if (!tty_hung_up_p(filp))
366 spin_lock_irqsave(&port->lock, flags);
367 port->count++; 364 port->count++;
368 spin_unlock_irqrestore(&port->lock, flags); 365 spin_unlock_irqrestore(&port->lock, flags);
369 }
370 port->blocked_open--; 366 port->blocked_open--;
371 367
372 IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n", 368 IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n",