The modifications made to vdev_read in r325310 to support read offsets and sizes not aligned with sector boundaries contains at least one bug, which will corrupt memory when triggered. If the read is not aligned to an underlying sector boundary, or the extent of the read does not cover a multiple of the underlying sector size, a bounce buffer will be used. If a bounce buffer is used and the requested read size (bytes parameter) is greater than the bounce buffer size (which is set to the underlying sector size), the first call to read() will overrun the end of the bounce buffer, as rb_size is still set to the value of the bytes parameter.
This patch fixes the bug described above and also rewrites the routine to be much easier to verify step-by-step for all of the read alignment and size cases.