This looks sane - slightly updated version below to not bother with the ret and a few tidyups.
That being said and to get back to the discussion in this thread: I think it would be saner to give up on direct I/O in case of the invalidation failure. I've cooked up a patch on top of this one (for which I had a few trivial cleanups). It is still under testing, but I'll send the two out in a new thread.