Right now we get and release the header semaphore every time we
process a request for an rbd image. We do this because for write
requests we need to supply the snapshot context, and we can't
safely get a reference to it without holding that semaphore.
There's no need to get the snap context if we're doing a read,
so avoid doing so in that case.
The rbd_device->exists field can be updated asynchronously, changing
from set to clear if a mapped snapshot disappears from the base
image's snapshot context. Although I don't think synchronizing
access to this carefully is that critical, it is converted here to
be an atomic variable so a request is aware the flag is clear as
soon as that is known.