"Stephen C. Tweedie" <[EMAIL PROTECTED]> wrote:
>
> In invalidate_inode_pages2_range(), what happens if we lookup a pagevec,
> get a bunch of pages back, but all the pages in the vec are beyond the
> end of the range we want?

hmm, yes.  Another one :(

> @@ -271,12 +271,13 @@ int invalidate_inode_pages2_range(struct
>                       int was_dirty;
>  
>                       lock_page(page);
> +                     if (page->mapping == mapping)
> +                             next = page->index + 1;
>                       if (page->mapping != mapping || page->index > end) {
>                               unlock_page(page);
>                               continue;
>                       }
>                       wait_on_page_writeback(page);
> -                     next = page->index + 1;
>                       if (next == 0)
>                               wrapped = 1;
>                       while (page_mapped(page)) {

truncate_inode_pages_range() seems to dtrt here.  Can we do it in the same
manner in invalidate_inode_pages2_range()?


Something like:


diff -puN mm/truncate.c~invalidate_inode_pages2_range-livelock-fix mm/truncate.c
--- 25/mm/truncate.c~invalidate_inode_pages2_range-livelock-fix Mon Mar  7 
15:47:25 2005
+++ 25-akpm/mm/truncate.c       Mon Mar  7 15:49:09 2005
@@ -305,15 +305,22 @@ int invalidate_inode_pages2_range(struct
                        min(end - next, (pgoff_t)PAGEVEC_SIZE - 1) + 1)) {
                for (i = 0; !ret && i < pagevec_count(&pvec); i++) {
                        struct page *page = pvec.pages[i];
+                       pgoff_t page_index;
                        int was_dirty;
 
                        lock_page(page);
-                       if (page->mapping != mapping || page->index > end) {
+                       page_index = page->index;
+                       if (page_index > end) {
+                               next = page_index;
+                               unlock_page(page);
+                               break;
+                       }
+                       if (page->mapping != mapping) {
                                unlock_page(page);
                                continue;
                        }
                        wait_on_page_writeback(page);
-                       next = page->index + 1;
+                       next = page_index + 1;
                        if (next == 0)
                                wrapped = 1;
                        while (page_mapped(page)) {
@@ -323,7 +330,7 @@ int invalidate_inode_pages2_range(struct
                                         */
                                        unmap_mapping_range(mapping,
                                            page->index << PAGE_CACHE_SHIFT,
-                                           (end - page->index + 1)
+                                           (end - page_index + 1)
                                                        << PAGE_CACHE_SHIFT,
                                            0);
                                        did_range_unmap = 1;
@@ -332,7 +339,7 @@ int invalidate_inode_pages2_range(struct
                                         * Just zap this page
                                         */
                                        unmap_mapping_range(mapping,
-                                         page->index << PAGE_CACHE_SHIFT,
+                                         page_index << PAGE_CACHE_SHIFT,
                                          PAGE_CACHE_SIZE, 0);
                                }
                        }
_

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to