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.