X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/27616fe74103c079a84ac34b2adb83f1952c5772..a3e32a2f4a702c076d46a5b19305dd20a1ee3012:/services/fuse/arvados_fuse/fusedir.py diff --git a/services/fuse/arvados_fuse/fusedir.py b/services/fuse/arvados_fuse/fusedir.py index 2fca36eb0a..8ffca49601 100644 --- a/services/fuse/arvados_fuse/fusedir.py +++ b/services/fuse/arvados_fuse/fusedir.py @@ -23,6 +23,7 @@ _logger = logging.getLogger('arvados.arvados_fuse') # appear as underscores in the fuse mount.) _disallowed_filename_characters = re.compile('[\x00/]') +# '.' and '..' are not reachable if API server is newer than #6277 def sanitize_filename(dirty): """Replace disallowed filename characters with harmless "_".""" if dirty is None: @@ -143,13 +144,13 @@ class Directory(FreshBase): # delete any other directory entries that were not in found in 'items' for i in oldentries: - _logger.debug("Forgetting about entry '%s' on inode %i", str(i), self.inode) - llfuse.invalidate_entry(self.inode, str(i)) + _logger.debug("Forgetting about entry '%s' on inode %i", i, self.inode) + self.inodes.invalidate_entry(self.inode, i.encode(self.inodes.encoding)) self.inodes.del_entry(oldentries[i]) changed = True if changed: - llfuse.invalidate_inode(self.inode) + self.inodes.invalidate_inode(self.inode) self._mtime = time.time() self.fresh() @@ -165,9 +166,9 @@ class Directory(FreshBase): self._entries = oldentries return False for n in oldentries: - llfuse.invalidate_entry(self.inode, str(n)) + self.inodes.invalidate_entry(self.inode, n.encode(self.inodes.encoding)) self.inodes.del_entry(oldentries[n]) - llfuse.invalidate_inode(self.inode) + self.inodes.invalidate_inode(self.inode) self.invalidate() return True else: @@ -235,20 +236,21 @@ class CollectionDirectoryBase(Directory): def on_event(self, event, collection, name, item): if collection == self.collection: - _logger.debug("%s %s %s %s", event, collection, name, item) + name = sanitize_filename(name) + _logger.debug("collection notify %s %s %s %s", event, collection, name, item) with llfuse.lock: if event == arvados.collection.ADD: self.new_entry(name, item, self.mtime()) elif event == arvados.collection.DEL: ent = self._entries[name] del self._entries[name] - llfuse.invalidate_entry(self.inode, name) + self.inodes.invalidate_entry(self.inode, name.encode(self.inodes.encoding)) self.inodes.del_entry(ent) elif event == arvados.collection.MOD: if hasattr(item, "fuse_entry") and item.fuse_entry is not None: - llfuse.invalidate_inode(item.fuse_entry.inode) + self.inodes.invalidate_inode(item.fuse_entry.inode) elif name in self._entries: - llfuse.invalidate_inode(self._entries[name].inode) + self.inodes.invalidate_inode(self._entries[name].inode) def populate(self, mtime): self._mtime = mtime @@ -371,7 +373,7 @@ class CollectionDirectory(CollectionDirectoryBase): return self.collection_locator @use_counter - def update(self): + def update(self, to_record_version=None): try: if self.collection_record is not None and portable_data_hash_pattern.match(self.collection_locator): return True @@ -386,9 +388,12 @@ class CollectionDirectory(CollectionDirectoryBase): if not self.stale(): return - _logger.debug("Updating %s", self.collection_locator) - if self.collection: - self.collection.update() + _logger.debug("Updating %s", to_record_version) + if self.collection is not None: + if self.collection.known_past_version(to_record_version): + _logger.debug("%s already processed %s", self.collection_locator, to_record_version) + else: + self.collection.update() else: if uuid_pattern.match(self.collection_locator): coll_reader = arvados.collection.Collection( @@ -419,8 +424,8 @@ class CollectionDirectory(CollectionDirectoryBase): return True finally: self._updating_lock.release() - except arvados.errors.NotFoundError: - _logger.exception("arv-mount %s: error", self.collection_locator) + except arvados.errors.NotFoundError as e: + _logger.error("Error fetching collection '%s': %s", self.collection_locator, e) except arvados.errors.ArgumentError as detail: _logger.warning("arv-mount %s: error %s", self.collection_locator, detail) if self.collection_record is not None and "manifest_text" in self.collection_record: @@ -462,6 +467,12 @@ class CollectionDirectory(CollectionDirectoryBase): # footprint directly would be more accurate, but also more complicated. return self._manifest_size * 128 + def finalize(self): + if self.collection is not None: + if self.writable(): + self.collection.save() + self.collection.stop_threads() + class MagicDirectory(Directory): """A special directory that logically contains the set of all extant keep locators. @@ -514,12 +525,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: + 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): @@ -759,7 +775,7 @@ class ProjectDirectory(Directory): # Acually move the entry from source directory to this directory. del src._entries[name_old] self._entries[name_new] = ent - llfuse.invalidate_entry(src.inode, name_old) + self.inodes.invalidate_entry(src.inode, name_old.encode(self.inodes.encoding)) class SharedDirectory(Directory):