diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-04 11:04:29 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-04 17:21:58 -0700 |
commit | c728b9c87b59fb943c4cba0552d38152787a4ab6 (patch) | |
tree | 072a4bac6686701ef46eca2fabb06306c400391b | |
parent | 321310ced2d6cc0175c76fa512fa8a829ee35223 (diff) | |
download | linux-c728b9c87b59fb943c4cba0552d38152787a4ab6.tar.gz linux-c728b9c87b59fb943c4cba0552d38152787a4ab6.tar.bz2 linux-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>
-rw-r--r-- | ipc/sem.c | 41 |
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) |