syncDirectory_lckd :: HalfsCapable b t r l m =>
                      DirHandle r l
                   -> HalfsM b r l m ()
syncDirectory_lckd dh = do
  -- Precond: (dhLock dh) is currently held (can we assert this? TODO)
  state <- readRef $ dhState dh

  -- TODO: Currently, we overwrite the entire DirectoryEntry list, truncating
  -- the directory's inode data stream as needed.  This is _braindead_, however.
  -- For OnlyAdded, we can just append to the stream; for OnlyDeleted, we can
  -- write only invalidating entries and employ incremental coalescing, etc.
  -- overwriteAll should be reserved for the VeryDirty case only.
  case state of
    Clean       -> return ()
    OnlyAdded   -> overwriteAll
    OnlyDeleted -> overwriteAll
    VeryDirty   -> overwriteAll
  where
    overwriteAll = do
      inr <- getDHINR_lckd dh
      writeStream inr 0 True
        =<< (encode . M.elems) `fmap` readRef (dhContents dh)
      lift . bdFlush =<< hasks hsBlockDev
      modifyRef (dhState dh) dirStTransClean

-- | Obtains an active directory handle for the directory at the given InodeRef
syncDirectory_lckd :: HalfsCapable b t r l m =>
                      DirHandle r l
                   -> HalfsM b r l m ()
syncDirectory_lckd dh = do
  -- Precond: (dhLock dh) is currently held (can we assert this? TODO)
  state <- readRef $ dhState dh

  -- TODO: Currently, we overwrite the entire DirectoryEntry list, truncating
  -- the directory's inode data stream as needed.  This is _braindead_, however.
  -- For OnlyAdded, we can just append to the stream; for OnlyDeleted, we can
  -- write only invalidating entries and employ incremental coalescing, etc.
  -- overwriteAll should be reserved for the VeryDirty case only.
  case state of
    Clean       -> return ()
    OnlyAdded   -> overwriteAll
    OnlyDeleted -> overwriteAll
    VeryDirty   -> overwriteAll
  where
    overwriteAll = do
      inr <- getDHINR_lckd dh
      writeStream inr 0 True
        =<< (encode . M.elems) `fmap` readRef (dhContents dh)
      lift . bdFlush =<< hasks hsBlockDev
      modifyRef (dhState dh) dirStTransClean

-- | Obtains an active directory handle for the directory at the given InodeRef
syncDirectory_lckd dh = do
  -- Precond: (dhLock dh) is currently held (can we assert this? TODO)
  state <- readRef $ dhState dh

  -- TODO: Currently, we overwrite the entire DirectoryEntry list, truncating
  -- the directory's inode data stream as needed.  This is _braindead_, however.
  -- For OnlyAdded, we can just append to the stream; for OnlyDeleted, we can
  -- write only invalidating entries and employ incremental coalescing, etc.
  -- overwriteAll should be reserved for the VeryDirty case only.
  case state of
    Clean       -> return ()
    OnlyAdded   -> overwriteAll
    OnlyDeleted -> overwriteAll
    VeryDirty   -> overwriteAll
  where
    overwriteAll = do
      inr <- getDHINR_lckd dh
      writeStream inr 0 True
        =<< (encode . M.elems) `fmap` readRef (dhContents dh)
      lift . bdFlush =<< hasks hsBlockDev
      modifyRef (dhState dh) dirStTransClean

-- | Obtains an active directory handle for the directory at the given InodeRef