Browse Source

FUSE: reflect deduplication in allocated blocks

Instead of giving all files a fixed block count of 1, this assigns each
deduplicated chunk to a certain file. In effect, the cumulative file
size that is shown in the mountpoint accurately reflects the amount of
actual disk space needed for the repository (barring metadata overhead).

Although the block assignment is done arbitrarily, depending on the
user's access pattern, the sizes will be consistent within the entire
mount point. This facilitates the use of tools like du and ncdu for
inspecting the actual disk usage in a repository as opposed to just
looking at the original, uncompressed, non-deduplicated file sizes.
Daniel Danner 10 năm trước cách đây
mục cha
commit
bffc419615
1 tập tin đã thay đổi với 8 bổ sung2 xóa
  1. 8 2
      attic/fuse.py

+ 8 - 2
attic/fuse.py

@@ -43,6 +43,7 @@ class AtticOperations(llfuse.Operations):
         self.contents = defaultdict(dict)
         self.contents = defaultdict(dict)
         self.default_dir = {b'mode': 0o40755, b'mtime': int(time.time() * 1e9), b'uid': os.getuid(), b'gid': os.getgid()}
         self.default_dir = {b'mode': 0o40755, b'mtime': int(time.time() * 1e9), b'uid': os.getuid(), b'gid': os.getgid()}
         self.pending_archives = {}
         self.pending_archives = {}
+        self.accounted_chunks = {}
         self.cache = ItemCache()
         self.cache = ItemCache()
         if archive:
         if archive:
             self.process_archive(archive)
             self.process_archive(archive)
@@ -130,8 +131,13 @@ class AtticOperations(llfuse.Operations):
     def getattr(self, inode):
     def getattr(self, inode):
         item = self.get_item(inode)
         item = self.get_item(inode)
         size = 0
         size = 0
+        dsize = 0
         try:
         try:
-            size = sum(size for _, size, _ in item[b'chunks'])
+            for key, chunksize, _ in item[b'chunks']:
+                size += chunksize
+                if self.accounted_chunks.get(key, inode) == inode:
+                    self.accounted_chunks[key] = inode
+                    dsize += chunksize
         except KeyError:
         except KeyError:
             pass
             pass
         entry = llfuse.EntryAttributes()
         entry = llfuse.EntryAttributes()
@@ -146,7 +152,7 @@ class AtticOperations(llfuse.Operations):
         entry.st_rdev = item.get(b'rdev', 0)
         entry.st_rdev = item.get(b'rdev', 0)
         entry.st_size = size
         entry.st_size = size
         entry.st_blksize = 512
         entry.st_blksize = 512
-        entry.st_blocks = 1
+        entry.st_blocks = dsize / 512
         if have_fuse_mtime_ns:
         if have_fuse_mtime_ns:
             entry.st_atime_ns = item[b'mtime']
             entry.st_atime_ns = item[b'mtime']
             entry.st_mtime_ns = item[b'mtime']
             entry.st_mtime_ns = item[b'mtime']