]> git.apps.os.sepia.ceph.com Git - xfstests-dev.git/commitdiff
t_ofd_locks: fix sem initialization sequence
authorStas Sergeev <stsp2@yandex.ru>
Tue, 1 Aug 2023 17:52:20 +0000 (22:52 +0500)
committerZorro Lang <zlang@kernel.org>
Fri, 18 Aug 2023 18:44:54 +0000 (02:44 +0800)
The locker was waiting for sem_otime on sem0 to became non-zero after
incrementing sem0 himself. So sem_otime was never 0 at the time of
checking it, so the check was redundant/wrong.

This patch:
- moves the increment of sem1 to the lock-tester site
- lock-setter waits for that sem1 event, for which this patch replaces
  the wait loop on sem_otime with GETVAL loop, adding a small sleep
- increment of sem0 to 2 moved past that sem1 event. That sem0 event
  is currently not used/waited.

This guarantees that the lock-setter is working only after lock-getter
is fully initialized.

CC: fstests@vger.kernel.org
CC: Murphy Zhou <xzhou@redhat.com>
CC: Jeff Layton <jlayton@kernel.org>
CC: Zorro Lang <zlang@redhat.com>
Signed-off-by: Stas Sergeev <stsp2@yandex.ru>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Zorro Lang <zlang@kernel.org>
src/t_ofd_locks.c

index 88ef2690b8ca98c36bcee92855e519f4b9ad1628..58cb095999c0b0c106ce699ee1aa0d67cb702c8d 100644 (file)
@@ -294,32 +294,29 @@ int main(int argc, char **argv)
                semu.array = vals;
                if (semctl(semid, 2, SETALL, semu) == -1)
                        err_exit("init sem", errno);
-               /* Inc both new sem to 2 */
-               sop.sem_num = 0;
-               sop.sem_op = 1;
-               sop.sem_flg = 0;
-               ts.tv_sec = 5;
-               ts.tv_nsec = 0;
-               if (semtimedop(semid, &sop, 1, &ts) == -1)
-                       err_exit("inc sem0 2", errno);
-               sop.sem_num = 1;
-               sop.sem_op = 1;
-               sop.sem_flg = 0;
-               ts.tv_sec = 5;
-               ts.tv_nsec = 0;
-               if (semtimedop(semid, &sop, 1, &ts) == -1)
-                       err_exit("inc sem1 2", errno);
 
                /*
-                * Wait initialization complete. semctl(2) only update
-                * sem_ctime, semop(2) will update sem_otime.
+                * Wait initialization complete.
                 */
                ret = -1;
                do {
+                       if (ret != -1)
+                               usleep(100000);
                        memset(&sem_ds, 0, sizeof(sem_ds));
                        semu.buf = &sem_ds;
-                       ret = semctl(semid, 0, IPC_STAT, semu);
-               } while (!(ret == 0 && sem_ds.sem_otime != 0));
+                       ret = semctl(semid, 1, GETVAL, semu);
+                       if (ret == -1)
+                               err_exit("wait sem1 2", errno);
+               } while (ret != 2);
+
+               /* Inc sem0 to 2 */
+               sop.sem_num = 0;
+               sop.sem_op = 1;
+               sop.sem_flg = 0;
+               ts.tv_sec = 5;
+               ts.tv_nsec = 0;
+               if (semtimedop(semid, &sop, 1, &ts) == -1)
+                       err_exit("inc sem0 2", errno);
 
                /* place the lock */
                if (fcntl(fd, setlk_macro, &flk) < 0)
@@ -385,6 +382,15 @@ int main(int argc, char **argv)
                                err_exit("wait sem1 1", errno);
                } while (ret != 1);
 
+               /* inc sem1 to 2 (initialization completed) */
+               sop.sem_num = 1;
+               sop.sem_op = 1;
+               sop.sem_flg = 0;
+               ts.tv_sec = 5;
+               ts.tv_nsec = 0;
+               if (semtimedop(semid, &sop, 1, &ts) == -1)
+                       err_exit("inc sem1 2", errno);
+
                /* wait sem0 == 0 (setlk and close fd done) */
                sop.sem_num = 0;
                sop.sem_op = 0;