From patchwork Sat May 9 16:43:05 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anthony Basile X-Patchwork-Id: 470334 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from fraxinus.osuosl.org (fraxinus.osuosl.org [140.211.166.137]) by ozlabs.org (Postfix) with ESMTP id 8ECB11402D2 for ; Sun, 10 May 2015 02:52:14 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 2FB6FA27B4; Sat, 9 May 2015 16:52:12 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 1mnjH2K2c5MA; Sat, 9 May 2015 16:52:11 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by fraxinus.osuosl.org (Postfix) with ESMTP id 2CCD5A27A9; Sat, 9 May 2015 16:52:11 +0000 (UTC) X-Original-To: uclibc@lists.busybox.net Delivered-To: uclibc@osuosl.org Received: from fraxinus.osuosl.org (fraxinus.osuosl.org [140.211.166.137]) by ash.osuosl.org (Postfix) with ESMTP id B13ED1C1525 for ; Sat, 9 May 2015 16:52:10 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id ACD23A27A9 for ; Sat, 9 May 2015 16:52:10 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5HN4H3tSXPxP for ; Sat, 9 May 2015 16:52:09 +0000 (UTC) X-Greylist: delayed 00:05:44 by SQLgrey-1.7.6 Received: from virtual.dyc.edu (mail.virtual.dyc.edu [67.222.116.22]) by fraxinus.osuosl.org (Postfix) with ESMTP id C5C97A2794 for ; Sat, 9 May 2015 16:52:09 +0000 (UTC) Received: from opensource.dyc.edu (unknown [67.222.116.23]) by virtual.dyc.edu (Postfix) with ESMTP id BC9C77E0216; Sat, 9 May 2015 12:46:20 -0400 (EDT) Received: by opensource.dyc.edu (Postfix, from userid 1001) id EF3AB2B00DE1; Sat, 9 May 2015 12:43:13 -0400 (EDT) From: "Anthony G. Basile" To: uclibc@uclibc.org Subject: [PATCH] common/pread_write.c: backport fix for 64-bit handling of pread/pwrite Date: Sat, 9 May 2015 12:43:05 -0400 Message-Id: <1431189785-15161-1-git-send-email-basile@opensource.dyc.edu> X-Mailer: git-send-email 1.7.6.1 Cc: "Anthony G. Basile" , embedded@gentoo.org X-BeenThere: uclibc@uclibc.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "Discussion and development of uClibc \(the embedded C library\)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: uclibc-bounces@uclibc.org Sender: "uClibc" From: "Anthony G. Basile" Commit 458076d fixed the pread/pwrite syscalls for 64-bit ports on the master branch, but the fix was not backported to the 0.9.33 branch. This patch backports the fix which is critical for e2fsprogs-1.42.12 and above. The introduction of pread64()/pwrite64() in e2fsprogs' commit f00948a broke fsck.ext3 and fsck.ext4 on uclibc-0.9.33, leading to potential data corrupton. See https://bugs.gentoo.org/show_bug.cgi?id=548950 http://git.kernel.org/cgit/fs/ext2/e2fsprogs.git/commit/?id=f00948ad1df100c7d616ef6fbf7609329a2e4001 Signed-off-by: Anthony G. Basile --- libc/sysdeps/linux/common/pread_write.c | 120 +++++++++++++++++++------------- 1 file changed, 71 insertions(+), 49 deletions(-) diff --git a/libc/sysdeps/linux/common/pread_write.c b/libc/sysdeps/linux/common/pread_write.c index 924509e..51d76a1 100644 --- a/libc/sysdeps/linux/common/pread_write.c +++ b/libc/sysdeps/linux/common/pread_write.c @@ -28,87 +28,109 @@ #define LIBC_CANCEL_HANDLED() /* Nothing. */ #endif -extern __typeof(pread) __libc_pread; -extern __typeof(pwrite) __libc_pwrite; -#ifdef __UCLIBC_HAS_LFS__ -extern __typeof(pread64) __libc_pread64; -extern __typeof(pwrite64) __libc_pwrite64; -#endif - -#ifdef __NR_pread64 /* Newer kernels renamed but it's the same. */ +#ifdef __NR_pread64 # undef __NR_pread # define __NR_pread __NR_pread64 #endif +#ifdef __NR_pwrite64 +# undef __NR_pwrite +# define __NR_pwrite __NR_pwrite64 +#endif -#include - -# define __NR___syscall_pread __NR_pread +#ifndef MY_PREAD +# ifdef __NR_pread +# define __NR___syscall_pread __NR_pread +# if defined(__UCLIBC_SYSCALL_ALIGN_64BIT__) +static _syscall6(ssize_t, __syscall_pread, int, fd, void *, buf, + size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo) +# define MY_PREAD(fd, buf, count, offset) __syscall_pread(fd, buf, count, 0, OFF_HI_LO(offset)) +# define MY_PREAD64(fd, buf, count, offset) __syscall_pread(fd, buf, count, 0, OFF64_HI_LO(offset)) +# elif __WORDSIZE == 32 +static _syscall5(ssize_t, __syscall_pread, int, fd, void *, buf, + size_t, count, off_t, offset_hi, off_t, offset_lo) +# define MY_PREAD(fd, buf, count, offset) __syscall_pread(fd, buf, count, OFF_HI_LO(offset)) +# define MY_PREAD64(fd, buf, count, offset) __syscall_pread(fd, buf, count, OFF64_HI_LO(offset)) +# else +static _syscall4(ssize_t, __syscall_pread, int, fd, void *, buf, + size_t, count, off_t, offset) +# define MY_PREAD(fd, buf, count, offset) __syscall_pread(fd, buf, count, offset) +# define MY_PREAD64(fd, buf, count, offset) __syscall_pread(fd, buf, count, offset) +# endif +# endif +#endif -#if defined(__UCLIBC_SYSCALL_ALIGN_64BIT__) -static __inline__ _syscall6(ssize_t, __syscall_pread, int, fd, void *, buf, - size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo) -# define __syscall_pread(fd, buf, count, ...) __syscall_pread(fd, buf, count, 0, __VA_ARGS__) -#else -static __inline__ _syscall5(ssize_t, __syscall_pread, int, fd, void *, buf, - size_t, count, off_t, offset_hi, off_t, offset_lo) +#ifndef MY_PWRITE +# ifdef __NR_pwrite +# define __NR___syscall_pwrite __NR_pwrite +# if defined(__UCLIBC_SYSCALL_ALIGN_64BIT__) +static _syscall6(ssize_t, __syscall_pwrite, int, fd, const void *, buf, + size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo) +# define MY_PWRITE(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, 0, OFF_HI_LO(offset)) +# define MY_PWRITE64(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, 0, OFF64_HI_LO(offset)) +# elif __WORDSIZE == 32 +static _syscall5(ssize_t, __syscall_pwrite, int, fd, const void *, buf, + size_t, count, off_t, offset_hi, off_t, offset_lo) +# define MY_PWRITE(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, OFF_HI_LO(offset)) +# define MY_PWRITE64(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, OFF64_HI_LO(offset)) +# else +static _syscall4(ssize_t, __syscall_pwrite, int, fd, const void *, buf, + size_t, count, off_t, offset) +# define MY_PWRITE(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, offset) +# define MY_PWRITE64(fd, buf, count, offset) __syscall_pwrite(fd, buf, count, offset) +# endif +# endif #endif ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset) { int oldtype = LIBC_CANCEL_ASYNC (); - int result = __syscall_pread(fd, buf, count, __LONG_LONG_PAIR(offset >> 31, offset)); + int result = MY_PREAD(fd, buf, count, offset); LIBC_CANCEL_RESET (oldtype); return result; } weak_alias(__libc_pread,pread) -# ifdef __UCLIBC_HAS_LFS__ -ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset) +ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset) { - uint32_t low = offset & 0xffffffff; - uint32_t high = offset >> 32; int oldtype = LIBC_CANCEL_ASYNC (); - int result = __syscall_pread(fd, buf, count, __LONG_LONG_PAIR(high, low)); + int result = MY_PWRITE(fd, buf, count, offset); LIBC_CANCEL_RESET (oldtype); return result; } -weak_alias(__libc_pread64,pread64) -# endif /* __UCLIBC_HAS_LFS__ */ - -#ifdef __NR_pwrite64 /* Newer kernels renamed but it's the same. */ -# undef __NR_pwrite -# define __NR_pwrite __NR_pwrite64 -#endif - -# define __NR___syscall_pwrite __NR_pwrite -#if defined(__UCLIBC_SYSCALL_ALIGN_64BIT__) -static __inline__ _syscall6(ssize_t, __syscall_pwrite, int, fd, const void *, buf, - size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo) -# define __syscall_pwrite(fd, buf, count, ...) __syscall_pwrite(fd, buf, count, 0, __VA_ARGS__) -#else -static __inline__ _syscall5(ssize_t, __syscall_pwrite, int, fd, const void *, buf, - size_t, count, off_t, offset_hi, off_t, offset_lo) -#endif +weak_alias(__libc_pwrite,pwrite) -ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset) +#ifdef __UCLIBC_HAS_LFS__ +# if __WORDSIZE == 32 +ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset) { int oldtype = LIBC_CANCEL_ASYNC (); - int result = __syscall_pwrite(fd, buf, count, __LONG_LONG_PAIR(offset >> 31, offset)); + int result = MY_PREAD64(fd, buf, count, offset); LIBC_CANCEL_RESET (oldtype); return result; } -weak_alias(__libc_pwrite,pwrite) +weak_alias(__libc_pread64,pread64) -# ifdef __UCLIBC_HAS_LFS__ ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset) { - uint32_t low = offset & 0xffffffff; - uint32_t high = offset >> 32; int oldtype = LIBC_CANCEL_ASYNC (); - int result = __syscall_pwrite(fd, buf, count, __LONG_LONG_PAIR(high, low)); + int result = MY_PWRITE64(fd, buf, count, offset); LIBC_CANCEL_RESET (oldtype); return result; } weak_alias(__libc_pwrite64,pwrite64) -# endif /* __UCLIBC_HAS_LFS__ */ + +# else +# ifdef __LINUXTHREADS_OLD__ +weak_alias(pread,pread64) +weak_alias(pwrite,pwrite64) +extern __typeof(pread64) __libc_pread64; +extern __typeof(pwrite64) __libc_pwrite4; +strong_alias(pread64,__libc_pread64) +strong_alias(pwrite64,__libc_write64) +# else +strong_alias_untyped(pread,pread64) +strong_alias_untyped(pwrite,pwrite64) +# endif +# endif +#endif