dedup: use chmod/chown volflags; closes #1203

This commit is contained in:
ed 2026-01-15 19:19:27 +00:00
parent 5b3191b495
commit bef07720d9
2 changed files with 26 additions and 5 deletions

View file

@ -61,6 +61,8 @@ from .util import (
s3dec, s3dec,
s3enc, s3enc,
sanitize_fn, sanitize_fn,
set_ap_perms,
set_fperms,
sfsenc, sfsenc,
spack, spack,
statdir, statdir,
@ -3546,7 +3548,7 @@ class Up2k(object):
if self.args.nw: if self.args.nw:
return return
linked = False linked = 0
try: try:
if rm and bos.path.exists(dst): if rm and bos.path.exists(dst):
wunlink(self.log, dst, flags) wunlink(self.log, dst, flags)
@ -3560,6 +3562,8 @@ class Up2k(object):
try: try:
with open(fsenc(src), "rb") as fi, open(fsenc(dst), "wb") as fo: with open(fsenc(src), "rb") as fi, open(fsenc(dst), "wb") as fo:
fcntl.ioctl(fo.fileno(), fcntl.FICLONE, fi.fileno()) fcntl.ioctl(fo.fileno(), fcntl.FICLONE, fi.fileno())
if "fperms" in flags:
set_fperms(fo, flags)
except: except:
if bos.path.exists(dst): if bos.path.exists(dst):
wunlink(self.log, dst, flags) wunlink(self.log, dst, flags)
@ -3597,7 +3601,7 @@ class Up2k(object):
try: try:
if "hardlink" in flags: if "hardlink" in flags:
os.link(fsenc(absreal(src)), fsenc(dst)) os.link(fsenc(absreal(src)), fsenc(dst))
linked = True linked = 2
except Exception as ex: except Exception as ex:
self.log("cannot hardlink: " + repr(ex)) self.log("cannot hardlink: " + repr(ex))
if "hardlinkonly" in flags: if "hardlinkonly" in flags:
@ -3616,7 +3620,7 @@ class Up2k(object):
else: else:
os.symlink(fsenc(lsrc), fsenc(ldst)) os.symlink(fsenc(lsrc), fsenc(ldst))
linked = True linked = 1
except Exception as ex: except Exception as ex:
if str(ex) != "reflink": if str(ex) != "reflink":
self.log("cannot link; creating copy: " + repr(ex)) self.log("cannot link; creating copy: " + repr(ex))
@ -3630,8 +3634,11 @@ class Up2k(object):
raise Exception(t % (src, fsrc, dst)) raise Exception(t % (src, fsrc, dst))
trystat_shutil_copy2(self.log, fsenc(csrc), fsenc(dst)) trystat_shutil_copy2(self.log, fsenc(csrc), fsenc(dst))
if lmod and (not linked or SYMTIME): if linked < 2 and (linked < 1 or SYMTIME):
bos.utime_c(self.log, dst, int(lmod), False) if lmod:
bos.utime_c(self.log, dst, int(lmod), False)
if "fperms" in flags:
set_ap_perms(dst, flags)
def handle_chunks( def handle_chunks(
self, ptop: str, wark: str, chashes: list[str] self, ptop: str, wark: str, chashes: list[str]
@ -4507,6 +4514,8 @@ class Up2k(object):
bos.utime(dabs, times, False) bos.utime(dabs, times, False)
except: except:
pass pass
if "fperms" in dvn.flags:
set_ap_perms(dabs, dvn.flags)
if xac: if xac:
runhook( runhook(
@ -4792,6 +4801,8 @@ class Up2k(object):
wunlink(self.log, sabs, svn.flags) wunlink(self.log, sabs, svn.flags)
else: else:
atomic_move(self.log, sabs, dabs, svn.flags) atomic_move(self.log, sabs, dabs, svn.flags)
if svn != dvn and "fperms" in dvn.flags:
set_ap_perms(dabs, dvn.flags)
except OSError as ex: except OSError as ex:
if ex.errno != errno.EXDEV: if ex.errno != errno.EXDEV:
@ -4825,6 +4836,8 @@ class Up2k(object):
bos.utime(dabs, times, False) bos.utime(dabs, times, False)
except: except:
pass pass
if "fperms" in dvn.flags:
set_ap_perms(dabs, dvn.flags)
wunlink(self.log, sabs, svn.flags) wunlink(self.log, sabs, svn.flags)

View file

@ -2721,6 +2721,14 @@ def set_fperms(f: Union[typing.BinaryIO, typing.IO[Any]], vf: dict[str, Any]) ->
os.fchown(fno, vf["uid"], vf["gid"]) os.fchown(fno, vf["uid"], vf["gid"])
def set_ap_perms(ap: str, vf: dict[str, Any]) -> None:
zb = fsenc(ap)
if "chmod_f" in vf:
os.chmod(zb, vf["chmod_f"])
if "chown" in vf:
os.chown(zb, vf["uid"], vf["gid"])
def trystat_shutil_copy2(log: "NamedLogger", src: bytes, dst: bytes) -> bytes: def trystat_shutil_copy2(log: "NamedLogger", src: bytes, dst: bytes) -> bytes:
try: try:
return shutil.copy2(src, dst) return shutil.copy2(src, dst)