openDirectory :: HalfsCapable b t r l m =>
                 InodeRef
              -> HalfsM b r l m (DirHandle r l)
openDirectory inr = do
  -- TODO FIXME permissions checks!
  dhMap <- hasks hsDHMap
  mdh   <- withLockedRscRef dhMap (lookupRM inr)
  case mdh of
    Just dh -> return dh
    Nothing -> do
      dh <- newDirHandle inr
      withLockedRscRef dhMap $ \ref -> do
        -- If there's now a DirHandle in the map for our inode ref, prefer it to
        -- the one we just created; this is to safely avoid race conditions
        -- without extending the critical section over this entire function,
        -- which performs a potentially expensive BlockDevice read.
        mdh' <- lookupRM inr ref
        case mdh' of
          Just dh' -> return dh'
          Nothing  -> do
            insertRM inr dh ref
            return dh
openDirectory :: HalfsCapable b t r l m =>
                 InodeRef
              -> HalfsM b r l m (DirHandle r l)
openDirectory inr = do
  -- TODO FIXME permissions checks!
  dhMap <- hasks hsDHMap
  mdh   <- withLockedRscRef dhMap (lookupRM inr)
  case mdh of
    Just dh -> return dh
    Nothing -> do
      dh <- newDirHandle inr
      withLockedRscRef dhMap $ \ref -> do
        -- If there's now a DirHandle in the map for our inode ref, prefer it to
        -- the one we just created; this is to safely avoid race conditions
        -- without extending the critical section over this entire function,
        -- which performs a potentially expensive BlockDevice read.
        mdh' <- lookupRM inr ref
        case mdh' of
          Just dh' -> return dh'
          Nothing  -> do
            insertRM inr dh ref
            return dh
openDirectory inr = do
  -- TODO FIXME permissions checks!
  dhMap <- hasks hsDHMap
  mdh   <- withLockedRscRef dhMap (lookupRM inr)
  case mdh of
    Just dh -> return dh
    Nothing -> do
      dh <- newDirHandle inr
      withLockedRscRef dhMap $ \ref -> do
        -- If there's now a DirHandle in the map for our inode ref, prefer it to
        -- the one we just created; this is to safely avoid race conditions
        -- without extending the critical section over this entire function,
        -- which performs a potentially expensive BlockDevice read.
        mdh' <- lookupRM inr ref
        case mdh' of
          Just dh' -> return dh'
          Nothing  -> do
            insertRM inr dh ref
            return dh