From 3167dad07cf528e7464320c160a61eba0df747c8 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 1 Apr 2011 11:33:14 -0400 Subject: Also make x86 sync_file_range a cancellation point. --- sysdeps/unix/sysv/linux/i386/Makefile | 3 + .../unix/sysv/linux/i386/call_sync_file_range.S | 72 ++++++++++++++++++++++ sysdeps/unix/sysv/linux/i386/sync_file_range.S | 72 ---------------------- sysdeps/unix/sysv/linux/i386/sync_file_range.c | 44 +++++++++++++ 4 files changed, 119 insertions(+), 72 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/i386/call_sync_file_range.S delete mode 100644 sysdeps/unix/sysv/linux/i386/sync_file_range.S create mode 100644 sysdeps/unix/sysv/linux/i386/sync_file_range.c (limited to 'sysdeps') diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile index f52ee89f0e..fc5a524ebf 100644 --- a/sysdeps/unix/sysv/linux/i386/Makefile +++ b/sysdeps/unix/sysv/linux/i386/Makefile @@ -6,7 +6,10 @@ endif ifeq ($(subdir),elf) sysdep-others += lddlibc4 install-bin += lddlibc4 +endif +ifeq ($(subdir),io) +sysdep_routines += call_sync_file_range endif ifeq ($(subdir),resource) diff --git a/sysdeps/unix/sysv/linux/i386/call_sync_file_range.S b/sysdeps/unix/sysv/linux/i386/call_sync_file_range.S new file mode 100644 index 0000000000..fb0ab492cb --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/call_sync_file_range.S @@ -0,0 +1,72 @@ +/* Selective file content synch'ing. + Copyright (C) 2006, 2007, 2011 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#define _ERRNO_H 1 +#include + + + .text +ENTRY (__call_sync_file_range) +#ifdef __NR_sync_file_range + pushl %ebx + cfi_adjust_cfa_offset (4) + pushl %esi + cfi_adjust_cfa_offset (4) + pushl %edi + cfi_adjust_cfa_offset (4) + pushl %ebp + cfi_adjust_cfa_offset (4) + + movl 20(%esp), %ebx + cfi_rel_offset (ebx, 12) + movl 24(%esp), %ecx + movl 28(%esp), %edx + movl 32(%esp), %esi + cfi_rel_offset (esi, 8) + movl 36(%esp), %edi + cfi_rel_offset (edi, 4) + movl 40(%esp), %ebp + cfi_rel_offset (ebp, 0) + + movl $SYS_ify(sync_file_range), %eax + ENTER_KERNEL + + popl %ebp + cfi_adjust_cfa_offset (-4) + cfi_restore (ebp) + popl %edi + cfi_adjust_cfa_offset (-4) + cfi_restore (edi) + popl %esi + cfi_adjust_cfa_offset (-4) + cfi_restore (esi) + popl %ebx + cfi_adjust_cfa_offset (-4) + cfi_restore (ebx) + + cmpl $-4095, %eax + jae SYSCALL_ERROR_LABEL +#else + movl $-ENOSYS, %eax + jmp SYSCALL_ERROR_LABEL +#endif +L(pseudo_end): + ret +PSEUDO_END (__call_sync_file_range) diff --git a/sysdeps/unix/sysv/linux/i386/sync_file_range.S b/sysdeps/unix/sysv/linux/i386/sync_file_range.S deleted file mode 100644 index 8544703d56..0000000000 --- a/sysdeps/unix/sysv/linux/i386/sync_file_range.S +++ /dev/null @@ -1,72 +0,0 @@ -/* Selective file content synch'ing. - Copyright (C) 2006, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include -#define _ERRNO_H 1 -#include - - - .text -ENTRY (sync_file_range) -#ifdef __NR_sync_file_range - pushl %ebx - cfi_adjust_cfa_offset (4) - pushl %esi - cfi_adjust_cfa_offset (4) - pushl %edi - cfi_adjust_cfa_offset (4) - pushl %ebp - cfi_adjust_cfa_offset (4) - - movl 20(%esp), %ebx - cfi_rel_offset (ebx, 12) - movl 24(%esp), %ecx - movl 28(%esp), %edx - movl 32(%esp), %esi - cfi_rel_offset (esi, 8) - movl 36(%esp), %edi - cfi_rel_offset (edi, 4) - movl 40(%esp), %ebp - cfi_rel_offset (ebp, 0) - - movl $SYS_ify(sync_file_range), %eax - ENTER_KERNEL - - popl %ebp - cfi_adjust_cfa_offset (-4) - cfi_restore (ebp) - popl %edi - cfi_adjust_cfa_offset (-4) - cfi_restore (edi) - popl %esi - cfi_adjust_cfa_offset (-4) - cfi_restore (esi) - popl %ebx - cfi_adjust_cfa_offset (-4) - cfi_restore (ebx) - - cmpl $-4095, %eax - jae SYSCALL_ERROR_LABEL -#else - movl $-ENOSYS, %eax - jmp SYSCALL_ERROR_LABEL -#endif -L(pseudo_end): - ret -PSEUDO_END (sync_file_range) diff --git a/sysdeps/unix/sysv/linux/i386/sync_file_range.c b/sysdeps/unix/sysv/linux/i386/sync_file_range.c new file mode 100644 index 0000000000..c10e99604a --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/sync_file_range.c @@ -0,0 +1,44 @@ +/* Selective file content synch'ing. + Copyright (C) 2006, 2007, 2011 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + + +extern int __call_sync_file_range (int fd, off64_t offset, off64_t nbytes, + unsigned int flags) + attribute_hidden; + + +int +sync_file_range (int fd, __off64_t from, __off64_t to, unsigned int flags) +{ + if (SINGLE_THREAD_P) + return __call_sync_file_range (fd, from, to, flags); + + int result; + int oldtype = LIBC_CANCEL_ASYNC (); + + result = __call_sync_file_range (fd, from, to, flags); + + LIBC_CANCEL_RESET (oldtype); + + return result; +} -- cgit 1.4.1