Skip to content
  • Marvin Scholz's avatar
    mmc_device_darwin: Rewrite mounting logic · cc2f95a6
    Marvin Scholz authored
    The previous way of mounting the disk was flawed which especially
    showed after moving to using a dispatch queue that removed long wait
    times.
    
    When the exclusive low level access is released, the OS will see the
    disk as if it is a "new" device and then try to mount it again, so it
    does not work to immediately try to mount the disk again as it would
    fail. The disk is not mounted for us, regardless of the failure, thats
    done because the OS mounts the disk. Even removing the mount call
    completely would still result in the disk getting mounted by the OS,
    so calling iokit_mount was unnecessary.
    
    Yet we want to mount the disk ourselves so we know when it is usable
    and completely mounted for reading files on it. To do that my approach
    is to use a mount approval callback, this callback gets called whenever
    a device is to be mounted by someone (usually the OS auto-mounting) and
    then the callback can decide to allow or deny mounting.
    
    In this callback we check if the disk is currently not mounted, then we
    compare the disk with our disk to know if they match.
    Internally what that does is just compare the BSD name so it is not
    entirely perfect as the user could unplug the disk and plug a different
    one and it could appear as the "same" disk.
    
    If the disks match, we reject the mount attempt and indicate to the
    caller that the disk appeared, using the disk_state.
    
    The caller uses a semaphore to wait for a given timeout, currently
    20 seconds. Waiting indefinitely is impossible as it could cause
    the program to hang if the user unplugs the drive while we wait.
    
    When the disk re-appears we now mount it, during that the state has to
    be set to mounting so that the mount approval callback can allow the
    request when we try to mount. Just unregistering the mount approval
    callback after our disk appeared the first time does not work as
    it causes the OS to immediately re-try mounting the disk apparently.
    
    Once the mounting succeeded we can proceed. Even if it fails though,
    there is currently not much that can be done about that, so the return
    value of the iokit_mount is ignored.
    cc2f95a6