aboutsummaryrefslogtreecommitdiffstats
path: root/main/libc0.9.32/0001-libc-add-posix_fallocate.patch
blob: 560a94b0b4a2a1fd243d686d4e1cafb2b949f544 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
From 987ccf6ee3cbb4bb6055d9f4c635bdaddf2377fc Mon Sep 17 00:00:00 2001
From: Natanael Copa <ncopa@alpinelinux.org>
Date: Tue, 12 Jun 2012 07:59:16 +0000
Subject: [PATCH] libc: add posix_fallocate

http://www.mail-archive.com/uclibc@uclibc.org/msg08105.html
---
 include/fcntl.h                                  |    4 +-
 libc/sysdeps/linux/common/Makefile.in            |    3 +-
 libc/sysdeps/linux/common/bits/kernel-features.h |    8 ++
 libc/sysdeps/linux/common/posix_fallocate.c      |   43 ++++++++
 libc/sysdeps/linux/common/posix_fallocate64.c    |   39 +++++++
 libc/sysdeps/linux/common/stubs.c                |   16 +++
 test/.gitignore                                  |    1 +
 test/unistd/Makefile.in                          |    3 +
 test/unistd/tst-posix_fallocate.c                |  121 ++++++++++++++++++++++
 9 files changed, 234 insertions(+), 4 deletions(-)
 create mode 100644 libc/sysdeps/linux/common/posix_fallocate.c
 create mode 100644 libc/sysdeps/linux/common/posix_fallocate64.c
 create mode 100644 test/unistd/tst-posix_fallocate.c

diff --git a/include/fcntl.h b/include/fcntl.h
index 26ad1fe..c4a47af 100644
--- a/include/fcntl.h
+++ b/include/fcntl.h
@@ -210,9 +210,7 @@ extern int posix_fadvise64 (int __fd, __off64_t __offset, __off64_t __len,
 
 #endif
 
-#if 0 /* && defined __UCLIBC_HAS_ADVANCED_REALTIME__ */
-
-/* FIXME -- uClibc should probably implement these... */
+#if defined __UCLIBC_HAS_ADVANCED_REALTIME__
 
 /* Reserve storage for the data of the file associated with FD.
 
diff --git a/libc/sysdeps/linux/common/Makefile.in b/libc/sysdeps/linux/common/Makefile.in
index 3b5763c..cddcd74 100644
--- a/libc/sysdeps/linux/common/Makefile.in
+++ b/libc/sysdeps/linux/common/Makefile.in
@@ -81,7 +81,8 @@ CSRC-$(UCLIBC_HAS_REALTIME) += clock_getres.c clock_gettime.c clock_settime.c \
 	sched_get_priority_max.c sched_get_priority_min.c sched_getscheduler.c \
 	sched_rr_get_interval.c sched_setparam.c sched_setscheduler.c sigqueue.c
 # clock_getcpuclockid|clock_nanosleep|mq_timedreceive|mq_timedsend|posix_fadvise|posix_fallocate|posix_madvise|posix_memalign|posix_mem_offset|posix_spawnattr_destroy|posix_spawnattr_init|posix_spawnattr_getflags|posix_spawnattr_setflags|posix_spawnattr_getpgroup|posix_spawnattr_setpgroup|posix_spawnattr_getschedparam|posix_spawnattr_setschedparam|posix_spawnattr_getschedpolicy|posix_spawnattr_setschedpolicy|posix_spawnattr_getsigdefault|posix_spawnattr_setsigdefault|posix_spawnattr_getsigmask|posix_spawnattr_setsigmask|posix_spawnattr_init|posix_spawnattr_setflags|posix_spawnattr_setpgroup|posix_spawnattr_setschedparam|posix_spawnattr_setschedpolicy|posix_spawnattr_setsigdefault|posix_spawnattr_setsigmask|posix_spawn_file_actions_addclose|posix_spawn_file_actions_addopen|posix_spawn_file_actions_adddup2|posix_spawn_file_actions_addopen|posix_spawn_file_actions_destroy|posix_spawn_file_actions_init|posix_spawn_file_actions_init|posix_spawn|posix_spawnp|posix_spawnp|posix_typed_mem_get_info|pthread_mutex_timedlock|sem_timedwait
-CSRC-$(UCLIBC_HAS_ADVANCED_REALTIME) += posix_fadvise64.c posix_fadvise.c
+CSRC-$(UCLIBC_HAS_ADVANCED_REALTIME) += posix_fadvise64.c posix_fadvise.c \
+	posix_fallocate.c posix_fallocate64.c
 CSRC-$(UCLIBC_SUSV4_LEGACY) += utime.c
 CSRC-$(UCLIBC_HAS_EPOLL) += epoll.c
 CSRC-$(UCLIBC_HAS_XATTR) += xattr.c
diff --git a/libc/sysdeps/linux/common/bits/kernel-features.h b/libc/sysdeps/linux/common/bits/kernel-features.h
index 5ea85d2..be00dda 100644
--- a/libc/sysdeps/linux/common/bits/kernel-features.h
+++ b/libc/sysdeps/linux/common/bits/kernel-features.h
@@ -494,6 +494,14 @@
 # define __ASSUME_PRIVATE_FUTEX	1
 #endif
 
+/* Support for fallocate was added in 2.6.23,
+   on s390 only after 2.6.23-rc1, on alpha only after 2.6.33-rc1.  */
+#if __LINUX_KERNEL_VERSION >= 0x020617 \
+    && (!defined __s390__ || __LINUX_KERNEL_VERSION >= 0x020618) \
+    && (!defined __alpha__ || __LINUX_KERNEL_VERSION >= 0x020621)
+# define __ASSUME_FALLOCATE 1
+#endif
+
 /* getcpu is a syscall for x86-64 since 3.1.  */
 #if defined __x86_64__ && __LINUX_KERNEL_VERSION >= 0x030100
 # define __ASSUME_GETCPU_SYSCALL        1
diff --git a/libc/sysdeps/linux/common/posix_fallocate.c b/libc/sysdeps/linux/common/posix_fallocate.c
new file mode 100644
index 0000000..9aaa6ce
--- /dev/null
+++ b/libc/sysdeps/linux/common/posix_fallocate.c
@@ -0,0 +1,43 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * posix_fallocate() for uClibc
+ * http://www.opengroup.org/onlinepubs/9699919799/functions/posix_fallocate.html
+ *
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <fcntl.h>
+#include <bits/kernel-features.h>
+#include <stdint.h>
+
+#if defined __NR_fallocate
+int posix_fallocate(int fd, __off_t offset, __off_t len)
+{
+	int ret;
+
+# if __WORDSIZE == 32
+	uint32_t off_low = offset;
+	uint32_t len_low = len;
+	/* may assert that these >>31 are 0 */
+	uint32_t zero = 0;
+	INTERNAL_SYSCALL_DECL(err);
+	ret = (int) (INTERNAL_SYSCALL(fallocate, err, 6, fd, 0,
+		__LONG_LONG_PAIR (zero, off_low),
+		__LONG_LONG_PAIR (zero, len_low)));
+# elif __WORDSIZE == 64
+	INTERNAL_SYSCALL_DECL(err);
+	ret = (int) (INTERNAL_SYSCALL(fallocate, err, 4, fd, 0, offset, len));
+# else
+# error your machine is neither 32 bit or 64 bit ... it must be magical
+#endif
+    if (unlikely(INTERNAL_SYSCALL_ERROR_P (ret, err)))
+      return INTERNAL_SYSCALL_ERRNO (ret, err);
+    return 0;
+}
+# if defined __UCLIBC_HAS_LFS__ && __WORDSIZE == 64
+strong_alias(posix_fallocate,posix_fallocate64)
+# endif
+#endif
diff --git a/libc/sysdeps/linux/common/posix_fallocate64.c b/libc/sysdeps/linux/common/posix_fallocate64.c
new file mode 100644
index 0000000..818d868
--- /dev/null
+++ b/libc/sysdeps/linux/common/posix_fallocate64.c
@@ -0,0 +1,39 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * posix_fallocate() for uClibc
+ * http://www.opengroup.org/onlinepubs/9699919799/functions/posix_fallocate.html
+ *
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <fcntl.h>
+#include <bits/kernel-features.h>
+#include <stdint.h>
+
+#if defined __NR_fallocate
+
+# if __WORDSIZE == 64
+/* Can use normal posix_fallocate() */
+# elif __WORDSIZE == 32
+int posix_fallocate64(int fd, __off64_t offset, __off64_t len)
+{
+	int ret;
+	uint32_t off_low = offset & 0xffffffff;
+	uint32_t off_high = offset >> 32;
+	uint32_t len_low = len & 0xffffffff;
+	uint32_t len_high = len >> 32;
+	INTERNAL_SYSCALL_DECL(err);
+	ret = (int) (INTERNAL_SYSCALL(fallocate, err, 6, fd, 0,
+		__LONG_LONG_PAIR (off_high, off_low),
+		__LONG_LONG_PAIR (len_high, len_low)));
+    if (unlikely(INTERNAL_SYSCALL_ERROR_P (ret, err)))
+      return INTERNAL_SYSCALL_ERRNO (ret, err);
+    return 0;
+}
+# else
+# error your machine is neither 32 bit or 64 bit ... it must be magical
+# endif
+#endif
diff --git a/libc/sysdeps/linux/common/stubs.c b/libc/sysdeps/linux/common/stubs.c
index 4d1e26c..43d8081 100644
--- a/libc/sysdeps/linux/common/stubs.c
+++ b/libc/sysdeps/linux/common/stubs.c
@@ -225,6 +225,22 @@ make_stub(pipe2)
 make_stub(pivot_root)
 #endif
 
+#if !defined __NR_fadvise64 && defined __UCLIBC_HAS_LFS__
+make_ret_stub(posix_fadvise)
+#endif
+
+#if !defined __NR_fadvise64_64 && defined __UCLIBC_HAS_LFS__ && __WORDSIZE == 32
+make_ret_stub(posix_fadvise64)
+#endif
+
+#if !defined __NR_fallocate && defined __UCLIBC_HAS_ADVANCED_REALTIME__
+make_ret_stub(posix_fallocate)
+#endif
+
+#ifndef __NR_madvise
+make_ret_stub(posix_madvise)
+#endif
+
 #if !defined __NR_ppoll && defined __UCLIBC_LINUX_SPECIFIC__
 make_stub(ppoll)
 #endif
diff --git a/test/.gitignore b/test/.gitignore
index c892816..14cb5d6 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -302,6 +302,7 @@ unistd/getcwd
 unistd/getopt
 unistd/getopt_long
 unistd/tstgetopt
+unistd/tst-posix_fallocate
 unistd/tst-preadwrite
 unistd/tst-preadwrite64
 unistd/vfork
diff --git a/test/unistd/Makefile.in b/test/unistd/Makefile.in
index c542f98..6583e42 100644
--- a/test/unistd/Makefile.in
+++ b/test/unistd/Makefile.in
@@ -4,6 +4,9 @@
 ifeq ($(UCLIBC_HAS_LFS),)
 TESTS_DISABLED := tst-preadwrite64
 endif
+ifeq ($(UCLIBC_HAS_ADVANCED_REALTIME),)
+TESTS_DISABLED := tst-posix_fallocate
+endif
 OPTS_getopt      := -abcXXX -9
 OPTS_getopt_long := --add XXX --delete YYY --verbose
 ifeq ($(UCLIBC_HAS_GNU_GETOPT),y)
diff --git a/test/unistd/tst-posix_fallocate.c b/test/unistd/tst-posix_fallocate.c
new file mode 100644
index 0000000..eec50ea
--- /dev/null
+++ b/test/unistd/tst-posix_fallocate.c
@@ -0,0 +1,121 @@
+#include <fcntl.h>
+#include <sys/stat.h>
+
+static void do_prepare (void);
+#define PREPARE(argc, argv) do_prepare ()
+static int do_test (void);
+#define TEST_FUNCTION do_test ()
+#include <test-skeleton.c>
+
+static int fd;
+#ifndef O_LARGEFILE
+# error no O_LARGEFILE
+#endif
+static void
+do_prepare (void)
+{
+  fd = create_temp_file ("tst-posix_fallocate.", NULL);
+  if (fd == -1)
+    {
+      printf ("cannot create temporary file: %m\n");
+      exit (1);
+    }
+}
+
+
+static int
+do_test (void)
+{
+  struct stat64 st;
+
+  if (fstat64 (fd, &st) != 0)
+    {
+      puts ("1st fstat failed");
+      return 1;
+    }
+
+  if (st.st_size != 0)
+    {
+      puts ("file not created with size 0");
+      return 1;
+    }
+
+  if (posix_fallocate (fd, 512, 768) != 0)
+    {
+      puts ("1st posix_fallocate call failed");
+      return 1;
+    }
+
+  if (fstat64 (fd, &st) != 0)
+    {
+      puts ("2nd fstat failed");
+      return 1;
+    }
+
+  if (st.st_size != 512 + 768)
+    {
+      printf ("file size after 1st posix_fallocate call is %llu, expected %u\n",
+	      (unsigned long long int) st.st_size, 512u + 768u);
+      return 1;
+    }
+
+  if (posix_fallocate (fd, 0, 1024) != 0)
+    {
+      puts ("2nd posix_fallocate call failed");
+      return 1;
+    }
+
+  if (fstat64 (fd, &st) != 0)
+    {
+      puts ("3rd fstat failed");
+      return 1;
+    }
+
+  if (st.st_size != 512 + 768)
+    {
+      puts ("file size changed in 2nd posix_fallocate");
+      return 1;
+    }
+
+  if (posix_fallocate (fd, 2048, 64) != 0)
+    {
+      puts ("3rd posix_fallocate call failed");
+      return 1;
+    }
+
+  if (fstat64 (fd, &st) != 0)
+    {
+      puts ("4th fstat failed");
+      return 1;
+    }
+
+  if (st.st_size != 2048 + 64)
+    {
+      printf ("file size after 3rd posix_fallocate call is %llu, expected %u\n",
+	      (unsigned long long int) st.st_size, 2048u + 64u);
+      return 1;
+    }
+
+  if (posix_fallocate64 (fd, 4097ULL, 4294967295ULL + 2ULL) != 0)
+    {
+      puts ("4th posix_fallocate call failed");
+      return 1;
+    }
+
+  if (fstat64 (fd, &st) != 0)
+    {
+      puts ("5th fstat failed");
+      return 1;
+    }
+
+  if (st.st_size != 4097ULL + 4294967295ULL + 2ULL)
+    {
+      printf ("file size after 4th posix_fallocate call is %llu, expected %u\n",
+	      (unsigned long long int) st.st_size, 4097ULL + 4294967295ULL + 2ULL);
+      return 1;
+    }
+
+  close (fd);
+
+  return 0;
+}
-- 
1.7.10.3