[blobfs] Improve precondition checking on teardown.

Don't check the status of "no more clones" notifications
when the system is being tear down, as the waiter may have
been cancelled.

This doesn't change the behavior of production code.

Bug: 40738

Change-Id: I7c824bed875432e1b9c0c8b5450bc7fdfeff0fad
diff --git a/zircon/system/ulib/blobfs/blob.cc b/zircon/system/ulib/blobfs/blob.cc
index c6de82c..a2bc9d2 100644
--- a/zircon/system/ulib/blobfs/blob.cc
+++ b/zircon/system/ulib/blobfs/blob.cc
@@ -545,9 +545,11 @@
 
 void Blob::HandleNoClones(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
                           const zx_packet_signal_t* signal) {
-  ZX_DEBUG_ASSERT(status == ZX_OK);
-  ZX_DEBUG_ASSERT((signal->observed & ZX_VMO_ZERO_CHILDREN) != 0);
-  ZX_DEBUG_ASSERT(clone_watcher_.object() != ZX_HANDLE_INVALID);
+  if (!tearing_down_) {
+    ZX_DEBUG_ASSERT(status == ZX_OK);
+    ZX_DEBUG_ASSERT((signal->observed & ZX_VMO_ZERO_CHILDREN) != 0);
+    ZX_DEBUG_ASSERT(clone_watcher_.object() != ZX_HANDLE_INVALID);
+  }
   clone_watcher_.set_object(ZX_HANDLE_INVALID);
   clone_ref_ = nullptr;
 }
@@ -822,6 +824,7 @@
   if (clone_watcher_.is_pending()) {
     clone_watcher_.Cancel();
     clone_watcher_.set_object(ZX_HANDLE_INVALID);
+    tearing_down_ = true;
     return std::move(clone_ref_);
   }
   return nullptr;
diff --git a/zircon/system/ulib/blobfs/blob.h b/zircon/system/ulib/blobfs/blob.h
index a64bd5b..971a41e 100644
--- a/zircon/system/ulib/blobfs/blob.h
+++ b/zircon/system/ulib/blobfs/blob.h
@@ -180,6 +180,8 @@
   // Monitors the current VMO, keeping a reference to the Vnode
   // alive while the |out| VMO (and any clones it may have) are open.
   zx_status_t CloneDataVmo(zx_rights_t rights, zx::vmo* out_vmo, size_t* out_size);
+
+  // Receives notifications when all clones vended by CloneDataVmo() are released.
   void HandleNoClones(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
                       const zx_packet_signal_t* signal);
 
@@ -277,8 +279,9 @@
 
   zx::event readable_event_ = {};
 
-  uint32_t fd_count_ = {};
-  uint32_t map_index_ = {};
+  uint32_t fd_count_ = 0;
+  uint32_t map_index_ = 0;
+  bool tearing_down_ = false;
 
   // TODO(smklein): We are only using a few of these fields, such as:
   // - blob_size