ipc/sem: make semctl setting sempid consistent
[linux-2.6-block.git] / ipc / sem.c
index cddd5b5fde514a205ed24a46b7a273643ab62c7c..b3757ea0694be8a993d7e60d6c2fe90c9dbe90dc 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
 /* One semaphore structure for each semaphore in the system. */
 struct sem {
        int     semval;         /* current value */
-       int     sempid;         /* pid of last operation */
+       /*
+        * PID of the process that last modified the semaphore. For
+        * Linux, specifically these are:
+        *  - semop
+        *  - semctl, via SETVAL and SETALL.
+        *  - at task exit when performing undo adjustments (see exit_sem).
+        */
+       int     sempid;
        spinlock_t      lock;   /* spinlock for fine-grained semtimedop */
        struct list_head pending_alter; /* pending single-sop operations */
                                        /* that alter the semaphore */
@@ -1444,8 +1451,10 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
                        goto out_unlock;
                }
 
-               for (i = 0; i < nsems; i++)
+               for (i = 0; i < nsems; i++) {
                        sma->sem_base[i].semval = sem_io[i];
+                       sma->sem_base[i].sempid = task_tgid_vnr(current);
+               }
 
                ipc_assert_locked_object(&sma->sem_perm);
                list_for_each_entry(un, &sma->list_id, list_id) {