X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=ipc%2Fsem.c;h=642659cd596b82f5aa3974e61925708cdc62f9dd;hb=f360ce3be466d50de153b001b24561ca7593042b;hp=19af028a3e380d251d31e4b8ec4cd96ee679a1cb;hpb=0d9136fdbcdbddcd4eb5ac94c248c039193d4795;p=linux-2.6-omap-h63xx.git diff --git a/ipc/sem.c b/ipc/sem.c index 19af028a3e3..642659cd596 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -56,7 +56,7 @@ * /proc/sysvipc/sem support (c) 1999 Dragos Acostachioaie * * SMP-threaded, sysctl's added - * (c) 1999 Manfred Spraul + * (c) 1999 Manfred Spraul * Enforced range limit on SEM_UNDO * (c) 2001 Red Hat Inc * Lockless wakeup @@ -73,7 +73,10 @@ #include #include #include +#include #include +#include + #include #include "util.h" @@ -138,7 +141,7 @@ void __init sem_init (void) * * if it's IN_WAKEUP, then it must wait until the value changes * * if it's not -EINTR, then the operation was completed by * update_queue. semtimedop can return queue.status without - * performing any operation on the semaphore array. + * performing any operation on the sem array. * * otherwise it must acquire the spinlock and check what's up. * * The two-stage algorithm is necessary to protect against the following @@ -213,7 +216,7 @@ asmlinkage long sys_semget (key_t key, int nsems, int semflg) if (nsems < 0 || nsems > sc_semmsl) return -EINVAL; - down(&sem_ids.sem); + mutex_lock(&sem_ids.mutex); if (key == IPC_PRIVATE) { err = newary(key, nsems, semflg); @@ -226,8 +229,7 @@ asmlinkage long sys_semget (key_t key, int nsems, int semflg) err = -EEXIST; } else { sma = sem_lock(id); - if(sma==NULL) - BUG(); + BUG_ON(sma==NULL); if (nsems > sma->sem_nsems) err = -EINVAL; else if (ipcperms(&sma->sem_perm, semflg)) @@ -241,7 +243,7 @@ asmlinkage long sys_semget (key_t key, int nsems, int semflg) sem_unlock(sma); } - up(&sem_ids.sem); + mutex_unlock(&sem_ids.mutex); return err; } @@ -381,6 +383,7 @@ static void update_queue (struct sem_array * sma) /* hands-off: q will disappear immediately after * writing q->status. */ + smp_wmb(); q->status = error; q = n; } else { @@ -435,8 +438,8 @@ static int count_semzcnt (struct sem_array * sma, ushort semnum) return semzcnt; } -/* Free a semaphore set. freeary() is called with sem_ids.sem down and - * the spinlock for this semaphore set hold. sem_ids.sem remains locked +/* Free a semaphore set. freeary() is called with sem_ids.mutex locked and + * the spinlock for this semaphore set hold. sem_ids.mutex remains locked * on exit. */ static void freeary (struct sem_array *sma, int id) @@ -461,6 +464,7 @@ static void freeary (struct sem_array *sma, int id) n = q->next; q->status = IN_WAKEUP; wake_up_process(q->sleeper); /* doesn't sleep */ + smp_wmb(); q->status = -EIDRM; /* hands-off q */ q = n; } @@ -522,7 +526,7 @@ static int semctl_nolock(int semid, int semnum, int cmd, int version, union semu seminfo.semmnu = SEMMNU; seminfo.semmap = SEMMAP; seminfo.semume = SEMUME; - down(&sem_ids.sem); + mutex_lock(&sem_ids.mutex); if (cmd == SEM_INFO) { seminfo.semusz = sem_ids.in_use; seminfo.semaem = used_sems; @@ -531,7 +535,7 @@ static int semctl_nolock(int semid, int semnum, int cmd, int version, union semu seminfo.semaem = SEMAEM; } max_id = sem_ids.max_id; - up(&sem_ids.sem); + mutex_unlock(&sem_ids.mutex); if (copy_to_user (arg.__buf, &seminfo, sizeof(struct seminfo))) return -EFAULT; return (max_id < 0) ? 0: max_id; @@ -806,8 +810,6 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun if(cmd == IPC_SET) { if(copy_semid_from_user (&setbuf, arg.buf, version)) return -EFAULT; - if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode))) - return err; } sma = sem_lock(semid); if(sma==NULL) @@ -818,7 +820,6 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun goto out_unlock; } ipcp = &sma->sem_perm; - if (current->euid != ipcp->cuid && current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) { err=-EPERM; @@ -835,6 +836,8 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun err = 0; break; case IPC_SET: + if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode, ipcp))) + goto out_unlock; ipcp->uid = setbuf.uid; ipcp->gid = setbuf.gid; ipcp->mode = (ipcp->mode & ~S_IRWXUGO) @@ -883,9 +886,9 @@ asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg) return err; case IPC_RMID: case IPC_SET: - down(&sem_ids.sem); + mutex_lock(&sem_ids.mutex); err = semctl_down(semid,semnum,cmd,version,arg); - up(&sem_ids.sem); + mutex_unlock(&sem_ids.mutex); return err; default: return -EINVAL; @@ -1179,8 +1182,7 @@ retry_undos: sma = sem_lock(semid); if(sma==NULL) { - if(queue.prev != NULL) - BUG(); + BUG_ON(queue.prev != NULL); error = -EIDRM; goto out_free; } @@ -1297,9 +1299,9 @@ found: /* perform adjustments registered in u */ nsems = sma->sem_nsems; for (i = 0; i < nsems; i++) { - struct sem * sem = &sma->sem_base[i]; + struct sem * semaphore = &sma->sem_base[i]; if (u->semadj[i]) { - sem->semval += u->semadj[i]; + semaphore->semval += u->semadj[i]; /* * Range checks of the new semaphore value, * not defined by sus: @@ -1313,11 +1315,11 @@ found: * * Manfred */ - if (sem->semval < 0) - sem->semval = 0; - if (sem->semval > SEMVMX) - sem->semval = SEMVMX; - sem->sempid = current->tgid; + if (semaphore->semval < 0) + semaphore->semval = 0; + if (semaphore->semval > SEMVMX) + semaphore->semval = SEMVMX; + semaphore->sempid = current->tgid; } } sma->sem_otime = get_seconds();