Message ID | PUZPR04MB631609520C4F2CE212A9A5F781712@PUZPR04MB6316.apcprd04.prod.outlook.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v1] exfat: fix zero the unwritten part for dio read | expand |
2024-01-18 18:43 GMT+09:00, Yuezhang.Mo@sony.com <Yuezhang.Mo@sony.com>: > For dio read, bio will be leave in flight when a successful partial > aio read have been setup, blockdev_direct_IO() will return > -EIOCBQUEUED. In the case, iter->iov_offset will be not advanced, > the oops reported by syzbot will occur if revert iter->iov_offset > with iov_iter_revert(). The unwritten part had been zeroed by aio > read, so there is no need to zero it in dio read. > > Reported-by: syzbot+fd404f6b03a58e8bc403@syzkaller.appspotmail.com > Closes: https://syzkaller.appspot.com/bug?extid=fd404f6b03a58e8bc403 > Fixes: 11a347fb6cef ("exfat: change to get file size from DataLength") > Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com> Applied, Thanks for your patch!
diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c index 522edcbb2ce4..0687f952956c 100644 --- a/fs/exfat/inode.c +++ b/fs/exfat/inode.c @@ -501,7 +501,7 @@ static ssize_t exfat_direct_IO(struct kiocb *iocb, struct iov_iter *iter) struct inode *inode = mapping->host; struct exfat_inode_info *ei = EXFAT_I(inode); loff_t pos = iocb->ki_pos; - loff_t size = iocb->ki_pos + iov_iter_count(iter); + loff_t size = pos + iov_iter_count(iter); int rw = iov_iter_rw(iter); ssize_t ret; @@ -525,11 +525,10 @@ static ssize_t exfat_direct_IO(struct kiocb *iocb, struct iov_iter *iter) */ ret = blockdev_direct_IO(iocb, inode, iter, exfat_get_block); if (ret < 0) { - if (rw == WRITE) + if (rw == WRITE && ret != -EIOCBQUEUED) exfat_write_failed(mapping, size); - if (ret != -EIOCBQUEUED) - return ret; + return ret; } else size = pos + ret;
For dio read, bio will be leave in flight when a successful partial aio read have been setup, blockdev_direct_IO() will return -EIOCBQUEUED. In the case, iter->iov_offset will be not advanced, the oops reported by syzbot will occur if revert iter->iov_offset with iov_iter_revert(). The unwritten part had been zeroed by aio read, so there is no need to zero it in dio read. Reported-by: syzbot+fd404f6b03a58e8bc403@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=fd404f6b03a58e8bc403 Fixes: 11a347fb6cef ("exfat: change to get file size from DataLength") Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com> --- fs/exfat/inode.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)