Re: [RFC] ext3/jbd race: releasing in-use journal_heads

From: Andrew Morton
Date: Mon Mar 07 2005 - 19:01:57 EST


"Stephen C. Tweedie" <sct@xxxxxxxxxx> 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/