initial import
[patches.git] / glibc-fdatasync-lockf-cancellation.patch
1 05-06-2007 Mike Frysinger <vapier@gentoo.org>
2
3 * sysdeps/unix/make-syscalls.sh: Document "C" syscall signature.
4 * sysdeps/unix/sysv/linux/syscalls.list (fdatasync): Add "C" to args.
5 * io/lockf.c: Handle pthread cancellation.
6 * nptl/tst-cancel-wrappers.sh: Set C["fdatasync"] and C["lockf"] to 1.
7 * nptl/tst-cancel4.c (tf_fdatasync): New test.
8
9 --- sysdeps/unix/make-syscalls.sh
10 +++ sysdeps/unix/make-syscalls.sh
11 @@ -10,6 +10,7 @@
12 # a: unchecked address (e.g., 1st arg to mmap)
13 # b: non-NULL buffer (e.g., 2nd arg to read; return value from mmap)
14 # B: optionally-NULL buffer (e.g., 4th arg to getsockopt)
15 +# C: pthread cancellation endpoint
16 # f: buffer of 2 ints (e.g., 4th arg to socketpair)
17 # F: 3rd arg to fcntl
18 # i: scalar (any signedness & size: int, long, long long, enum, whatever)
19 --- sysdeps/unix/sysv/linux/syscalls.list
20 +++ sysdeps/unix/sysv/linux/syscalls.list
21 @@ -11,7 +11,7 @@
22 epoll_ctl EXTRA epoll_ctl i:iiip epoll_ctl
23 epoll_wait EXTRA epoll_wait Ci:ipii epoll_wait
24 epoll_pwait EXTRA epoll_pwait Ci:ipiipi epoll_pwait
25 -fdatasync - fdatasync i:i fdatasync
26 +fdatasync - fdatasync Ci:i fdatasync
27 flock - flock i:ii __flock flock
28 fork - fork i: __libc_fork __fork fork
29 get_kernel_syms EXTRA get_kernel_syms i:p get_kernel_syms
30 --- io/lockf.c
31 +++ io/lockf.c
32 @@ -18,6 +18,7 @@
33
34 #include <sys/types.h>
35 #include <unistd.h>
36 +#include <sysdep-cancel.h> /* Must come before <fcntl.h>. */
37 #include <fcntl.h>
38 #include <errno.h>
39 #include <string.h>
40 @@ -68,7 +69,16 @@
41 }
42
43 /* lockf() is a cancellation point but so is fcntl() if F_SETLKW is
44 - used. Therefore we don't have to care about cancellation here,
45 - the fcntl() function will take care of it. */
46 - return __fcntl (fd, cmd, &fl);
47 + used. Therefore we don't have to care about cancellation in that
48 + case as the fcntl() function will take care of it. */
49 + if (SINGLE_THREAD_P || cmd == F_SETLKW)
50 + return __fcntl (fd, cmd, &fl);
51 +
52 + int oldtype = LIBC_CANCEL_ASYNC ();
53 +
54 + int result = __fcntl (fd, cmd, &fl);
55 +
56 + LIBC_CANCEL_RESET (oldtype);
57 +
58 + return result;
59 }
60 --- nptl/tst-cancel-wrappers.sh
61 +++ nptl/tst-cancel-wrappers.sh
62 @@ -26,7 +26,9 @@ C["close"]=1
63 C["connect"]=1
64 C["creat"]=1
65 C["fcntl"]=1
66 +C["fdatasync"]=1
67 C["fsync"]=1
68 +C["lockf"]=1
69 C["msgrcv"]=1
70 C["msgsnd"]=1
71 C["msync"]=1
72 --- nptl/tst-cancel4.c
73 +++ nptl/tst-cancel4.c
74 @@ -1571,6 +1571,47 @@ tf_fsync (void *arg)
75
76
77 static void *
78 +tf_fdatasync (void *arg)
79 +{
80 + if (arg == NULL)
81 + // XXX If somebody can provide a portable test case in which fdatasync()
82 + // blocks we can enable this test to run in both rounds.
83 + abort ();
84 +
85 + tempfd = open ("Makefile", O_RDONLY);
86 + if (tempfd == -1)
87 + {
88 + printf ("%s: cannot open Makefile\n", __FUNCTION__);
89 + exit (1);
90 + }
91 +
92 + int r = pthread_barrier_wait (&b2);
93 + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
94 + {
95 + printf ("%s: barrier_wait failed\n", __FUNCTION__);
96 + exit (1);
97 + }
98 +
99 + r = pthread_barrier_wait (&b2);
100 + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
101 + {
102 + printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
103 + exit (1);
104 + }
105 +
106 + pthread_cleanup_push (cl, NULL);
107 +
108 + fdatasync (tempfd);
109 +
110 + pthread_cleanup_pop (0);
111 +
112 + printf ("%s: fdatasync returned\n", __FUNCTION__);
113 +
114 + exit (1);
115 +}
116 +
117 +
118 +static void *
119 tf_msync (void *arg)
120 {
121 if (arg == NULL)
122 @@ -2078,6 +2119,7 @@ static struct
123 ADD_TEST (pread, 2, 1),
124 ADD_TEST (pwrite, 2, 1),
125 ADD_TEST (fsync, 2, 1),
126 + ADD_TEST (fdatasync, 2, 1),
127 ADD_TEST (msync, 2, 1),
128 ADD_TEST (sendto, 2, 1),
129 ADD_TEST (sendmsg, 2, 1),