On Mon, 2 Oct 2006 16:21:25 -0700 (PDT) Zach Brown <zach.brown@xxxxxxxxxx> wrote: > dio: centralize completion in dio_complete() > > The mechanics which decide the result of a direct IO operation were duplicated > in the sync and async paths. > > The async path didn't check page_errors which can manifest as silently > returning success when the final pointer in an operation faults and its > matching file region is filled with zeros. > > The sync path and async path differed in whether they passed errors to the > caller's dio->end_io operation. The async path was passing errors to it which > trips an assertion in XFS, though it is apparently harmless. > > This centralizes the completion phase of dio ops in one place. AIO will now > return EFAULT consistently and all paths fall back to the previously sync > behaviour of passing the number of bytes 'transferred' to the dio->end_io > callback, regardless of errors. > > dio_await_completion() doesn't have to propogate EIO from non-uptodate > bios now that it's being propogated through dio_complete() via dio->io_error. > This lets it return void which simplifies its sole caller. > > ... > > -static void dio_complete(struct dio *dio, loff_t offset, ssize_t bytes) > +static int dio_complete(struct dio *dio, loff_t offset, int ret) > { > + ssize_t transferred = 0; > + > + if (dio->result) { > + transferred = dio->result; > + > + /* Check for short read case */ > + if ((dio->rw == READ) && ((offset + transferred) > dio->i_size)) > + transferred = dio->i_size - offset; On 32-bit machines ssize_t is `int' and loff_t is `long long'. I guess `transferred' cannot overflow because you can't write >4G. And I guess `transferred' cannot go negative because you cannot write >=2G. Can you confirm that thinking? - To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html