Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
[deliverable/linux.git] / ipc / sem.c
index f2151babd26a7688ccc638b7a4dd35dd6022e5bb..a7e40ed8a07674fd0493c1495a012a09759d835b 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -796,6 +796,13 @@ static int count_semncnt (struct sem_array * sma, ushort semnum)
        struct sem_queue * q;
 
        semncnt = 0;
+       list_for_each_entry(q, &sma->sem_base[semnum].sem_pending, list) {
+               struct sembuf * sops = q->sops;
+               BUG_ON(sops->sem_num != semnum);
+               if ((sops->sem_op < 0) && !(sops->sem_flg & IPC_NOWAIT))
+                       semncnt++;
+       }
+
        list_for_each_entry(q, &sma->sem_pending, list) {
                struct sembuf * sops = q->sops;
                int nsops = q->nsops;
@@ -815,6 +822,13 @@ static int count_semzcnt (struct sem_array * sma, ushort semnum)
        struct sem_queue * q;
 
        semzcnt = 0;
+       list_for_each_entry(q, &sma->sem_base[semnum].sem_pending, list) {
+               struct sembuf * sops = q->sops;
+               BUG_ON(sops->sem_num != semnum);
+               if ((sops->sem_op == 0) && !(sops->sem_flg & IPC_NOWAIT))
+                       semzcnt++;
+       }
+
        list_for_each_entry(q, &sma->sem_pending, list) {
                struct sembuf * sops = q->sops;
                int nsops = q->nsops;
@@ -948,8 +962,8 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid,
 
                memset(&tbuf, 0, sizeof(tbuf));
 
+               rcu_read_lock();
                if (cmd == SEM_STAT) {
-                       rcu_read_lock();
                        sma = sem_obtain_object(ns, semid);
                        if (IS_ERR(sma)) {
                                err = PTR_ERR(sma);
@@ -957,7 +971,6 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid,
                        }
                        id = sma->sem_perm.id;
                } else {
-                       rcu_read_lock();
                        sma = sem_obtain_object_check(ns, semid);
                        if (IS_ERR(sma)) {
                                err = PTR_ERR(sma);
This page took 0.031693 seconds and 5 git commands to generate.