From patchwork Wed Jan 15 01:31:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiao Yang X-Patchwork-Id: 37387 Received: (qmail 90593 invoked by alias); 15 Jan 2020 01:36:15 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 90581 invoked by uid 89); 15 Jan 2020 01:36:15 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-20.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3 autolearn=ham version=3.3.1 spammy=HContent-Transfer-Encoding:8bit X-HELO: heian.cn.fujitsu.com From: Xiao Yang To: CC: Xiao Yang Subject: [PATCH v2] sysdeps/posix/posix_fallocate*: Make emulated posix_fallocate() work properly Date: Wed, 15 Jan 2020 09:31:51 +0800 Message-ID: <20200115013151.905-1-yangx.jy@cn.fujitsu.com> MIME-Version: 1.0 X-yoursite-MailScanner-ID: E6CB34CE20C0.AA7B2 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: yangx.jy@cn.fujitsu.com 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 --- 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