diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-27 20:07:35 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-27 20:07:35 -0500 |
commit | bc77789a491cdc6f47e5bbd1d04ddd283d64658b (patch) | |
tree | 7ee181b42c600a6456be1d337f47ff60f1c955c2 /fs | |
parent | 47a43f2f0ce24bb75e3e4500118000585a3b496a (diff) | |
parent | 3cc31fa65d85610574c0f6a474e89f4c419923d5 (diff) |
Merge tag 'iomap-4.21-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull iomap update from Darrick Wong:
"Fix a memory overflow bug for blocksize < pagesize"
* tag 'iomap-4.21-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
iomap: don't search past page end in iomap_is_partially_uptodate
Diffstat (limited to 'fs')
-rw-r--r-- | fs/iomap.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/fs/iomap.c b/fs/iomap.c index d6bc98ae8d35..ce837d962d47 100644 --- a/fs/iomap.c +++ b/fs/iomap.c | |||
@@ -492,16 +492,29 @@ done: | |||
492 | } | 492 | } |
493 | EXPORT_SYMBOL_GPL(iomap_readpages); | 493 | EXPORT_SYMBOL_GPL(iomap_readpages); |
494 | 494 | ||
495 | /* | ||
496 | * iomap_is_partially_uptodate checks whether blocks within a page are | ||
497 | * uptodate or not. | ||
498 | * | ||
499 | * Returns true if all blocks which correspond to a file portion | ||
500 | * we want to read within the page are uptodate. | ||
501 | */ | ||
495 | int | 502 | int |
496 | iomap_is_partially_uptodate(struct page *page, unsigned long from, | 503 | iomap_is_partially_uptodate(struct page *page, unsigned long from, |
497 | unsigned long count) | 504 | unsigned long count) |
498 | { | 505 | { |
499 | struct iomap_page *iop = to_iomap_page(page); | 506 | struct iomap_page *iop = to_iomap_page(page); |
500 | struct inode *inode = page->mapping->host; | 507 | struct inode *inode = page->mapping->host; |
501 | unsigned first = from >> inode->i_blkbits; | 508 | unsigned len, first, last; |
502 | unsigned last = (from + count - 1) >> inode->i_blkbits; | ||
503 | unsigned i; | 509 | unsigned i; |
504 | 510 | ||
511 | /* Limit range to one page */ | ||
512 | len = min_t(unsigned, PAGE_SIZE - from, count); | ||
513 | |||
514 | /* First and last blocks in range within page */ | ||
515 | first = from >> inode->i_blkbits; | ||
516 | last = (from + len - 1) >> inode->i_blkbits; | ||
517 | |||
505 | if (iop) { | 518 | if (iop) { |
506 | for (i = first; i <= last; i++) | 519 | for (i = first; i <= last; i++) |
507 | if (!test_bit(i, iop->uptodate)) | 520 | if (!test_bit(i, iop->uptodate)) |