ソースを参照

Move sync_file_range to its own extension

Will 5 年 前
コミット
242424ecae
3 ファイル変更23 行追加7 行削除
  1. 4 0
      setup.py
  2. 6 7
      src/borg/platform/linux.pyx
  3. 13 0
      src/borg/platform/syncfilerange.pyx

+ 4 - 0
setup.py

@@ -98,6 +98,7 @@ item_source = 'src/borg/item.pyx'
 checksums_source = 'src/borg/algorithms/checksums.pyx'
 platform_posix_source = 'src/borg/platform/posix.pyx'
 platform_linux_source = 'src/borg/platform/linux.pyx'
+platform_syncfilerange_source = 'src/borg/platform/syncfilerange.pyx'
 platform_darwin_source = 'src/borg/platform/darwin.pyx'
 platform_freebsd_source = 'src/borg/platform/freebsd.pyx'
 platform_windows_source = 'src/borg/platform/windows.pyx'
@@ -112,6 +113,7 @@ cython_sources = [
 
     platform_posix_source,
     platform_linux_source,
+    platform_syncfilerange_source,
     platform_freebsd_source,
     platform_darwin_source,
     platform_windows_source,
@@ -202,6 +204,7 @@ if not on_rtd:
 
     posix_ext = Extension('borg.platform.posix', [platform_posix_source])
     linux_ext = Extension('borg.platform.linux', [platform_linux_source], libraries=['acl'])
+    syncfilerange_ext = Extension('borg.platform.syncfilerange', [platform_syncfilerange_source])
     freebsd_ext = Extension('borg.platform.freebsd', [platform_freebsd_source])
     darwin_ext = Extension('borg.platform.darwin', [platform_darwin_source])
     windows_ext = Extension('borg.platform.windows', [platform_windows_source])
@@ -212,6 +215,7 @@ if not on_rtd:
         ext_modules.append(windows_ext)
     if sys.platform == 'linux':
         ext_modules.append(linux_ext)
+        ext_modules.append(syncfilerange_ext)
     elif sys.platform.startswith('freebsd'):
         ext_modules.append(freebsd_ext)
     elif sys.platform == 'darwin':

+ 6 - 7
src/borg/platform/linux.pyx

@@ -10,6 +10,11 @@ from ..helpers import safe_decode, safe_encode
 from .base import SyncFile as BaseSyncFile
 from .base import safe_fadvise
 from .xattr import _listxattr_inner, _getxattr_inner, _setxattr_inner, split_string0
+try:
+    from .syncfilerange import sync_file_range, SYNC_FILE_RANGE_WRITE, SYNC_FILE_RANGE_WAIT_BEFORE, SYNC_FILE_RANGE_WAIT_AFTER
+    SYNC_FILE_RANGE_LOADED = True
+except ImportError:
+    SYNC_FILE_RANGE_LOADED = False
 
 from libc cimport errno
 from libc.stdint cimport int64_t
@@ -50,12 +55,6 @@ cdef extern from "acl/libacl.h":
     int acl_extended_file(const char *path)
     int acl_extended_fd(int fd)
 
-cdef extern from "fcntl.h":
-    int sync_file_range(int fd, int64_t offset, int64_t nbytes, unsigned int flags)
-    unsigned int SYNC_FILE_RANGE_WRITE
-    unsigned int SYNC_FILE_RANGE_WAIT_BEFORE
-    unsigned int SYNC_FILE_RANGE_WAIT_AFTER
-
 cdef extern from "linux/fs.h":
     # ioctls
     int FS_IOC_SETFLAGS
@@ -317,7 +316,7 @@ cdef _sync_file_range(fd, offset, length, flags):
 cdef unsigned PAGE_MASK = sysconf(_SC_PAGESIZE) - 1
 
 
-if 'basesyncfile' in workarounds:
+if 'basesyncfile' in workarounds or not SYNC_FILE_RANGE_LOADED:
     class SyncFile(BaseSyncFile):
         # if we are on platforms with a broken or not implemented sync_file_range,
         # use the more generic BaseSyncFile to avoid issues.

+ 13 - 0
src/borg/platform/syncfilerange.pyx

@@ -0,0 +1,13 @@
+from libc.stdint cimport int64_t
+
+
+# Some Linux systems (like Termux on Android 7 or earlier) do not have access
+# to sync_file_range. By isolating the access to sync_file_range in this
+# separate extension, it can be imported dynamically from linux.pyx only when
+# available and systems without support can otherwise use the rest of
+# linux.pyx.
+cdef extern from "fcntl.h":
+    int sync_file_range(int fd, int64_t offset, int64_t nbytes, unsigned int flags)
+    unsigned int SYNC_FILE_RANGE_WRITE
+    unsigned int SYNC_FILE_RANGE_WAIT_BEFORE
+    unsigned int SYNC_FILE_RANGE_WAIT_AFTER