This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v2] sysdeps/posix/posix_fallocate*: Make emulated posix_fallocate() work properly


Emulated posix_fallocate() only writes data in one block if block
size is 4096, offset is 4095 and len is 2.  The emulated code should
write data in two blocks in the case because it actually crosses two
blocks.

Signed-off-by: Xiao Yang <yangx.jy@cn.fujitsu.com>
---
 sysdeps/posix/posix_fallocate.c   | 17 +++++++++++++++++
 sysdeps/posix/posix_fallocate64.c | 17 +++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/sysdeps/posix/posix_fallocate.c b/sysdeps/posix/posix_fallocate.c
index e7fccfc1c8..22e5fea091 100644
--- a/sysdeps/posix/posix_fallocate.c
+++ b/sysdeps/posix/posix_fallocate.c
@@ -93,6 +93,23 @@ posix_fallocate (int fd, __off_t offset, __off_t len)
       increment = 4096;
   }
 
+  if (offset % increment + len % increment > increment)
+    {
+      if (offset < st.st_size)
+        {
+          unsigned char b;
+          ssize_t rdsize = __pread (fd, &b, 1, offset);
+          if (rdsize < 0)
+            return errno;
+          if (rdsize == 1 && b != 0)
+            goto next;
+        }
+
+      if (__pwrite (fd, "", 1, offset) != 1)
+        return errno;
+    }
+
+next:
   /* Write a null byte to every block.  This is racy; we currently
      lack a better option.  Compare-and-swap against a file mapping
      might additional local races, but requires interposition of a
diff --git a/sysdeps/posix/posix_fallocate64.c b/sysdeps/posix/posix_fallocate64.c
index f9d4fe5ca3..1c46b186b6 100644
--- a/sysdeps/posix/posix_fallocate64.c
+++ b/sysdeps/posix/posix_fallocate64.c
@@ -93,6 +93,23 @@ __posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len)
       increment = 4096;
   }
 
+  if (offset % increment + len % increment > increment)
+    {
+      if (offset < st.st_size)
+        {
+          unsigned char b;
+          ssize_t rdsize = __libc_pread64 (fd, &b, 1, offset);
+          if (rdsize < 0)
+            return errno;
+          if (rdsize == 1 && b != 0)
+            goto next;
+        }
+
+      if (__libc_pwrite64 (fd, "", 1, offset) != 1)
+        return errno;
+    }
+
+next:
   /* Write a null byte to every block.  This is racy; we currently
      lack a better option.  Compare-and-swap against a file mapping
      might address local races, but requires interposition of a signal
-- 
2.21.0




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]