Source code for reflink.reflink
# -*- coding: utf-8 -*-
"""Main module."""
import os
from . import backend
[docs]def reflink(oldpath, newpath):
""" Create a reflink from ``newpath`` to ``oldpath``.
Raises a ``NotImplementedError`` when the OS does not implement reflink.
Raises a ``ReflinkImpossibleError`` when trying to reflink between devices,
Raises an ``IOError`` when:
* ``oldpath`` is a directory
* The user has no permissions to create ``newpath``
* Trying to reflink into a swapfile (ETXTBSY)
For debugability's sake, ``reflink`` _can_ throw IOError in other cases,
when the underlying system call fails for another reason.
However, these reasons cannot be triggered with this basic call.
See man `IOCTL-FICLONERANGE(2) <http://man7.org/linux/man-pages/man2/ioctl_ficlonerange.2.html>`__
and ``backend.py`` for more details on these conditions.
Example code:
>>> from reflink import reflink
>>> reflink("large_file.img", "copy_of_file.img") # doctest: +SKIP
>>>
"""
# raise NotImplementedError when OS does not implement reflink
# raise ReflinkImpossibleError when trying to reflink across devices
backend.clone(oldpath, newpath)
[docs]def supported_at(path):
""" Returns ``True`` when a path on the filesystem supports reflinking,
``False`` otherwise.
Please note that the current implementation verifies this by testing
whether it's possible to reflink.
"""
# Currently, there's no systemcall that tests whether a point in the VFS is supported or not.
# We create a file at ``path``, and clone it.
a = os.path.join(path, "i_hope_no_one_will_ever_try_this_name.txt")
b = os.path.join(path, "i_hope_no_one_will_ever_try_that_name.txt")
with open(a, 'w+') as f:
f.write(u"abc")
try:
reflink(a, b)
return True
except:
pass
# TODO: there are probably specific exception that we can handle
finally:
os.unlink(a)
if os.path.isfile(b):
os.unlink(b)
return False