diff options
author | Jiri Slaby <jirislaby@gmail.com> | 2009-06-22 19:42:03 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-22 20:32:23 +0200 |
commit | eca41044268887838fa122aa24475df8f23d614c (patch) | |
tree | 9cf22d5b96037273f6aa30fb9eb61ff4f9f04b7b /drivers/char/n_r3964.c | |
parent | serial: fix off by one errors (diff) | |
download | linux-eca41044268887838fa122aa24475df8f23d614c.tar.xz linux-eca41044268887838fa122aa24475df8f23d614c.zip |
n_r3964: fix lock imbalance
There is omitted BKunL in r3964_read.
Centralize the paths to one point with one unlock.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Cc: stable@kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to '')
-rw-r--r-- | drivers/char/n_r3964.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index d2e93e343226..2e99158ebb8a 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c @@ -1062,7 +1062,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, struct r3964_client_info *pClient; struct r3964_message *pMsg; struct r3964_client_message theMsg; - int count; + int ret; TRACE_L("read()"); @@ -1074,8 +1074,8 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, if (pMsg == NULL) { /* no messages available. */ if (file->f_flags & O_NONBLOCK) { - unlock_kernel(); - return -EAGAIN; + ret = -EAGAIN; + goto unlock; } /* block until there is a message: */ wait_event_interruptible(pInfo->read_wait, @@ -1085,29 +1085,31 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, /* If we still haven't got a message, we must have been signalled */ if (!pMsg) { - unlock_kernel(); - return -EINTR; + ret = -EINTR; + goto unlock; } /* deliver msg to client process: */ theMsg.msg_id = pMsg->msg_id; theMsg.arg = pMsg->arg; theMsg.error_code = pMsg->error_code; - count = sizeof(struct r3964_client_message); + ret = sizeof(struct r3964_client_message); kfree(pMsg); TRACE_M("r3964_read - msg kfree %p", pMsg); - if (copy_to_user(buf, &theMsg, count)) { - unlock_kernel(); - return -EFAULT; + if (copy_to_user(buf, &theMsg, ret)) { + ret = -EFAULT; + goto unlock; } - TRACE_PS("read - return %d", count); - return count; + TRACE_PS("read - return %d", ret); + goto unlock; } + ret = -EPERM; +unlock: unlock_kernel(); - return -EPERM; + return ret; } static ssize_t r3964_write(struct tty_struct *tty, struct file *file, |