aboutsummaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
Diffstat (limited to 'ipc')
-rw-r--r--ipc/sem.c16
1 files changed, 7 insertions, 9 deletions
diff --git a/ipc/sem.c b/ipc/sem.c
index 1f8f01a542de..8486a5bb6d29 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -269,6 +269,8 @@ static inline void sem_unlock(struct sem_array *sma, int locknum)
269/* 269/*
270 * sem_lock_(check_) routines are called in the paths where the rw_mutex 270 * sem_lock_(check_) routines are called in the paths where the rw_mutex
271 * is not held. 271 * is not held.
272 *
273 * The caller holds the RCU read lock.
272 */ 274 */
273static inline struct sem_array *sem_obtain_lock(struct ipc_namespace *ns, 275static inline struct sem_array *sem_obtain_lock(struct ipc_namespace *ns,
274 int id, struct sembuf *sops, int nsops, int *locknum) 276 int id, struct sembuf *sops, int nsops, int *locknum)
@@ -276,12 +278,9 @@ static inline struct sem_array *sem_obtain_lock(struct ipc_namespace *ns,
276 struct kern_ipc_perm *ipcp; 278 struct kern_ipc_perm *ipcp;
277 struct sem_array *sma; 279 struct sem_array *sma;
278 280
279 rcu_read_lock();
280 ipcp = ipc_obtain_object(&sem_ids(ns), id); 281 ipcp = ipc_obtain_object(&sem_ids(ns), id);
281 if (IS_ERR(ipcp)) { 282 if (IS_ERR(ipcp))
282 sma = ERR_CAST(ipcp); 283 return ERR_CAST(ipcp);
283 goto err;
284 }
285 284
286 sma = container_of(ipcp, struct sem_array, sem_perm); 285 sma = container_of(ipcp, struct sem_array, sem_perm);
287 *locknum = sem_lock(sma, sops, nsops); 286 *locknum = sem_lock(sma, sops, nsops);
@@ -293,10 +292,7 @@ static inline struct sem_array *sem_obtain_lock(struct ipc_namespace *ns,
293 return container_of(ipcp, struct sem_array, sem_perm); 292 return container_of(ipcp, struct sem_array, sem_perm);
294 293
295 sem_unlock(sma, *locknum); 294 sem_unlock(sma, *locknum);
296 sma = ERR_PTR(-EINVAL); 295 return ERR_PTR(-EINVAL);
297err:
298 rcu_read_unlock();
299 return sma;
300} 296}
301 297
302static inline struct sem_array *sem_obtain_object(struct ipc_namespace *ns, int id) 298static inline struct sem_array *sem_obtain_object(struct ipc_namespace *ns, int id)
@@ -1680,6 +1676,7 @@ sleep_again:
1680 goto out_free; 1676 goto out_free;
1681 } 1677 }
1682 1678
1679 rcu_read_lock();
1683 sma = sem_obtain_lock(ns, semid, sops, nsops, &locknum); 1680 sma = sem_obtain_lock(ns, semid, sops, nsops, &locknum);
1684 1681
1685 /* 1682 /*
@@ -1691,6 +1688,7 @@ sleep_again:
1691 * Array removed? If yes, leave without sem_unlock(). 1688 * Array removed? If yes, leave without sem_unlock().
1692 */ 1689 */
1693 if (IS_ERR(sma)) { 1690 if (IS_ERR(sma)) {
1691 rcu_read_unlock();
1694 goto out_free; 1692 goto out_free;
1695 } 1693 }
1696 1694