Parcourir la source

Improved mtime precisoin checking for FUSE.

Jonas Borgström il y a 12 ans
Parent
commit
2e237ad006
3 fichiers modifiés avec 29 ajouts et 13 suppressions
  1. 10 3
      attic/fuse.py
  2. 18 9
      attic/testsuite/__init__.py
  3. 1 1
      attic/testsuite/archiver.py

+ 10 - 3
attic/fuse.py

@@ -6,6 +6,8 @@ import stat
 import time
 
 from attic.helpers import daemonize
+# Does this version of llfuse support ns precision?
+have_fuse_mtime_ns = hasattr(llfuse.EntryAttributes, 'st_mtime_ns')
 
 
 class AtticOperations(llfuse.Operations):
@@ -95,9 +97,14 @@ class AtticOperations(llfuse.Operations):
         entry.st_size = size
         entry.st_blksize = 512
         entry.st_blocks = 1
-        entry.st_atime = item[b'mtime'] / 1e9
-        entry.st_mtime = item[b'mtime'] / 1e9
-        entry.st_ctime = item[b'mtime'] / 1e9
+        if have_fuse_mtime_ns:
+            entry.st_atime_ns = item[b'mtime']
+            entry.st_mtime_ns = item[b'mtime']
+            entry.st_ctime_ns = item[b'mtime']
+        else:
+            entry.st_atime = item[b'mtime'] / 1e9
+            entry.st_mtime = item[b'mtime'] / 1e9
+            entry.st_ctime = item[b'mtime'] / 1e9
         return entry
 
     def listxattr(self, inode):

+ 18 - 9
attic/testsuite/__init__.py

@@ -8,6 +8,14 @@ import unittest
 from attic.helpers import st_mtime_ns
 from attic.xattr import get_all
 
+try:
+    import llfuse
+    # Does this version of llfuse support ns precision?
+    have_fuse_mtime_ns = hasattr(llfuse.EntryAttributes, 'st_mtime_ns')
+except ImportError:
+    have_fuse_mtime_ns = False
+
+
 # The mtime get/set precison varies on different OS and Python versions
 if 'HAVE_FUTIMENS' in getattr(posix, '_have_functions', []):
     st_mtime_ns_round = 0
@@ -34,11 +42,11 @@ class AtticTestCase(unittest.TestCase):
         except EnvironmentError:
             return {}
 
-    def assert_dirs_equal(self, dir1, dir2, fuse=False):
+    def assert_dirs_equal(self, dir1, dir2):
         diff = filecmp.dircmp(dir1, dir2)
-        self._assert_dirs_equal_cmp(diff, fuse)
+        self._assert_dirs_equal_cmp(diff)
 
-    def _assert_dirs_equal_cmp(self, diff, fuse=False):
+    def _assert_dirs_equal_cmp(self, diff):
         self.assert_equal(diff.left_only, [])
         self.assert_equal(diff.right_only, [])
         self.assert_equal(diff.diff_files, [])
@@ -48,6 +56,8 @@ class AtticTestCase(unittest.TestCase):
             path2 = os.path.join(diff.right, filename)
             s1 = os.lstat(path1)
             s2 = os.lstat(path2)
+            # Assume path2 is on FUSE if st_dev is different
+            fuse = s1.st_dev != s2.st_dev
             attrs = ['st_mode', 'st_uid', 'st_gid', 'st_rdev']
             if not fuse or not os.path.isdir(path1):
                 # dir nlink is always 1 on our fuse fileystem
@@ -55,18 +65,17 @@ class AtticTestCase(unittest.TestCase):
             d1 = [filename] + [getattr(s1, a) for a in attrs]
             d2 = [filename] + [getattr(s2, a) for a in attrs]
             if not os.path.islink(path1) or utime_supports_fd:
-                # llfuse does not provide ns precision for now
-                if fuse:
+                # Older versions of llfuse does not support ns precision properly
+                if fuse and not have_fuse_mtime_ns:
                     d1.append(round(st_mtime_ns(s1), -4))
                     d2.append(round(st_mtime_ns(s2), -4))
-                else:
-                    d1.append(round(st_mtime_ns(s1), st_mtime_ns_round))
-                    d2.append(round(st_mtime_ns(s2), st_mtime_ns_round))
+                d1.append(round(st_mtime_ns(s1), st_mtime_ns_round))
+                d2.append(round(st_mtime_ns(s2), st_mtime_ns_round))
             d1.append(self._get_xattrs(path1))
             d2.append(self._get_xattrs(path2))
             self.assert_equal(d1, d2)
         for sub_diff in diff.subdirs.values():
-            self._assert_dirs_equal_cmp(sub_diff, fuse)
+            self._assert_dirs_equal_cmp(sub_diff)
 
     def wait_for_mount(self, path, timeout=5):
         """Wait until a filesystem is mounted on `path`

+ 1 - 1
attic/testsuite/archiver.py

@@ -224,7 +224,7 @@ class ArchiverTestCase(AtticTestCase):
         try:
             self.attic('mount', self.repository_location + '::archive', mountpoint, fork=True)
             self.wait_for_mount(mountpoint)
-            self.assert_dirs_equal(self.input_path, os.path.join(mountpoint, 'input'), fuse=True)
+            self.assert_dirs_equal(self.input_path, os.path.join(mountpoint, 'input'))
         finally:
             if sys.platform.startswith('linux'):
                 os.system('fusermount -u ' + mountpoint)