New code for 5.6:
- Fix an off-by-one error when checking if offset is within inode size -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEUzaAxoMeQq6m2jMV+H93GTRKtOsFAl4vLo4ACgkQ+H93GTRK tOtFNg/+I0IVdJgzMPe6PoEhbMc80c1CK7yxjprtq6I1WV5/OVbpNSnXqym8vYPs atp+8loh9LMMYhi8ln0DyU0clu8p97+7D/aUqkN4DzKJ3t0T/LFR8NPHh7P7H3i/ rI0Ym8pTorueC3qgcVzgP2Xx8+yoURvlRV0VSd8C9Vza9E3g7U+8cAAzZz/iMbpy QbW32mrEWWtACLqVEj94+sNj9O4wHy1kefkBITWBkdmaWvqP6KBWJsdQrySHNHN4 BXEwOrfxM5w8isd9hOd3U6NPkY0I7EGq7K4aQhRzyoIw9LJ+APjpCvY1KpmFs1Ar 7yOM026MdZKGguL1cZcgXzFpIKbkv4xj4231RD6yKXUk1XhMIs+7JO+ontRekPg3 2oZgPJoz+5QXtcpJifKzwzwr32WFssX/HhYFlzbbq1SRlJBWEyKfPBXY8yoeAJJb lHK/fjsPwGeTgMG0/n3+r/GhO+3FDzDosFYHpD0IZIX08770tam7nB4hlGrJEel1 74/cxxphNeU1PkjV43V4vxTNucEkFNn+CDD9/9MvEx8ZXtz01HkIbEsANdyZM7yj SO0wjkHQjkm9YlBP+lh03ign4YQYYVQLN2zdw3VzK2QYo0GKln+o/wWrXhJksZ8t AT70yqYx2lntnkasvMPO02pgZulorM605mgUGkbwslcmuifvpo0= =iPhi -----END PGP SIGNATURE----- Merge tag 'iomap-5.6-merge-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux Pull iomap fix from Darrick Wong: "A single patch fixing an off-by-one error when we're checking to see how far we're gotten into an EOF page" * tag 'iomap-5.6-merge-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: fs: Fix page_mkwrite off-by-one errors
This commit is contained in:
commit
677b60dcb6
|
@ -1077,24 +1077,16 @@ vm_fault_t iomap_page_mkwrite(struct vm_fault *vmf, const struct iomap_ops *ops)
|
|||
struct page *page = vmf->page;
|
||||
struct inode *inode = file_inode(vmf->vma->vm_file);
|
||||
unsigned long length;
|
||||
loff_t offset, size;
|
||||
loff_t offset;
|
||||
ssize_t ret;
|
||||
|
||||
lock_page(page);
|
||||
size = i_size_read(inode);
|
||||
offset = page_offset(page);
|
||||
if (page->mapping != inode->i_mapping || offset > size) {
|
||||
/* We overload EFAULT to mean page got truncated */
|
||||
ret = -EFAULT;
|
||||
ret = page_mkwrite_check_truncate(page, inode);
|
||||
if (ret < 0)
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
/* page is wholly or partially inside EOF */
|
||||
if (offset > size - PAGE_SIZE)
|
||||
length = offset_in_page(size);
|
||||
else
|
||||
length = PAGE_SIZE;
|
||||
length = ret;
|
||||
|
||||
offset = page_offset(page);
|
||||
while (length > 0) {
|
||||
ret = iomap_apply(inode, offset, length,
|
||||
IOMAP_WRITE | IOMAP_FAULT, ops, page,
|
||||
|
|
|
@ -636,4 +636,32 @@ static inline unsigned long dir_pages(struct inode *inode)
|
|||
PAGE_SHIFT;
|
||||
}
|
||||
|
||||
/**
|
||||
* page_mkwrite_check_truncate - check if page was truncated
|
||||
* @page: the page to check
|
||||
* @inode: the inode to check the page against
|
||||
*
|
||||
* Returns the number of bytes in the page up to EOF,
|
||||
* or -EFAULT if the page was truncated.
|
||||
*/
|
||||
static inline int page_mkwrite_check_truncate(struct page *page,
|
||||
struct inode *inode)
|
||||
{
|
||||
loff_t size = i_size_read(inode);
|
||||
pgoff_t index = size >> PAGE_SHIFT;
|
||||
int offset = offset_in_page(size);
|
||||
|
||||
if (page->mapping != inode->i_mapping)
|
||||
return -EFAULT;
|
||||
|
||||
/* page is wholly inside EOF */
|
||||
if (page->index < index)
|
||||
return PAGE_SIZE;
|
||||
/* page is wholly past EOF */
|
||||
if (page->index > index || !offset)
|
||||
return -EFAULT;
|
||||
/* page is partially inside EOF */
|
||||
return offset;
|
||||
}
|
||||
|
||||
#endif /* _LINUX_PAGEMAP_H */
|
||||
|
|
Loading…
Reference in New Issue