summaryrefslogtreecommitdiff
path: root/ipc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-04 11:04:29 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-04 17:21:58 -0700
commitc728b9c87b59fb943c4cba0552d38152787a4ab6 (patch)
tree072a4bac6686701ef46eca2fabb06306c400391b /ipc
parent321310ced2d6cc0175c76fa512fa8a829ee35223 (diff)
downloadlinux-stable-c728b9c87b59fb943c4cba0552d38152787a4ab6.tar.gz
linux-stable-c728b9c87b59fb943c4cba0552d38152787a4ab6.tar.bz2
linux-stable-c728b9c87b59fb943c4cba0552d38152787a4ab6.zip
ipc: simplify semtimedop/semctl_main() common error path handling
With various straight RCU lock/unlock movements, one common exit path pattern had become rcu_read_unlock(); goto out_wakeup; and in fact there were no cases where we wanted to exit to out_wakeup _without_ releasing the RCU read lock. So replace that pattern with "goto out_rcu_wakeup", and remove the old out_wakeup. Acked-by: Davidlohr Bueso <davidlohr.bueso@hp.com> Cc: Rik van Riel <riel@redhat.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'ipc')
-rw-r--r--ipc/sem.c41
1 files changed, 14 insertions, 27 deletions
diff --git a/ipc/sem.c b/ipc/sem.c
index 8486a5bb6d29..f2151babd26a 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -1077,17 +1077,12 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
nsems = sma->sem_nsems;
err = -EACCES;
- if (ipcperms(ns, &sma->sem_perm,
- cmd == SETALL ? S_IWUGO : S_IRUGO)) {
- rcu_read_unlock();
- goto out_wakeup;
- }
+ if (ipcperms(ns, &sma->sem_perm, cmd == SETALL ? S_IWUGO : S_IRUGO))
+ goto out_rcu_wakeup;
err = security_sem_semctl(sma, cmd);
- if (err) {
- rcu_read_unlock();
- goto out_wakeup;
- }
+ if (err)
+ goto out_rcu_wakeup;
err = -EACCES;
switch (cmd) {
@@ -1188,10 +1183,8 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
/* GETVAL, GETPID, GETNCTN, GETZCNT: fall-through */
}
err = -EINVAL;
- if (semnum < 0 || semnum >= nsems) {
- rcu_read_unlock();
- goto out_wakeup;
- }
+ if (semnum < 0 || semnum >= nsems)
+ goto out_rcu_wakeup;
sem_lock(sma, NULL, -1);
curr = &sma->sem_base[semnum];
@@ -1213,8 +1206,8 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
out_unlock:
sem_unlock(sma, -1);
+out_rcu_wakeup:
rcu_read_unlock();
-out_wakeup:
wake_up_sem_queue_do(&tasks);
out_free:
if(sem_io != fast_sem_io)
@@ -1585,22 +1578,16 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
}
error = -EFBIG;
- if (max >= sma->sem_nsems) {
- rcu_read_unlock();
- goto out_wakeup;
- }
+ if (max >= sma->sem_nsems)
+ goto out_rcu_wakeup;
error = -EACCES;
- if (ipcperms(ns, &sma->sem_perm, alter ? S_IWUGO : S_IRUGO)) {
- rcu_read_unlock();
- goto out_wakeup;
- }
+ if (ipcperms(ns, &sma->sem_perm, alter ? S_IWUGO : S_IRUGO))
+ goto out_rcu_wakeup;
error = security_sem_semop(sma, sops, nsops, alter);
- if (error) {
- rcu_read_unlock();
- goto out_wakeup;
- }
+ if (error)
+ goto out_rcu_wakeup;
/*
* semid identifiers are not unique - find_alloc_undo may have
@@ -1718,8 +1705,8 @@ sleep_again:
out_unlock_free:
sem_unlock(sma, locknum);
+out_rcu_wakeup:
rcu_read_unlock();
-out_wakeup:
wake_up_sem_queue_do(&tasks);
out_free:
if(sops != fast_sops)