Copy data from one regular mmap-like fd to another by using a high-performance copy_file_range(2) syscall that gives filesystems an opportunity to implement the use of reflinks or server-side copy. This should work on Linux >= 4.5 only.
(fsrc, fdst)
| 135 | return blocksize |
| 136 | |
| 137 | def _fastcopy_copy_file_range(fsrc, fdst): |
| 138 | """Copy data from one regular mmap-like fd to another by using |
| 139 | a high-performance copy_file_range(2) syscall that gives filesystems |
| 140 | an opportunity to implement the use of reflinks or server-side copy. |
| 141 | |
| 142 | This should work on Linux >= 4.5 only. |
| 143 | """ |
| 144 | try: |
| 145 | infd = fsrc.fileno() |
| 146 | outfd = fdst.fileno() |
| 147 | except Exception as err: |
| 148 | raise _GiveupOnFastCopy(err) # not a regular file |
| 149 | |
| 150 | blocksize = _determine_linux_fastcopy_blocksize(infd) |
| 151 | offset = 0 |
| 152 | while True: |
| 153 | try: |
| 154 | n_copied = os.copy_file_range(infd, outfd, blocksize, offset_dst=offset) |
| 155 | except OSError as err: |
| 156 | # ...in oder to have a more informative exception. |
| 157 | err.filename = fsrc.name |
| 158 | err.filename2 = fdst.name |
| 159 | |
| 160 | if err.errno == errno.ENOSPC: # filesystem is full |
| 161 | raise err from None |
| 162 | |
| 163 | # Give up on first call and if no data was copied. |
| 164 | if offset == 0 and os.lseek(outfd, 0, os.SEEK_CUR) == 0: |
| 165 | raise _GiveupOnFastCopy(err) |
| 166 | |
| 167 | raise err |
| 168 | else: |
| 169 | if n_copied == 0: |
| 170 | # If no bytes have been copied yet, copy_file_range |
| 171 | # might silently fail. |
| 172 | # https://lore.kernel.org/linux-fsdevel/20210126233840.GG4626@dread.disaster.area/T/#m05753578c7f7882f6e9ffe01f981bc223edef2b0 |
| 173 | if offset == 0: |
| 174 | raise _GiveupOnFastCopy() |
| 175 | break |
| 176 | offset += n_copied |
| 177 | |
| 178 | def _fastcopy_sendfile(fsrc, fdst): |
| 179 | """Copy data from one regular mmap-like fd to another by using |
no test coverage detected
searching dependent graphs…