ext4_find_unwritten_pgoff() needs few tweaks to work with huge pages.
Mostly trivial page_mapping()/page_to_pgoff() and adjustment to how we
find relevant block.

Signe-off-by: Kirill A. Shutemov <kirill.shute...@linux.intel.com>
---
 fs/ext4/file.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index d663d3d7c81c..0b11aadfb75f 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -519,7 +519,7 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
                         * range, it will be a hole.
                         */
                        if (lastoff < endoff && whence == SEEK_HOLE &&
-                           page->index > end) {
+                           page_to_pgoff(page) > end) {
                                found = 1;
                                *offset = lastoff;
                                goto out;
@@ -527,7 +527,7 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
 
                        lock_page(page);
 
-                       if (unlikely(page->mapping != inode->i_mapping)) {
+                       if (unlikely(page_mapping(page) != inode->i_mapping)) {
                                unlock_page(page);
                                continue;
                        }
@@ -538,8 +538,12 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
                        }
 
                        if (page_has_buffers(page)) {
+                               int diff;
                                lastoff = page_offset(page);
                                bh = head = page_buffers(page);
+                               diff = (page - compound_head(page)) << 
inode->i_blkbits;
+                               while (diff--)
+                                       bh = bh->b_this_page;
                                do {
                                        if (buffer_uptodate(bh) ||
                                            buffer_unwritten(bh)) {
@@ -560,8 +564,12 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
                                } while (bh != head);
                        }
 
-                       lastoff = page_offset(page) + PAGE_SIZE;
+                       lastoff = page_offset(page) + hpage_size(page);
                        unlock_page(page);
+                       if (PageTransCompound(page)) {
+                               i++;
+                               break;
+                       }
                }
 
                /*
@@ -574,7 +582,9 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
                        break;
                }
 
-               index = pvec.pages[i - 1]->index + 1;
+               index = page_to_pgoff(pvec.pages[i - 1]) + 1;
+               if (PageTransCompound(pvec.pages[i - 1]))
+                       index = round_up(index, HPAGE_PMD_NR);
                pagevec_release(&pvec);
        } while (index <= end);
 
-- 
2.11.0

Reply via email to