aboutsummaryrefslogtreecommitdiffstats
path: root/toolchain/uClibc/patches-0.9.33.2/021-libc-add-posix_fallocate.patch
blob: 504405a716d89b9f8cd39eeda793a92c3842f13b (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
From: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Date: Tue, 17 Apr 2012 09:30:15 +0200
Subject: [PATCH] libc: add posix_fallocate()

Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
---
 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
 create mode 100644 test/unistd/tst-posix_fallocate64.c

--- a/include/fcntl.h
+++ b/include/fcntl.h
@@ -210,9 +210,7 @@ extern int posix_fadvise64 (int __fd, __
 
 #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.
 
--- a/libc/sysdeps/linux/common/Makefile.in
+++ b/libc/sysdeps/linux/common/Makefile.in
@@ -81,7 +81,8 @@ CSRC-$(UCLIBC_HAS_REALTIME) += clock_get
 	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 posix_madvise.c
+CSRC-$(UCLIBC_HAS_ADVANCED_REALTIME) += posix_fadvise64.c posix_fadvise.c posix_madvise.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
--- 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
--- /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
--- /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
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -302,6 +302,8 @@ unistd/getcwd
 unistd/getopt
 unistd/getopt_long
 unistd/tstgetopt
+unistd/tst-posix_fallocate
+unistd/tst-posix_fallocate64
 unistd/tst-preadwrite
 unistd/tst-preadwrite64
 unistd/vfork
--- a/test/unistd/Makefile.in
+++ b/test/unistd/Makefile.in
@@ -2,7 +2,10 @@
 # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
 
 ifeq ($(UCLIBC_HAS_LFS),)
-TESTS_DISABLED := tst-preadwrite64
+TESTS_DISABLED := tst-preadwrite64 tst-posix_fallocate64
+endif
+ifeq ($(UCLIBC_HAS_ADVANCED_REALTIME),)
+TESTS_DISABLED := tst-posix_fallocate
 endif
 OPTS_getopt      := -abcXXX -9
 OPTS_getopt_long := --add XXX --delete YYY --verbose
--- /dev/null
+++ b/test/unistd/tst-posix_fallocate.c
@@ -0,0 +1,127 @@
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#ifndef TST_POSIX_FALLOCATE64
+# define stat64 stat
+# define fstat64 fstat
+# else
+# ifndef O_LARGEFILE
+#  error no O_LARGEFILE but you want to test with LFS enabled
+# endif
+#endif
+
+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;
+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;
+    }
+#ifdef TST_POSIX_FALLOCATE64
+  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 %llu\n",
+	      (unsigned long long int) st.st_size, 4097ULL + 4294967295ULL + 2ULL);
+      return 1;
+    }
+#endif
+  close (fd);
+
+  return 0;
+}
--- /dev/null
+++ b/test/unistd/tst-posix_fallocate64.c
@@ -0,0 +1,2 @@
+#define TST_POSIX_FALLOCATE64
+#include "tst-posix_fallocate.c"