diff options
Diffstat (limited to 'ipc/sem.c')
-rw-r--r-- | ipc/sem.c | 34 |
1 files changed, 18 insertions, 16 deletions
@@ -75,6 +75,8 @@ | |||
75 | #include <linux/audit.h> | 75 | #include <linux/audit.h> |
76 | #include <linux/capability.h> | 76 | #include <linux/capability.h> |
77 | #include <linux/seq_file.h> | 77 | #include <linux/seq_file.h> |
78 | #include <linux/mutex.h> | ||
79 | |||
78 | #include <asm/uaccess.h> | 80 | #include <asm/uaccess.h> |
79 | #include "util.h" | 81 | #include "util.h" |
80 | 82 | ||
@@ -139,7 +141,7 @@ void __init sem_init (void) | |||
139 | * * if it's IN_WAKEUP, then it must wait until the value changes | 141 | * * if it's IN_WAKEUP, then it must wait until the value changes |
140 | * * if it's not -EINTR, then the operation was completed by | 142 | * * if it's not -EINTR, then the operation was completed by |
141 | * update_queue. semtimedop can return queue.status without | 143 | * update_queue. semtimedop can return queue.status without |
142 | * performing any operation on the semaphore array. | 144 | * performing any operation on the sem array. |
143 | * * otherwise it must acquire the spinlock and check what's up. | 145 | * * otherwise it must acquire the spinlock and check what's up. |
144 | * | 146 | * |
145 | * The two-stage algorithm is necessary to protect against the following | 147 | * The two-stage algorithm is necessary to protect against the following |
@@ -214,7 +216,7 @@ asmlinkage long sys_semget (key_t key, int nsems, int semflg) | |||
214 | 216 | ||
215 | if (nsems < 0 || nsems > sc_semmsl) | 217 | if (nsems < 0 || nsems > sc_semmsl) |
216 | return -EINVAL; | 218 | return -EINVAL; |
217 | down(&sem_ids.sem); | 219 | mutex_lock(&sem_ids.mutex); |
218 | 220 | ||
219 | if (key == IPC_PRIVATE) { | 221 | if (key == IPC_PRIVATE) { |
220 | err = newary(key, nsems, semflg); | 222 | err = newary(key, nsems, semflg); |
@@ -241,7 +243,7 @@ asmlinkage long sys_semget (key_t key, int nsems, int semflg) | |||
241 | sem_unlock(sma); | 243 | sem_unlock(sma); |
242 | } | 244 | } |
243 | 245 | ||
244 | up(&sem_ids.sem); | 246 | mutex_unlock(&sem_ids.mutex); |
245 | return err; | 247 | return err; |
246 | } | 248 | } |
247 | 249 | ||
@@ -436,8 +438,8 @@ static int count_semzcnt (struct sem_array * sma, ushort semnum) | |||
436 | return semzcnt; | 438 | return semzcnt; |
437 | } | 439 | } |
438 | 440 | ||
439 | /* Free a semaphore set. freeary() is called with sem_ids.sem down and | 441 | /* Free a semaphore set. freeary() is called with sem_ids.mutex locked and |
440 | * the spinlock for this semaphore set hold. sem_ids.sem remains locked | 442 | * the spinlock for this semaphore set hold. sem_ids.mutex remains locked |
441 | * on exit. | 443 | * on exit. |
442 | */ | 444 | */ |
443 | static void freeary (struct sem_array *sma, int id) | 445 | static void freeary (struct sem_array *sma, int id) |
@@ -524,7 +526,7 @@ static int semctl_nolock(int semid, int semnum, int cmd, int version, union semu | |||
524 | seminfo.semmnu = SEMMNU; | 526 | seminfo.semmnu = SEMMNU; |
525 | seminfo.semmap = SEMMAP; | 527 | seminfo.semmap = SEMMAP; |
526 | seminfo.semume = SEMUME; | 528 | seminfo.semume = SEMUME; |
527 | down(&sem_ids.sem); | 529 | mutex_lock(&sem_ids.mutex); |
528 | if (cmd == SEM_INFO) { | 530 | if (cmd == SEM_INFO) { |
529 | seminfo.semusz = sem_ids.in_use; | 531 | seminfo.semusz = sem_ids.in_use; |
530 | seminfo.semaem = used_sems; | 532 | seminfo.semaem = used_sems; |
@@ -533,7 +535,7 @@ static int semctl_nolock(int semid, int semnum, int cmd, int version, union semu | |||
533 | seminfo.semaem = SEMAEM; | 535 | seminfo.semaem = SEMAEM; |
534 | } | 536 | } |
535 | max_id = sem_ids.max_id; | 537 | max_id = sem_ids.max_id; |
536 | up(&sem_ids.sem); | 538 | mutex_unlock(&sem_ids.mutex); |
537 | if (copy_to_user (arg.__buf, &seminfo, sizeof(struct seminfo))) | 539 | if (copy_to_user (arg.__buf, &seminfo, sizeof(struct seminfo))) |
538 | return -EFAULT; | 540 | return -EFAULT; |
539 | return (max_id < 0) ? 0: max_id; | 541 | return (max_id < 0) ? 0: max_id; |
@@ -884,9 +886,9 @@ asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg) | |||
884 | return err; | 886 | return err; |
885 | case IPC_RMID: | 887 | case IPC_RMID: |
886 | case IPC_SET: | 888 | case IPC_SET: |
887 | down(&sem_ids.sem); | 889 | mutex_lock(&sem_ids.mutex); |
888 | err = semctl_down(semid,semnum,cmd,version,arg); | 890 | err = semctl_down(semid,semnum,cmd,version,arg); |
889 | up(&sem_ids.sem); | 891 | mutex_unlock(&sem_ids.mutex); |
890 | return err; | 892 | return err; |
891 | default: | 893 | default: |
892 | return -EINVAL; | 894 | return -EINVAL; |
@@ -1297,9 +1299,9 @@ found: | |||
1297 | /* perform adjustments registered in u */ | 1299 | /* perform adjustments registered in u */ |
1298 | nsems = sma->sem_nsems; | 1300 | nsems = sma->sem_nsems; |
1299 | for (i = 0; i < nsems; i++) { | 1301 | for (i = 0; i < nsems; i++) { |
1300 | struct sem * sem = &sma->sem_base[i]; | 1302 | struct sem * semaphore = &sma->sem_base[i]; |
1301 | if (u->semadj[i]) { | 1303 | if (u->semadj[i]) { |
1302 | sem->semval += u->semadj[i]; | 1304 | semaphore->semval += u->semadj[i]; |
1303 | /* | 1305 | /* |
1304 | * Range checks of the new semaphore value, | 1306 | * Range checks of the new semaphore value, |
1305 | * not defined by sus: | 1307 | * not defined by sus: |
@@ -1313,11 +1315,11 @@ found: | |||
1313 | * | 1315 | * |
1314 | * Manfred <manfred@colorfullife.com> | 1316 | * Manfred <manfred@colorfullife.com> |
1315 | */ | 1317 | */ |
1316 | if (sem->semval < 0) | 1318 | if (semaphore->semval < 0) |
1317 | sem->semval = 0; | 1319 | semaphore->semval = 0; |
1318 | if (sem->semval > SEMVMX) | 1320 | if (semaphore->semval > SEMVMX) |
1319 | sem->semval = SEMVMX; | 1321 | semaphore->semval = SEMVMX; |
1320 | sem->sempid = current->tgid; | 1322 | semaphore->sempid = current->tgid; |
1321 | } | 1323 | } |
1322 | } | 1324 | } |
1323 | sma->sem_otime = get_seconds(); | 1325 | sma->sem_otime = get_seconds(); |