|
|
@@ -488,16 +488,29 @@ done:
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(iomap_readpages);
|
|
|
|
|
|
+/*
|
|
|
+ * iomap_is_partially_uptodate checks whether blocks within a page are
|
|
|
+ * uptodate or not.
|
|
|
+ *
|
|
|
+ * Returns true if all blocks which correspond to a file portion
|
|
|
+ * we want to read within the page are uptodate.
|
|
|
+ */
|
|
|
int
|
|
|
iomap_is_partially_uptodate(struct page *page, unsigned long from,
|
|
|
unsigned long count)
|
|
|
{
|
|
|
struct iomap_page *iop = to_iomap_page(page);
|
|
|
struct inode *inode = page->mapping->host;
|
|
|
- unsigned first = from >> inode->i_blkbits;
|
|
|
- unsigned last = (from + count - 1) >> inode->i_blkbits;
|
|
|
+ unsigned len, first, last;
|
|
|
unsigned i;
|
|
|
|
|
|
+ /* Limit range to one page */
|
|
|
+ len = min_t(unsigned, PAGE_SIZE - from, count);
|
|
|
+
|
|
|
+ /* First and last blocks in range within page */
|
|
|
+ first = from >> inode->i_blkbits;
|
|
|
+ last = (from + len - 1) >> inode->i_blkbits;
|
|
|
+
|
|
|
if (iop) {
|
|
|
for (i = first; i <= last; i++)
|
|
|
if (!test_bit(i, iop->uptodate))
|