X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/8d61948fecccfc60db2f18ba4daf7c01ddf3d3c8..80d4b6ebb20393507be7ecd0dcf888ebda623a35:/services/fuse/arvados_fuse/__init__.py diff --git a/services/fuse/arvados_fuse/__init__.py b/services/fuse/arvados_fuse/__init__.py index 527e02728b..51b0a57a7f 100644 --- a/services/fuse/arvados_fuse/__init__.py +++ b/services/fuse/arvados_fuse/__init__.py @@ -367,45 +367,38 @@ class Operations(llfuse.Operations): return True def listen_for_events(self): - self.events = arvados.events.subscribe(self._api_client, - [["event_type", "in", ["create", "update", "delete"]]], - self.on_event) + self.events = arvados.events.subscribe( + self._api_client, + [["event_type", "in", ["create", "update", "delete"]]], + self.on_event) @catch_exceptions def on_event(self, ev): if 'event_type' not in ev: return with llfuse.lock: + new_attrs = (ev.get("properties") or {}).get("new_attributes") or {} + pdh = new_attrs.get("portable_data_hash") + # new_attributes.modified_at currently lacks + # subsecond precision (see #6347) so use event_at + # which should always be the same. + stamp = ev.get("event_at") + for item in self.inodes.inode_cache.find_by_uuid(ev["object_uuid"]): item.invalidate() - if ev["object_kind"] == "arvados#collection": - new_attr = (ev.get("properties") and - ev["properties"].get("new_attributes") and - ev["properties"]["new_attributes"]) - - # new_attributes.modified_at currently lacks - # subsecond precision (see #6347) so use event_at - # which should always be the same. - record_version = ( - (ev["event_at"], new_attr["portable_data_hash"]) - if new_attr else None) - - item.update(to_record_version=record_version) + if stamp and pdh and ev.get("object_kind") == "arvados#collection": + item.update(to_record_version=(stamp, pdh)) else: item.update() - oldowner = ( - ev.get("properties") and - ev["properties"].get("old_attributes") and - ev["properties"]["old_attributes"].get("owner_uuid")) - newowner = ev["object_owner_uuid"] + oldowner = ((ev.get("properties") or {}).get("old_attributes") or {}).get("owner_uuid") + newowner = ev.get("object_owner_uuid") for parent in ( self.inodes.inode_cache.find_by_uuid(oldowner) + self.inodes.inode_cache.find_by_uuid(newowner)): parent.invalidate() parent.update() - @catch_exceptions def getattr(self, inode): if inode not in self.inodes: @@ -511,6 +504,20 @@ class Operations(llfuse.Operations): self._filehandles[fh] = FileHandle(fh, p) self.inodes.touch(p) + # Normally, we will have received an "update" event if the + # parent collection is stale here. However, even if the parent + # collection hasn't changed, the manifest might have been + # fetched so long ago that the signatures on the data block + # locators have expired. Calling checkupdate() on all + # ancestors ensures the signatures will be refreshed if + # necessary. + while p.parent_inode in self.inodes: + if p == self.inodes[p.parent_inode]: + break + p = self.inodes[p.parent_inode] + self.inodes.touch(p) + p.checkupdate() + _logger.debug("arv-mount open inode %i flags %x fh %i", inode, flags, fh) return fh