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); |
@@ -242,7 +244,7 @@ asmlinkage long sys_semget (key_t key, int nsems, int semflg) | |||
242 | sem_unlock(sma); | 244 | sem_unlock(sma); |
243 | } | 245 | } |
244 | 246 | ||
245 | up(&sem_ids.sem); | 247 | mutex_unlock(&sem_ids.mutex); |
246 | return err; | 248 | return err; |
247 | } | 249 | } |
248 | 250 | ||
@@ -437,8 +439,8 @@ static int count_semzcnt (struct sem_array * sma, ushort semnum) | |||
437 | return semzcnt; | 439 | return semzcnt; |
438 | } | 440 | } |
439 | 441 | ||
440 | /* Free a semaphore set. freeary() is called with sem_ids.sem down and | 442 | /* Free a semaphore set. freeary() is called with sem_ids.mutex locked and |
441 | * the spinlock for this semaphore set hold. sem_ids.sem remains locked | 443 | * the spinlock for this semaphore set hold. sem_ids.mutex remains locked |
442 | * on exit. | 444 | * on exit. |
443 | */ | 445 | */ |
444 | static void freeary (struct sem_array *sma, int id) | 446 | static void freeary (struct sem_array *sma, int id) |
@@ -525,7 +527,7 @@ static int semctl_nolock(int semid, int semnum, int cmd, int version, union semu | |||
525 | seminfo.semmnu = SEMMNU; | 527 | seminfo.semmnu = SEMMNU; |
526 | seminfo.semmap = SEMMAP; | 528 | seminfo.semmap = SEMMAP; |
527 | seminfo.semume = SEMUME; | 529 | seminfo.semume = SEMUME; |
528 | down(&sem_ids.sem); | 530 | mutex_lock(&sem_ids.mutex); |
529 | if (cmd == SEM_INFO) { | 531 | if (cmd == SEM_INFO) { |
530 | seminfo.semusz = sem_ids.in_use; | 532 | seminfo.semusz = sem_ids.in_use; |
531 | seminfo.semaem = used_sems; | 533 | seminfo.semaem = used_sems; |
@@ -534,7 +536,7 @@ static int semctl_nolock(int semid, int semnum, int cmd, int version, union semu | |||
534 | seminfo.semaem = SEMAEM; | 536 | seminfo.semaem = SEMAEM; |
535 | } | 537 | } |
536 | max_id = sem_ids.max_id; | 538 | max_id = sem_ids.max_id; |
537 | up(&sem_ids.sem); | 539 | mutex_unlock(&sem_ids.mutex); |
538 | if (copy_to_user (arg.__buf, &seminfo, sizeof(struct seminfo))) | 540 | if (copy_to_user (arg.__buf, &seminfo, sizeof(struct seminfo))) |
539 | return -EFAULT; | 541 | return -EFAULT; |
540 | return (max_id < 0) ? 0: max_id; | 542 | return (max_id < 0) ? 0: max_id; |
@@ -885,9 +887,9 @@ asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg) | |||
885 | return err; | 887 | return err; |
886 | case IPC_RMID: | 888 | case IPC_RMID: |
887 | case IPC_SET: | 889 | case IPC_SET: |
888 | down(&sem_ids.sem); | 890 | mutex_lock(&sem_ids.mutex); |
889 | err = semctl_down(semid,semnum,cmd,version,arg); | 891 | err = semctl_down(semid,semnum,cmd,version,arg); |
890 | up(&sem_ids.sem); | 892 | mutex_unlock(&sem_ids.mutex); |
891 | return err; | 893 | return err; |
892 | default: | 894 | default: |
893 | return -EINVAL; | 895 | return -EINVAL; |
@@ -1299,9 +1301,9 @@ found: | |||
1299 | /* perform adjustments registered in u */ | 1301 | /* perform adjustments registered in u */ |
1300 | nsems = sma->sem_nsems; | 1302 | nsems = sma->sem_nsems; |
1301 | for (i = 0; i < nsems; i++) { | 1303 | for (i = 0; i < nsems; i++) { |
1302 | struct sem * sem = &sma->sem_base[i]; | 1304 | struct sem * semaphore = &sma->sem_base[i]; |
1303 | if (u->semadj[i]) { | 1305 | if (u->semadj[i]) { |
1304 | sem->semval += u->semadj[i]; | 1306 | semaphore->semval += u->semadj[i]; |
1305 | /* | 1307 | /* |
1306 | * Range checks of the new semaphore value, | 1308 | * Range checks of the new semaphore value, |
1307 | * not defined by sus: | 1309 | * not defined by sus: |
@@ -1315,11 +1317,11 @@ found: | |||
1315 | * | 1317 | * |
1316 | * Manfred <manfred@colorfullife.com> | 1318 | * Manfred <manfred@colorfullife.com> |
1317 | */ | 1319 | */ |
1318 | if (sem->semval < 0) | 1320 | if (semaphore->semval < 0) |
1319 | sem->semval = 0; | 1321 | semaphore->semval = 0; |
1320 | if (sem->semval > SEMVMX) | 1322 | if (semaphore->semval > SEMVMX) |
1321 | sem->semval = SEMVMX; | 1323 | semaphore->semval = SEMVMX; |
1322 | sem->sempid = current->tgid; | 1324 | semaphore->sempid = current->tgid; |
1323 | } | 1325 | } |
1324 | } | 1326 | } |
1325 | sma->sem_otime = get_seconds(); | 1327 | sma->sem_otime = get_seconds(); |