IPC/semaphores: consolidate SEM_STAT and IPC_STAT commands
[safe/jmp/linux-2.6] / ipc / sem.c
index 84c701f..7836edb 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -617,8 +617,8 @@ static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in,
        }
 }
 
-static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum,
-               int cmd, int version, union semun arg)
+static int semctl_nolock(struct ipc_namespace *ns, int semid,
+                        int cmd, int version, union semun arg)
 {
        int err = -EINVAL;
        struct sem_array *sma;
@@ -657,14 +657,23 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum,
                        return -EFAULT;
                return (max_id < 0) ? 0: max_id;
        }
+       case IPC_STAT:
        case SEM_STAT:
        {
                struct semid64_ds tbuf;
                int id;
 
-               sma = sem_lock(ns, semid);
-               if (IS_ERR(sma))
-                       return PTR_ERR(sma);
+               if (cmd == SEM_STAT) {
+                       sma = sem_lock(ns, semid);
+                       if (IS_ERR(sma))
+                               return PTR_ERR(sma);
+                       id = sma->sem_perm.id;
+               } else {
+                       sma = sem_lock_check(ns, semid);
+                       if (IS_ERR(sma))
+                               return PTR_ERR(sma);
+                       id = 0;
+               }
 
                err = -EACCES;
                if (ipcperms (&sma->sem_perm, S_IRUGO))
@@ -674,8 +683,6 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum,
                if (err)
                        goto out_unlock;
 
-               id = sma->sem_perm.id;
-
                memset(&tbuf, 0, sizeof(tbuf));
 
                kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm);
@@ -810,19 +817,6 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
                err = 0;
                goto out_unlock;
        }
-       case IPC_STAT:
-       {
-               struct semid64_ds tbuf;
-               memset(&tbuf,0,sizeof(tbuf));
-               kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm);
-               tbuf.sem_otime  = sma->sem_otime;
-               tbuf.sem_ctime  = sma->sem_ctime;
-               tbuf.sem_nsems  = sma->sem_nsems;
-               sem_unlock(sma);
-               if (copy_semid_to_user (arg.buf, &tbuf, version))
-                       return -EFAULT;
-               return 0;
-       }
        /* GETVAL, GETPID, GETNCTN, GETZCNT, SETVAL: fall-through */
        }
        err = -EINVAL;
@@ -989,15 +983,15 @@ asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg)
        switch(cmd) {
        case IPC_INFO:
        case SEM_INFO:
+       case IPC_STAT:
        case SEM_STAT:
-               err = semctl_nolock(ns,semid,semnum,cmd,version,arg);
+               err = semctl_nolock(ns, semid, cmd, version, arg);
                return err;
        case GETALL:
        case GETVAL:
        case GETPID:
        case GETNCNT:
        case GETZCNT:
-       case IPC_STAT:
        case SETVAL:
        case SETALL:
                err = semctl_main(ns,semid,semnum,cmd,version,arg);