dedup: explicit reflink/ficlone on python<3.14

This commit is contained in:
ed 2025-10-11 23:43:09 +00:00
parent e65ec75e22
commit f2caab6119
3 changed files with 25 additions and 7 deletions

View file

@ -2868,8 +2868,6 @@ class AuthSrv(object):
if have_reflink: if have_reflink:
t = "WARNING: Reflink-based dedup was requested, but %s. This will not work; files will be full copies instead." t = "WARNING: Reflink-based dedup was requested, but %s. This will not work; files will be full copies instead."
if sys.version_info < (3, 14):
self.log(t % "your python version is not new enough", 1)
if not sys.platform.startswith("linux"): if not sys.platform.startswith("linux"):
self.log(t % "your OS is not Linux", 1) self.log(t % "your OS is not Linux", 1)

View file

@ -10,6 +10,7 @@ import re
import shutil import shutil
import stat import stat
import subprocess as sp import subprocess as sp
import sys
import tempfile import tempfile
import threading import threading
import time import time
@ -27,6 +28,7 @@ from .mtag import MParser, MTag
from .util import ( from .util import (
E_FS_CRIT, E_FS_CRIT,
E_FS_MEH, E_FS_MEH,
HAVE_FICLONE,
HAVE_SQLITE3, HAVE_SQLITE3,
SYMTIME, SYMTIME,
VF_CAREFUL, VF_CAREFUL,
@ -88,6 +90,10 @@ if True: # pylint: disable=using-constant-test
if TYPE_CHECKING: if TYPE_CHECKING:
from .svchub import SvcHub from .svchub import SvcHub
USE_FICLONE = HAVE_FICLONE and sys.version_info < (3, 14)
if USE_FICLONE:
import fcntl
zsg = "avif,avifs,bmp,gif,heic,heics,heif,heifs,ico,j2p,j2k,jp2,jpeg,jpg,jpx,png,tga,tif,tiff,webp" zsg = "avif,avifs,bmp,gif,heic,heics,heif,heifs,ico,j2p,j2k,jp2,jpeg,jpg,jpx,png,tga,tif,tiff,webp"
ICV_EXTS = set(zsg.split(",")) ICV_EXTS = set(zsg.split(","))
@ -3530,11 +3536,26 @@ class Up2k(object):
linked = False linked = False
try: try:
if "reflink" in flags: if rm and bos.path.exists(dst):
raise Exception("reflink") wunlink(self.log, dst, flags)
if not is_mv and not flags.get("dedup"): if not is_mv and not flags.get("dedup"):
raise Exception("dedup is disabled in config") raise Exception("dedup is disabled in config")
if "reflink" in flags:
if not USE_FICLONE:
raise Exception("reflink") # python 3.14 or newer; no need
try:
with open(fsenc(src), "rb") as fi, open(fsenc(dst), "wb") as fo:
fcntl.ioctl(fo.fileno(), fcntl.FICLONE, fi.fileno())
except:
if bos.path.exists(dst):
wunlink(self.log, dst, flags)
raise
if lmod:
bos.utime_c(self.log, dst, int(lmod), False)
return
lsrc = src lsrc = src
ldst = dst ldst = dst
fs1 = bos.stat(os.path.dirname(src)).st_dev fs1 = bos.stat(os.path.dirname(src)).st_dev
@ -3561,9 +3582,6 @@ class Up2k(object):
lsrc = lsrc.replace("/", "\\") lsrc = lsrc.replace("/", "\\")
ldst = ldst.replace("/", "\\") ldst = ldst.replace("/", "\\")
if rm and bos.path.exists(dst):
wunlink(self.log, dst, flags)
try: try:
if "hardlink" in flags: if "hardlink" in flags:
os.link(fsenc(absreal(src)), fsenc(dst)) os.link(fsenc(absreal(src)), fsenc(dst))

View file

@ -129,8 +129,10 @@ try:
import fcntl import fcntl
HAVE_FCNTL = True HAVE_FCNTL = True
HAVE_FICLONE = hasattr(fcntl, "FICLONE")
except: except:
HAVE_FCNTL = False HAVE_FCNTL = False
HAVE_FICLONE = False
try: try:
import ctypes import ctypes