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.
Did you lowercase just to stick with our same conventions? I'd be wary about changing what the OS is giving us, and if it's against our conventions it's not really our fault.