mirror of
https://github.com/borgbackup/borg.git
synced 2026-02-20 00:10:35 -05:00
Switch to st_mtime_ns when available
This commit is contained in:
parent
1fdc5eabc6
commit
ad08664b65
5 changed files with 27 additions and 16 deletions
|
|
@ -12,7 +12,7 @@ import xattr
|
|||
|
||||
from .chunker import chunkify
|
||||
from .helpers import uid2user, user2uid, gid2group, group2gid, \
|
||||
Statistics, decode_dict
|
||||
Statistics, decode_dict, st_mtime_ns
|
||||
|
||||
ITEMS_BUFFER = 1024 * 1024
|
||||
CHUNK_MIN = 1024
|
||||
|
|
@ -20,6 +20,7 @@ WINDOW_SIZE = 0xfff
|
|||
CHUNK_MASK = 0xffff
|
||||
|
||||
utime_supports_fd = os.utime in getattr(os, 'supports_fd', {})
|
||||
has_mtime_ns = sys.version >= '3.3'
|
||||
has_lchmod = hasattr(os, 'lchmod')
|
||||
|
||||
|
||||
|
|
@ -304,11 +305,11 @@ class Archive(object):
|
|||
elif has_lchmod: # Not available on Linux
|
||||
os.lchmod(path, item[b'mode'])
|
||||
if fd and utime_supports_fd: # Python >= 3.3
|
||||
os.utime(fd, (item[b'mtime'], item[b'mtime']))
|
||||
os.utime(fd, None, ns=(item[b'mtime'], item[b'mtime']))
|
||||
elif utime_supports_fd: # Python >= 3.3
|
||||
os.utime(path, (item[b'mtime'], item[b'mtime']), follow_symlinks=False)
|
||||
os.utime(path, None, ns=(item[b'mtime'], item[b'mtime']), follow_symlinks=False)
|
||||
elif not symlink:
|
||||
os.utime(path, (item[b'mtime'], item[b'mtime']))
|
||||
os.utime(path, (item[b'mtime'] / 10**9, item[b'mtime'] / 10**9))
|
||||
|
||||
def verify_file(self, item, start, result, peek=None):
|
||||
if not item[b'chunks']:
|
||||
|
|
@ -347,7 +348,7 @@ class Archive(object):
|
|||
b'mode': st.st_mode,
|
||||
b'uid': st.st_uid, b'user': uid2user(st.st_uid),
|
||||
b'gid': st.st_gid, b'group': gid2group(st.st_gid),
|
||||
b'mtime': st.st_mtime,
|
||||
b'mtime': st_mtime_ns(st),
|
||||
}
|
||||
if self.numeric_owner:
|
||||
item[b'user'] = item[b'group'] = None
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ class Archiver(object):
|
|||
size = sum(size for _, size, _ in item[b'chunks'])
|
||||
except KeyError:
|
||||
pass
|
||||
mtime = format_time(datetime.fromtimestamp(item[b'mtime']))
|
||||
mtime = format_time(datetime.fromtimestamp(item[b'mtime'] / 10**9))
|
||||
if b'source' in item:
|
||||
if type == 'l':
|
||||
extra = ' -> %s' % item[b'source']
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import os
|
|||
from binascii import hexlify, unhexlify
|
||||
import shutil
|
||||
|
||||
from .helpers import get_cache_dir, decode_dict
|
||||
from .helpers import get_cache_dir, decode_dict, st_mtime_ns
|
||||
from .hashindex import ChunkIndex
|
||||
|
||||
|
||||
|
|
@ -190,7 +190,7 @@ class Cache(object):
|
|||
if self.files is None:
|
||||
self._read_files()
|
||||
entry = self.files.get(path_hash)
|
||||
if (entry and entry[3] == st.st_mtime
|
||||
if (entry and entry[3] == st_mtime_ns(st)
|
||||
and entry[2] == st.st_size and entry[1] == st.st_ino):
|
||||
# reset entry age
|
||||
self.files[path_hash][0] = 0
|
||||
|
|
@ -200,6 +200,6 @@ class Cache(object):
|
|||
|
||||
def memorize_file(self, path_hash, st, ids):
|
||||
# Entry: Age, inode, size, mtime, chunk ids
|
||||
self.files[path_hash] = 0, st.st_ino, st.st_size, st.st_mtime, ids
|
||||
self._newest_mtime = max(self._newest_mtime, st.st_mtime)
|
||||
|
||||
mtime_ns = st_mtime_ns(st)
|
||||
self.files[path_hash] = 0, st.st_ino, st.st_size, mtime_ns, ids
|
||||
self._newest_mtime = max(self._newest_mtime, mtime_ns)
|
||||
|
|
|
|||
|
|
@ -375,4 +375,12 @@ def decode_dict(d, keys, encoding='utf-8', errors='surrogateescape'):
|
|||
|
||||
|
||||
def remove_surrogates(s, errors='replace'):
|
||||
return s.encode('utf-8', errors).decode('utf-8')
|
||||
return s.encode('utf-8', errors).decode('utf-8')
|
||||
|
||||
|
||||
if sys.version < '3.3':
|
||||
def st_mtime_ns(st):
|
||||
return int(st.st_mtime * 10**9)
|
||||
else:
|
||||
def st_mtime_ns(st):
|
||||
return st.st_mtime_ns
|
||||
|
|
|
|||
10
darc/test.py
10
darc/test.py
|
|
@ -16,6 +16,7 @@ from .key import suite as KeySuite
|
|||
from .store import Store, suite as StoreSuite
|
||||
from .remote import Store, suite as RemoteStoreSuite
|
||||
|
||||
has_mtime_ns = sys.version >= '3.3'
|
||||
utime_supports_fd = os.utime in getattr(os, 'supports_fd', {})
|
||||
|
||||
|
||||
|
|
@ -89,12 +90,13 @@ class Test(unittest.TestCase):
|
|||
s2 = os.lstat(path2)
|
||||
attrs = ['st_mode', 'st_uid', 'st_gid', 'st_rdev']
|
||||
if not os.path.islink(path1) or utime_supports_fd:
|
||||
attrs.append('st_mtime')
|
||||
attrs.append('st_mtime_ns' if has_mtime_ns else 'st_mtime')
|
||||
d1 = [filename] + [getattr(s1, a) for a in attrs]
|
||||
d2 = [filename] + [getattr(s2, a) for a in attrs]
|
||||
if(len(d1) == 6):
|
||||
d1[-1] = int(d1[-1])
|
||||
d2[-1] = int(d2[-1])
|
||||
# 'st_mtime precision is limited'
|
||||
if attrs[-1] == 'st_mtime':
|
||||
d1[-1] = round(d1[-1], 4)
|
||||
d2[-1] = round(d2[-1], 4)
|
||||
d1.append(self.get_xattrs(path1))
|
||||
d2.append(self.get_xattrs(path2))
|
||||
self.assertEqual(d1, d2)
|
||||
|
|
|
|||
Loading…
Reference in a new issue