Improve error messages for io::fs

This commit improves the error descriptions and details for the functions and methods exposed in `io::fs`.

The basic idea is that the description should always map onto the high-level operation that the user was trying to perform, with the `detail` containing the original message. The `IoErrorKind` is always maintained. The `detail` also includes additional information (most notably the relevant path, but also other parameters or contextual information).

I added an `UpdateIoError` trait to make it easier to do these in-place modification, and I'm eager for feedback on the specific strategy.
I feel like there is a conspiracy to make each method call at least 10 lines ;)