Skip to content

Commit

Permalink
fix inconsistent use of symlink mtimes in database;
Browse files Browse the repository at this point in the history
on upload, dupes are by default handled by symlinking to the existing
copy on disk, writing the uploader's local mtime into the symlink mtime,
which is also what gets indexed in the db

this worked as intended, however during an -e2dsa rescan on startup the
symlink destination timestamps would be used instead, causing a reindex
and the resulting loss of uploader metadata (ip, timestamp)

will now always use the symlink's mtime;
worst-case 1% slower startup (no dhash)

this change will cause a reindex of incorrectly indexed files, however
as this has already happened at least once due to the bug being fixed,
there will be no additional loss of metadata
  • Loading branch information
9001 committed Sep 1, 2023
1 parent a50d056 commit c1efd22
Showing 1 changed file with 18 additions and 3 deletions.
21 changes: 18 additions & 3 deletions copyparty/up2k.py
Original file line number Diff line number Diff line change
Expand Up @@ -1050,7 +1050,7 @@ def _build_dir(
if WINDOWS:
rd = rd.replace("\\", "/").strip("/")

g = statdir(self.log_func, not self.args.no_scandir, False, cdir)
g = statdir(self.log_func, not self.args.no_scandir, True, cdir)
gl = sorted(g)
partials = set([x[0] for x in gl if "PARTIAL" in x[0]])
for iname, inf in gl:
Expand All @@ -1065,6 +1065,12 @@ def _build_dir(
continue

lmod = int(inf.st_mtime)
if stat.S_ISLNK(inf.st_mode):
try:
inf = bos.stat(abspath)
except:
continue

sz = inf.st_size
if fat32 and not ffat and inf.st_mtime % 2:
fat32 = False
Expand Down Expand Up @@ -1445,9 +1451,11 @@ def _verify_integrity(self, vol: VFS) -> int:
pf = "v{}, {:.0f}+".format(n_left, b_left / 1024 / 1024)
self.pp.msg = pf + abspath

st = bos.stat(abspath)
# throws on broken symlinks (always did)
stl = bos.lstat(abspath)
st = bos.stat(abspath) if stat.S_ISLNK(stl.st_mode) else stl
mt2 = int(stl.st_mtime)
sz2 = st.st_size
mt2 = int(st.st_mtime)

if nohash or not sz2:
w2 = up2k_wark_from_metadata(self.salt, sz2, mt2, rd, fn)
Expand All @@ -1469,6 +1477,13 @@ def _verify_integrity(self, vol: VFS) -> int:
if w == w2:
continue

# symlink mtime was inconsistent before v1.9.4; check if that's it
if st != stl and (nohash or not sz2):
mt2b = int(st.st_mtime)
w2b = up2k_wark_from_metadata(self.salt, sz2, mt2b, rd, fn)
if w == w2b:
continue

rewark.append((drd, dfn, w2, sz2, mt2))

t = "hash mismatch: {}\n db: {} ({} byte, {})\n fs: {} ({} byte, {})"
Expand Down

0 comments on commit c1efd22

Please sign in to comment.