> > > [snip] > > > > @@ -436,8 +485,20 @@ static ssize_t exfat_direct_IO(struct kiocb > > > > *iocb, struct iov_iter *iter) > > > > * condition of exfat_get_block() and ->truncate(). > > > > */ > > > > ret = blockdev_direct_IO(iocb, inode, iter, exfat_get_block); > > > > - if (ret < 0 && (rw & WRITE)) > > > > - exfat_write_failed(mapping, size); > > > > + if (ret < 0) { > > > > + if (rw & WRITE) > > > > + exfat_write_failed(mapping, size); > > > > + > > > > + if (ret != -EIOCBQUEUED) > > > > + return ret; > > > > + } else > > > > + size = pos + ret; > > > > + > > > > + if ((rw & READ) && pos < ei->valid_size && ei->valid_size < size) { > > > > + iov_iter_revert(iter, size - ei->valid_size); > > > > + iov_iter_zero(size - ei->valid_size, iter); > > > > + } > > > > > > This approach causes unnecessary reads to the range after > > > valid_size, > > right? > > > > I don't think so. > > > > If the blocks across valid_size, the iov_iter will be handle as 1. > > Read the blocks before valid_size. > > 2. Read the block where valid_size is located and set the area after > > valid_size to zero. > > 3. zero the buffer of the blocks after valid_size(not read from disk) > > > > So there are unnecessary zeroing here(in 1 and 2), no unnecessary reads. > > I will remove the unnecessary zeroing. > > You are right. There might be no need to change. > It could be handled in do_direct_IO() with get_block newly modifed. Since "size = pos + ret;" is updated to the actual read position, there is no unnecessary zeroing. The code does not need to be updated.