X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/97fe5c7710eb3a61757618df774447839b317ecb..fa8c5cdb36fa89af92087d6465b207d65ffc9618:/services/fuse/arvados_fuse/fusedir.py diff --git a/services/fuse/arvados_fuse/fusedir.py b/services/fuse/arvados_fuse/fusedir.py index 00efab765a..76530844b5 100644 --- a/services/fuse/arvados_fuse/fusedir.py +++ b/services/fuse/arvados_fuse/fusedir.py @@ -156,24 +156,38 @@ class Directory(FreshBase): self.fresh() - def clear(self, force=False): - """Delete all entries""" + def in_use(self): + if super(Directory, self).in_use(): + return True + for v in self._entries.itervalues(): + if v.in_use(): + return True + return False - if not self.in_use() or force: - oldentries = self._entries - self._entries = {} - for n in oldentries: - if not oldentries[n].clear(force): - self._entries = oldentries - return False - for n in oldentries: - self.inodes.invalidate_entry(self.inode, n.encode(self.inodes.encoding)) - self.inodes.del_entry(oldentries[n]) - self.inodes.invalidate_inode(self.inode) - self.invalidate() + def has_ref(self, only_children): + if super(Directory, self).has_ref(only_children): return True - else: - return False + for v in self._entries.itervalues(): + if v.has_ref(False): + return True + return False + + def clear(self): + """Delete all entries""" + oldentries = self._entries + self._entries = {} + for n in oldentries: + oldentries[n].clear() + self.inodes.invalidate_entry(self.inode, n.encode(self.inodes.encoding)) + self.inodes.del_entry(oldentries[n]) + self.inodes.invalidate_inode(self.inode) + self.invalidate() + + def kernel_invalidate(self): + for n, e in self._entries.iteritems(): + self.inodes.invalidate_entry(self.inode, n.encode(self.inodes.encoding)) + e.kernel_invalidate() + self.inodes.invalidate_inode(self.inode) def mtime(self): return self._mtime @@ -184,6 +198,9 @@ class Directory(FreshBase): def flush(self): pass + def want_event_subscribe(self): + raise NotImplementedError() + def create(self, name): raise NotImplementedError() @@ -317,6 +334,10 @@ class CollectionDirectoryBase(Directory): self.flush() src.flush() + def clear(self): + super(CollectionDirectoryBase, self).clear() + self.collection = None + class CollectionDirectory(CollectionDirectoryBase): """Represents the root of a directory tree representing a collection.""" @@ -327,12 +348,12 @@ class CollectionDirectory(CollectionDirectoryBase): self.num_retries = num_retries self.collection_record_file = None self.collection_record = None - self.poll = True + self._poll = True try: - self.poll_time = (api._rootDesc.get('blobSignatureTtl', 60*60*2)/2) + self._poll_time = (api._rootDesc.get('blobSignatureTtl', 60*60*2)/2) except: _logger.debug("Error getting blobSignatureTtl from discovery document: %s", sys.exc_info()[0]) - self.poll_time = 60*60 + self._poll_time = 60*60 if isinstance(collection_record, dict): self.collection_locator = collection_record['uuid'] @@ -351,6 +372,9 @@ class CollectionDirectory(CollectionDirectoryBase): def writable(self): return self.collection.writable() if self.collection is not None else self._writable + def want_event_subscribe(self): + return (uuid_pattern.match(self.collection_locator) is not None) + # Used by arv-web.py to switch the contents of the CollectionDirectory def change_collection(self, new_locator): """Switch the contents of the CollectionDirectory. @@ -364,7 +388,7 @@ class CollectionDirectory(CollectionDirectoryBase): def new_collection(self, new_collection_record, coll_reader): if self.inode: - self.clear(force=True) + self.clear() self.collection_record = new_collection_record @@ -396,7 +420,7 @@ class CollectionDirectory(CollectionDirectoryBase): if not self.stale(): return - _logger.debug("Updating %s", to_record_version) + _logger.debug("Updating collection %s inode %s to record version %s", self.collection_locator, self.inode, 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) @@ -442,6 +466,7 @@ class CollectionDirectory(CollectionDirectoryBase): _logger.exception("arv-mount %s: error", self.collection_locator) if self.collection_record is not None and "manifest_text" in self.collection_record: _logger.error("arv-mount manifest_text is: %s", self.collection_record["manifest_text"]) + self.invalidate() return False @use_counter @@ -481,6 +506,10 @@ class CollectionDirectory(CollectionDirectoryBase): self.collection.save() self.collection.stop_threads() + def clear(self): + super(CollectionDirectory, self).clear() + self._manifest_size = 0 + class TmpCollectionDirectory(CollectionDirectoryBase): """A directory backed by an Arvados collection that never gets saved. @@ -500,7 +529,8 @@ class TmpCollectionDirectory(CollectionDirectoryBase): def __init__(self, parent_inode, inodes, api_client, num_retries): collection = self.UnsaveableCollection( api_client=api_client, - keep_client=api_client.keep) + keep_client=api_client.keep, + num_retries=num_retries) super(TmpCollectionDirectory, self).__init__( parent_inode, inodes, collection) self.collection_record_file = None @@ -542,6 +572,9 @@ class TmpCollectionDirectory(CollectionDirectoryBase): def writable(self): return True + def want_event_subscribe(self): + return False + def finalize(self): self.collection.stop_threads() @@ -610,10 +643,11 @@ will appear if it exists. self.inodes.del_entry(e) return True else: + self.inodes.invalidate_entry(self.inode, k) self.inodes.del_entry(e) return False - except Exception as e: - _logger.debug('arv-mount exception keep %s', e) + except Exception as ex: + _logger.debug('arv-mount exception keep %s', ex) self.inodes.del_entry(e) return False @@ -623,21 +657,14 @@ will appear if it exists. else: raise KeyError("No collection with id " + item) - def clear(self, force=False): + def clear(self): pass + def want_event_subscribe(self): + return not self.pdh_only -class RecursiveInvalidateDirectory(Directory): - def invalidate(self): - try: - super(RecursiveInvalidateDirectory, self).invalidate() - for a in self._entries: - self._entries[a].invalidate() - except Exception: - _logger.exception() - -class TagsDirectory(RecursiveInvalidateDirectory): +class TagsDirectory(Directory): """A special directory that contains as subdirectories all tags visible to the user.""" def __init__(self, parent_inode, inodes, api, num_retries, poll_time=60): @@ -647,6 +674,9 @@ class TagsDirectory(RecursiveInvalidateDirectory): self._poll = True self._poll_time = poll_time + def want_event_subscribe(self): + return True + @use_counter def update(self): with llfuse.lock_released: @@ -675,6 +705,9 @@ class TagDirectory(Directory): self._poll = poll self._poll_time = poll_time + def want_event_subscribe(self): + return True + @use_counter def update(self): with llfuse.lock_released: @@ -706,6 +739,9 @@ class ProjectDirectory(Directory): self._updating_lock = threading.Lock() self._current_user = None + def want_event_subscribe(self): + return True + def createDirectory(self, i): if collection_uuid_pattern.match(i['uuid']): return CollectionDirectory(self.inode, self.inodes, self.api, self.num_retries, i) @@ -926,3 +962,6 @@ class SharedDirectory(Directory): lambda i: ProjectDirectory(self.inode, self.inodes, self.api, self.num_retries, i[1], poll=self._poll, poll_time=self._poll_time)) except Exception: _logger.exception() + + def want_event_subscribe(self): + return True