aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/sem.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/sem.c')
-rw-r--r--ipc/sem.c96
1 files changed, 48 insertions, 48 deletions
diff --git a/ipc/sem.c b/ipc/sem.c
index 160fbb3390bb..c40876b5b002 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -188,7 +188,7 @@ void sem_exit_ns(struct ipc_namespace *ns)
188} 188}
189#endif 189#endif
190 190
191void __init sem_init (void) 191void __init sem_init(void)
192{ 192{
193 sem_init_ns(&init_ipc_ns); 193 sem_init_ns(&init_ipc_ns);
194 ipc_init_proc_interface("sysvipc/sem", 194 ipc_init_proc_interface("sysvipc/sem",
@@ -445,11 +445,11 @@ static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s)
445 * * call wake_up_process 445 * * call wake_up_process
446 * * set queue.status to the final value. 446 * * set queue.status to the final value.
447 * - the previously blocked thread checks queue.status: 447 * - the previously blocked thread checks queue.status:
448 * * if it's IN_WAKEUP, then it must wait until the value changes 448 * * if it's IN_WAKEUP, then it must wait until the value changes
449 * * if it's not -EINTR, then the operation was completed by 449 * * if it's not -EINTR, then the operation was completed by
450 * update_queue. semtimedop can return queue.status without 450 * update_queue. semtimedop can return queue.status without
451 * performing any operation on the sem array. 451 * performing any operation on the sem array.
452 * * otherwise it must acquire the spinlock and check what's up. 452 * * otherwise it must acquire the spinlock and check what's up.
453 * 453 *
454 * The two-stage algorithm is necessary to protect against the following 454 * The two-stage algorithm is necessary to protect against the following
455 * races: 455 * races:
@@ -491,12 +491,12 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params)
491 if (ns->used_sems + nsems > ns->sc_semmns) 491 if (ns->used_sems + nsems > ns->sc_semmns)
492 return -ENOSPC; 492 return -ENOSPC;
493 493
494 size = sizeof (*sma) + nsems * sizeof (struct sem); 494 size = sizeof(*sma) + nsems * sizeof(struct sem);
495 sma = ipc_rcu_alloc(size); 495 sma = ipc_rcu_alloc(size);
496 if (!sma) { 496 if (!sma) {
497 return -ENOMEM; 497 return -ENOMEM;
498 } 498 }
499 memset (sma, 0, size); 499 memset(sma, 0, size);
500 500
501 sma->sem_perm.mode = (semflg & S_IRWXUGO); 501 sma->sem_perm.mode = (semflg & S_IRWXUGO);
502 sma->sem_perm.key = key; 502 sma->sem_perm.key = key;
@@ -601,7 +601,7 @@ static int perform_atomic_semop(struct sem_array *sma, struct sembuf *sops,
601{ 601{
602 int result, sem_op; 602 int result, sem_op;
603 struct sembuf *sop; 603 struct sembuf *sop;
604 struct sem * curr; 604 struct sem *curr;
605 605
606 for (sop = sops; sop < sops + nsops; sop++) { 606 for (sop = sops; sop < sops + nsops; sop++) {
607 curr = sma->sem_base + sop->sem_num; 607 curr = sma->sem_base + sop->sem_num;
@@ -1000,21 +1000,21 @@ static void do_smart_update(struct sem_array *sma, struct sembuf *sops, int nsop
1000 * The counts we return here are a rough approximation, but still 1000 * The counts we return here are a rough approximation, but still
1001 * warrant that semncnt+semzcnt>0 if the task is on the pending queue. 1001 * warrant that semncnt+semzcnt>0 if the task is on the pending queue.
1002 */ 1002 */
1003static int count_semncnt (struct sem_array * sma, ushort semnum) 1003static int count_semncnt(struct sem_array *sma, ushort semnum)
1004{ 1004{
1005 int semncnt; 1005 int semncnt;
1006 struct sem_queue * q; 1006 struct sem_queue *q;
1007 1007
1008 semncnt = 0; 1008 semncnt = 0;
1009 list_for_each_entry(q, &sma->sem_base[semnum].pending_alter, list) { 1009 list_for_each_entry(q, &sma->sem_base[semnum].pending_alter, list) {
1010 struct sembuf * sops = q->sops; 1010 struct sembuf *sops = q->sops;
1011 BUG_ON(sops->sem_num != semnum); 1011 BUG_ON(sops->sem_num != semnum);
1012 if ((sops->sem_op < 0) && !(sops->sem_flg & IPC_NOWAIT)) 1012 if ((sops->sem_op < 0) && !(sops->sem_flg & IPC_NOWAIT))
1013 semncnt++; 1013 semncnt++;
1014 } 1014 }
1015 1015
1016 list_for_each_entry(q, &sma->pending_alter, list) { 1016 list_for_each_entry(q, &sma->pending_alter, list) {
1017 struct sembuf * sops = q->sops; 1017 struct sembuf *sops = q->sops;
1018 int nsops = q->nsops; 1018 int nsops = q->nsops;
1019 int i; 1019 int i;
1020 for (i = 0; i < nsops; i++) 1020 for (i = 0; i < nsops; i++)
@@ -1026,21 +1026,21 @@ static int count_semncnt (struct sem_array * sma, ushort semnum)
1026 return semncnt; 1026 return semncnt;
1027} 1027}
1028 1028
1029static int count_semzcnt (struct sem_array * sma, ushort semnum) 1029static int count_semzcnt(struct sem_array *sma, ushort semnum)
1030{ 1030{
1031 int semzcnt; 1031 int semzcnt;
1032 struct sem_queue * q; 1032 struct sem_queue *q;
1033 1033
1034 semzcnt = 0; 1034 semzcnt = 0;
1035 list_for_each_entry(q, &sma->sem_base[semnum].pending_const, list) { 1035 list_for_each_entry(q, &sma->sem_base[semnum].pending_const, list) {
1036 struct sembuf * sops = q->sops; 1036 struct sembuf *sops = q->sops;
1037 BUG_ON(sops->sem_num != semnum); 1037 BUG_ON(sops->sem_num != semnum);
1038 if ((sops->sem_op == 0) && !(sops->sem_flg & IPC_NOWAIT)) 1038 if ((sops->sem_op == 0) && !(sops->sem_flg & IPC_NOWAIT))
1039 semzcnt++; 1039 semzcnt++;
1040 } 1040 }
1041 1041
1042 list_for_each_entry(q, &sma->pending_const, list) { 1042 list_for_each_entry(q, &sma->pending_const, list) {
1043 struct sembuf * sops = q->sops; 1043 struct sembuf *sops = q->sops;
1044 int nsops = q->nsops; 1044 int nsops = q->nsops;
1045 int i; 1045 int i;
1046 for (i = 0; i < nsops; i++) 1046 for (i = 0; i < nsops; i++)
@@ -1110,7 +1110,7 @@ static void freeary(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
1110 1110
1111static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in, int version) 1111static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in, int version)
1112{ 1112{
1113 switch(version) { 1113 switch (version) {
1114 case IPC_64: 1114 case IPC_64:
1115 return copy_to_user(buf, in, sizeof(*in)); 1115 return copy_to_user(buf, in, sizeof(*in));
1116 case IPC_OLD: 1116 case IPC_OLD:
@@ -1153,7 +1153,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid,
1153 int err; 1153 int err;
1154 struct sem_array *sma; 1154 struct sem_array *sma;
1155 1155
1156 switch(cmd) { 1156 switch (cmd) {
1157 case IPC_INFO: 1157 case IPC_INFO:
1158 case SEM_INFO: 1158 case SEM_INFO:
1159 { 1159 {
@@ -1164,7 +1164,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid,
1164 if (err) 1164 if (err)
1165 return err; 1165 return err;
1166 1166
1167 memset(&seminfo,0,sizeof(seminfo)); 1167 memset(&seminfo, 0, sizeof(seminfo));
1168 seminfo.semmni = ns->sc_semmni; 1168 seminfo.semmni = ns->sc_semmni;
1169 seminfo.semmns = ns->sc_semmns; 1169 seminfo.semmns = ns->sc_semmns;
1170 seminfo.semmsl = ns->sc_semmsl; 1170 seminfo.semmsl = ns->sc_semmsl;
@@ -1185,7 +1185,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid,
1185 up_read(&sem_ids(ns).rwsem); 1185 up_read(&sem_ids(ns).rwsem);
1186 if (copy_to_user(p, &seminfo, sizeof(struct seminfo))) 1186 if (copy_to_user(p, &seminfo, sizeof(struct seminfo)))
1187 return -EFAULT; 1187 return -EFAULT;
1188 return (max_id < 0) ? 0: max_id; 1188 return (max_id < 0) ? 0 : max_id;
1189 } 1189 }
1190 case IPC_STAT: 1190 case IPC_STAT:
1191 case SEM_STAT: 1191 case SEM_STAT:
@@ -1241,7 +1241,7 @@ static int semctl_setval(struct ipc_namespace *ns, int semid, int semnum,
1241{ 1241{
1242 struct sem_undo *un; 1242 struct sem_undo *un;
1243 struct sem_array *sma; 1243 struct sem_array *sma;
1244 struct sem* curr; 1244 struct sem *curr;
1245 int err; 1245 int err;
1246 struct list_head tasks; 1246 struct list_head tasks;
1247 int val; 1247 int val;
@@ -1311,10 +1311,10 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
1311 int cmd, void __user *p) 1311 int cmd, void __user *p)
1312{ 1312{
1313 struct sem_array *sma; 1313 struct sem_array *sma;
1314 struct sem* curr; 1314 struct sem *curr;
1315 int err, nsems; 1315 int err, nsems;
1316 ushort fast_sem_io[SEMMSL_FAST]; 1316 ushort fast_sem_io[SEMMSL_FAST];
1317 ushort* sem_io = fast_sem_io; 1317 ushort *sem_io = fast_sem_io;
1318 struct list_head tasks; 1318 struct list_head tasks;
1319 1319
1320 INIT_LIST_HEAD(&tasks); 1320 INIT_LIST_HEAD(&tasks);
@@ -1348,7 +1348,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
1348 err = -EIDRM; 1348 err = -EIDRM;
1349 goto out_unlock; 1349 goto out_unlock;
1350 } 1350 }
1351 if(nsems > SEMMSL_FAST) { 1351 if (nsems > SEMMSL_FAST) {
1352 if (!ipc_rcu_getref(sma)) { 1352 if (!ipc_rcu_getref(sma)) {
1353 err = -EIDRM; 1353 err = -EIDRM;
1354 goto out_unlock; 1354 goto out_unlock;
@@ -1356,7 +1356,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
1356 sem_unlock(sma, -1); 1356 sem_unlock(sma, -1);
1357 rcu_read_unlock(); 1357 rcu_read_unlock();
1358 sem_io = ipc_alloc(sizeof(ushort)*nsems); 1358 sem_io = ipc_alloc(sizeof(ushort)*nsems);
1359 if(sem_io == NULL) { 1359 if (sem_io == NULL) {
1360 ipc_rcu_putref(sma, ipc_rcu_free); 1360 ipc_rcu_putref(sma, ipc_rcu_free);
1361 return -ENOMEM; 1361 return -ENOMEM;
1362 } 1362 }
@@ -1373,7 +1373,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
1373 sem_unlock(sma, -1); 1373 sem_unlock(sma, -1);
1374 rcu_read_unlock(); 1374 rcu_read_unlock();
1375 err = 0; 1375 err = 0;
1376 if(copy_to_user(array, sem_io, nsems*sizeof(ushort))) 1376 if (copy_to_user(array, sem_io, nsems*sizeof(ushort)))
1377 err = -EFAULT; 1377 err = -EFAULT;
1378 goto out_free; 1378 goto out_free;
1379 } 1379 }
@@ -1388,15 +1388,15 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
1388 } 1388 }
1389 rcu_read_unlock(); 1389 rcu_read_unlock();
1390 1390
1391 if(nsems > SEMMSL_FAST) { 1391 if (nsems > SEMMSL_FAST) {
1392 sem_io = ipc_alloc(sizeof(ushort)*nsems); 1392 sem_io = ipc_alloc(sizeof(ushort)*nsems);
1393 if(sem_io == NULL) { 1393 if (sem_io == NULL) {
1394 ipc_rcu_putref(sma, ipc_rcu_free); 1394 ipc_rcu_putref(sma, ipc_rcu_free);
1395 return -ENOMEM; 1395 return -ENOMEM;
1396 } 1396 }
1397 } 1397 }
1398 1398
1399 if (copy_from_user (sem_io, p, nsems*sizeof(ushort))) { 1399 if (copy_from_user(sem_io, p, nsems*sizeof(ushort))) {
1400 ipc_rcu_putref(sma, ipc_rcu_free); 1400 ipc_rcu_putref(sma, ipc_rcu_free);
1401 err = -EFAULT; 1401 err = -EFAULT;
1402 goto out_free; 1402 goto out_free;
@@ -1451,10 +1451,10 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
1451 err = curr->sempid; 1451 err = curr->sempid;
1452 goto out_unlock; 1452 goto out_unlock;
1453 case GETNCNT: 1453 case GETNCNT:
1454 err = count_semncnt(sma,semnum); 1454 err = count_semncnt(sma, semnum);
1455 goto out_unlock; 1455 goto out_unlock;
1456 case GETZCNT: 1456 case GETZCNT:
1457 err = count_semzcnt(sma,semnum); 1457 err = count_semzcnt(sma, semnum);
1458 goto out_unlock; 1458 goto out_unlock;
1459 } 1459 }
1460 1460
@@ -1464,7 +1464,7 @@ out_rcu_wakeup:
1464 rcu_read_unlock(); 1464 rcu_read_unlock();
1465 wake_up_sem_queue_do(&tasks); 1465 wake_up_sem_queue_do(&tasks);
1466out_free: 1466out_free:
1467 if(sem_io != fast_sem_io) 1467 if (sem_io != fast_sem_io)
1468 ipc_free(sem_io, sizeof(ushort)*nsems); 1468 ipc_free(sem_io, sizeof(ushort)*nsems);
1469 return err; 1469 return err;
1470} 1470}
@@ -1472,7 +1472,7 @@ out_free:
1472static inline unsigned long 1472static inline unsigned long
1473copy_semid_from_user(struct semid64_ds *out, void __user *buf, int version) 1473copy_semid_from_user(struct semid64_ds *out, void __user *buf, int version)
1474{ 1474{
1475 switch(version) { 1475 switch (version) {
1476 case IPC_64: 1476 case IPC_64:
1477 if (copy_from_user(out, buf, sizeof(*out))) 1477 if (copy_from_user(out, buf, sizeof(*out)))
1478 return -EFAULT; 1478 return -EFAULT;
@@ -1481,7 +1481,7 @@ copy_semid_from_user(struct semid64_ds *out, void __user *buf, int version)
1481 { 1481 {
1482 struct semid_ds tbuf_old; 1482 struct semid_ds tbuf_old;
1483 1483
1484 if(copy_from_user(&tbuf_old, buf, sizeof(tbuf_old))) 1484 if (copy_from_user(&tbuf_old, buf, sizeof(tbuf_old)))
1485 return -EFAULT; 1485 return -EFAULT;
1486 1486
1487 out->sem_perm.uid = tbuf_old.sem_perm.uid; 1487 out->sem_perm.uid = tbuf_old.sem_perm.uid;
@@ -1508,7 +1508,7 @@ static int semctl_down(struct ipc_namespace *ns, int semid,
1508 struct semid64_ds semid64; 1508 struct semid64_ds semid64;
1509 struct kern_ipc_perm *ipcp; 1509 struct kern_ipc_perm *ipcp;
1510 1510
1511 if(cmd == IPC_SET) { 1511 if (cmd == IPC_SET) {
1512 if (copy_semid_from_user(&semid64, p, version)) 1512 if (copy_semid_from_user(&semid64, p, version))
1513 return -EFAULT; 1513 return -EFAULT;
1514 } 1514 }
@@ -1568,7 +1568,7 @@ SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, unsigned long, arg)
1568 version = ipc_parse_version(&cmd); 1568 version = ipc_parse_version(&cmd);
1569 ns = current->nsproxy->ipc_ns; 1569 ns = current->nsproxy->ipc_ns;
1570 1570
1571 switch(cmd) { 1571 switch (cmd) {
1572 case IPC_INFO: 1572 case IPC_INFO:
1573 case SEM_INFO: 1573 case SEM_INFO:
1574 case IPC_STAT: 1574 case IPC_STAT:
@@ -1636,7 +1636,7 @@ static struct sem_undo *lookup_undo(struct sem_undo_list *ulp, int semid)
1636{ 1636{
1637 struct sem_undo *un; 1637 struct sem_undo *un;
1638 1638
1639 assert_spin_locked(&ulp->lock); 1639 assert_spin_locked(&ulp->lock);
1640 1640
1641 un = __lookup_undo(ulp, semid); 1641 un = __lookup_undo(ulp, semid);
1642 if (un) { 1642 if (un) {
@@ -1672,7 +1672,7 @@ static struct sem_undo *find_alloc_undo(struct ipc_namespace *ns, int semid)
1672 spin_lock(&ulp->lock); 1672 spin_lock(&ulp->lock);
1673 un = lookup_undo(ulp, semid); 1673 un = lookup_undo(ulp, semid);
1674 spin_unlock(&ulp->lock); 1674 spin_unlock(&ulp->lock);
1675 if (likely(un!=NULL)) 1675 if (likely(un != NULL))
1676 goto out; 1676 goto out;
1677 1677
1678 /* no undo structure around - allocate one. */ 1678 /* no undo structure around - allocate one. */
@@ -1767,7 +1767,7 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
1767 int error = -EINVAL; 1767 int error = -EINVAL;
1768 struct sem_array *sma; 1768 struct sem_array *sma;
1769 struct sembuf fast_sops[SEMOPM_FAST]; 1769 struct sembuf fast_sops[SEMOPM_FAST];
1770 struct sembuf* sops = fast_sops, *sop; 1770 struct sembuf *sops = fast_sops, *sop;
1771 struct sem_undo *un; 1771 struct sem_undo *un;
1772 int undos = 0, alter = 0, max, locknum; 1772 int undos = 0, alter = 0, max, locknum;
1773 struct sem_queue queue; 1773 struct sem_queue queue;
@@ -1781,13 +1781,13 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
1781 return -EINVAL; 1781 return -EINVAL;
1782 if (nsops > ns->sc_semopm) 1782 if (nsops > ns->sc_semopm)
1783 return -E2BIG; 1783 return -E2BIG;
1784 if(nsops > SEMOPM_FAST) { 1784 if (nsops > SEMOPM_FAST) {
1785 sops = kmalloc(sizeof(*sops)*nsops,GFP_KERNEL); 1785 sops = kmalloc(sizeof(*sops)*nsops, GFP_KERNEL);
1786 if(sops==NULL) 1786 if (sops == NULL)
1787 return -ENOMEM; 1787 return -ENOMEM;
1788 } 1788 }
1789 if (copy_from_user (sops, tsops, nsops * sizeof(*tsops))) { 1789 if (copy_from_user(sops, tsops, nsops * sizeof(*tsops))) {
1790 error=-EFAULT; 1790 error = -EFAULT;
1791 goto out_free; 1791 goto out_free;
1792 } 1792 }
1793 if (timeout) { 1793 if (timeout) {
@@ -1994,7 +1994,7 @@ out_rcu_wakeup:
1994 rcu_read_unlock(); 1994 rcu_read_unlock();
1995 wake_up_sem_queue_do(&tasks); 1995 wake_up_sem_queue_do(&tasks);
1996out_free: 1996out_free:
1997 if(sops != fast_sops) 1997 if (sops != fast_sops)
1998 kfree(sops); 1998 kfree(sops);
1999 return error; 1999 return error;
2000} 2000}
@@ -2103,7 +2103,7 @@ void exit_sem(struct task_struct *tsk)
2103 2103
2104 /* perform adjustments registered in un */ 2104 /* perform adjustments registered in un */
2105 for (i = 0; i < sma->sem_nsems; i++) { 2105 for (i = 0; i < sma->sem_nsems; i++) {
2106 struct sem * semaphore = &sma->sem_base[i]; 2106 struct sem *semaphore = &sma->sem_base[i];
2107 if (un->semadj[i]) { 2107 if (un->semadj[i]) {
2108 semaphore->semval += un->semadj[i]; 2108 semaphore->semval += un->semadj[i];
2109 /* 2109 /*
@@ -2117,7 +2117,7 @@ void exit_sem(struct task_struct *tsk)
2117 * Linux caps the semaphore value, both at 0 2117 * Linux caps the semaphore value, both at 0
2118 * and at SEMVMX. 2118 * and at SEMVMX.
2119 * 2119 *
2120 * Manfred <manfred@colorfullife.com> 2120 * Manfred <manfred@colorfullife.com>
2121 */ 2121 */
2122 if (semaphore->semval < 0) 2122 if (semaphore->semval < 0)
2123 semaphore->semval = 0; 2123 semaphore->semval = 0;