6643: Support associating uuid with multiple inodes to fix double-remove bug.
authorPeter Amstutz <peter.amstutz@curoverse.com>
Mon, 27 Jul 2015 13:11:07 +0000 (09:11 -0400)
committerPeter Amstutz <peter.amstutz@curoverse.com>
Mon, 27 Jul 2015 13:11:07 +0000 (09:11 -0400)
services/fuse/arvados_fuse/__init__.py
services/fuse/arvados_fuse/fusedir.py
services/fuse/tests/test_mount.py

index 59b4a6219233e1b857b96081950d6a71865e5ac5..775b9bec052ce65906707ce6704583f482188184 100644 (file)
@@ -148,7 +148,9 @@ class InodeCache(object):
         self._total -= obj.cache_size
         del self._entries[obj.cache_priority]
         if obj.cache_uuid:
-            del self._by_uuid[obj.cache_uuid]
+            self._by_uuid[obj.cache_uuid].remove(obj)
+            if not self._by_uuid[obj.cache_uuid]:
+                del self._by_uuid[obj.cache_uuid]
             obj.cache_uuid = None
         if clear:
             _logger.debug("InodeCache cleared %i total now %i", obj.inode, self._total)
@@ -168,7 +170,11 @@ class InodeCache(object):
             self._entries[obj.cache_priority] = obj
             obj.cache_uuid = obj.uuid()
             if obj.cache_uuid:
-                self._by_uuid[obj.cache_uuid] = obj
+                if obj.cache_uuid not in self._by_uuid:
+                    self._by_uuid[obj.cache_uuid] = [obj]
+                else:
+                    if obj not in self._by_uuid[obj.cache_uuid]:
+                        self._by_uuid[obj.cache_uuid].append(obj)
             self._total += obj.objsize()
             _logger.debug("InodeCache touched %i (size %i) (uuid %s) total now %i", obj.inode, obj.objsize(), obj.cache_uuid, self._total)
             self.cap_cache()
index 5ebb6b94ae42a21ec24bf78ccfedaecd00ff3cbe..de12fcce1763764e5ef80e6ef2ce62d70178b9d6 100644 (file)
@@ -524,13 +524,17 @@ will appear if it exists.
                     self.inode, self.inodes, self.api, self.num_retries, k))
 
             if e.update():
-                self._entries[k] = e
+                if k not in self._entries:
+                    self._entries[k] = e
+                else:
+                    self.inodes.del_entry(e)
                 return True
             else:
-                _logger.debug('update failed of %s', k)
+                self.inodes.del_entry(e)
                 return False
         except Exception as e:
             _logger.debug('arv-mount exception keep %s', e)
+            self.inodes.del_entry(e)
             return False
 
     def __getitem__(self, item):
index 53bde6e863af571cb2b8a0f4c4cab2f8b53878b7..b9309746a50f181803adf9063d998c5f51a0486d 100644 (file)
@@ -1022,13 +1022,14 @@ class MagicDirApiError(FuseMagicTest):
         self.make_mount(fuse.MagicDirectory)
 
         self.operations.inodes.inode_cache.cap = 1
-        self.operations.inodes.inode_cache.min_entries = 1
+        self.operations.inodes.inode_cache.min_entries = 2
 
         with self.assertRaises(OSError):
             llfuse.listdir(os.path.join(self.mounttmp, self.testcollection))
 
         llfuse.listdir(os.path.join(self.mounttmp, self.testcollection))
 
+
 class FuseUnitTest(unittest.TestCase):
     def test_sanitize_filename(self):
         acceptable = [