diff -purN -X /home/mbligh/.diff.exclude 545-aio-O_SYNC/fs/hugetlbfs/inode.c 550-gang_lookup_next/fs/hugetlbfs/inode.c --- 545-aio-O_SYNC/fs/hugetlbfs/inode.c 2004-02-18 14:57:15.000000000 -0800 +++ 550-gang_lookup_next/fs/hugetlbfs/inode.c 2004-02-20 15:41:06.000000000 -0800 @@ -165,7 +165,7 @@ void truncate_hugepages(struct address_s pagevec_init(&pvec, 0); next = start; while (1) { - if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) { + if (!pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) { if (next == start) break; next = start; @@ -176,9 +176,6 @@ void truncate_hugepages(struct address_s struct page *page = pvec.pages[i]; lock_page(page); - if (page->index > next) - next = page->index; - ++next; truncate_huge_page(page); unlock_page(page); hugetlb_put_quota(mapping); diff -purN -X /home/mbligh/.diff.exclude 545-aio-O_SYNC/include/linux/pagemap.h 550-gang_lookup_next/include/linux/pagemap.h --- 545-aio-O_SYNC/include/linux/pagemap.h 2004-02-20 15:40:47.000000000 -0800 +++ 550-gang_lookup_next/include/linux/pagemap.h 2004-02-20 15:41:06.000000000 -0800 @@ -70,7 +70,7 @@ extern struct page * find_trylock_page(s extern struct page * find_or_create_page(struct address_space *mapping, unsigned long index, unsigned int gfp_mask); extern unsigned int find_get_pages(struct address_space *mapping, - pgoff_t start, unsigned int nr_pages, + pgoff_t *next, unsigned int nr_pages, struct page **pages); /* diff -purN -X /home/mbligh/.diff.exclude 545-aio-O_SYNC/include/linux/pagevec.h 550-gang_lookup_next/include/linux/pagevec.h --- 545-aio-O_SYNC/include/linux/pagevec.h 2002-12-09 18:46:25.000000000 -0800 +++ 550-gang_lookup_next/include/linux/pagevec.h 2004-02-20 15:41:06.000000000 -0800 @@ -23,7 +23,7 @@ void __pagevec_lru_add(struct pagevec *p void __pagevec_lru_add_active(struct pagevec *pvec); void pagevec_strip(struct pagevec *pvec); unsigned int pagevec_lookup(struct pagevec *pvec, struct address_space *mapping, - pgoff_t start, unsigned int nr_pages); + pgoff_t *next, unsigned int nr_pages); static inline void pagevec_init(struct pagevec *pvec, int cold) { diff -purN -X /home/mbligh/.diff.exclude 545-aio-O_SYNC/mm/filemap.c 550-gang_lookup_next/mm/filemap.c --- 545-aio-O_SYNC/mm/filemap.c 2004-02-20 15:41:01.000000000 -0800 +++ 550-gang_lookup_next/mm/filemap.c 2004-02-20 15:41:06.000000000 -0800 @@ -571,9 +571,12 @@ EXPORT_SYMBOL(find_or_create_page); * The search returns a group of mapping-contiguous pages with ascending * indexes. There may be holes in the indices due to not-present pages. * - * find_get_pages() returns the number of pages which were found. + * find_get_pages() returns the number of pages which were found + * and also atomically sets the next offset to continue looking up + * mapping contiguous pages from (useful when doing a range of + * pagevec lookups in chunks of PAGEVEC_SIZE). */ -unsigned int find_get_pages(struct address_space *mapping, pgoff_t start, +unsigned int find_get_pages(struct address_space *mapping, pgoff_t *next, unsigned int nr_pages, struct page **pages) { unsigned int i; @@ -581,9 +584,12 @@ unsigned int find_get_pages(struct addre spin_lock(&mapping->page_lock); ret = radix_tree_gang_lookup(&mapping->page_tree, - (void **)pages, start, nr_pages); + (void **)pages, *next, nr_pages); for (i = 0; i < ret; i++) page_cache_get(pages[i]); + if (ret) + *next = pages[ret - 1]->index + 1; + spin_unlock(&mapping->page_lock); return ret; } diff -purN -X /home/mbligh/.diff.exclude 545-aio-O_SYNC/mm/swap.c 550-gang_lookup_next/mm/swap.c --- 545-aio-O_SYNC/mm/swap.c 2004-01-15 10:41:20.000000000 -0800 +++ 550-gang_lookup_next/mm/swap.c 2004-02-20 15:41:06.000000000 -0800 @@ -348,12 +348,15 @@ void pagevec_strip(struct pagevec *pvec) * The search returns a group of mapping-contiguous pages with ascending * indexes. There may be holes in the indices due to not-present pages. * - * pagevec_lookup() returns the number of pages which were found. + * pagevec_lookup() returns the number of pages which were found + * and also atomically sets the next offset to continue looking up + * mapping contiguous pages from (useful when doing a range of + * pagevec lookups in chunks of PAGEVEC_SIZE). */ unsigned int pagevec_lookup(struct pagevec *pvec, struct address_space *mapping, - pgoff_t start, unsigned int nr_pages) + pgoff_t *next, unsigned int nr_pages) { - pvec->nr = find_get_pages(mapping, start, nr_pages, pvec->pages); + pvec->nr = find_get_pages(mapping, next, nr_pages, pvec->pages); return pagevec_count(pvec); } diff -purN -X /home/mbligh/.diff.exclude 545-aio-O_SYNC/mm/truncate.c 550-gang_lookup_next/mm/truncate.c --- 545-aio-O_SYNC/mm/truncate.c 2003-10-14 15:50:36.000000000 -0700 +++ 550-gang_lookup_next/mm/truncate.c 2004-02-20 15:41:06.000000000 -0800 @@ -122,14 +122,10 @@ void truncate_inode_pages(struct address pagevec_init(&pvec, 0); next = start; - while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) { + while (pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) { for (i = 0; i < pagevec_count(&pvec); i++) { struct page *page = pvec.pages[i]; - pgoff_t page_index = page->index; - if (page_index > next) - next = page_index; - next++; if (TestSetPageLocked(page)) continue; if (PageWriteback(page)) { @@ -155,7 +151,7 @@ void truncate_inode_pages(struct address next = start; for ( ; ; ) { - if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) { + if (!pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) { if (next == start) break; next = start; @@ -166,9 +162,6 @@ void truncate_inode_pages(struct address lock_page(page); wait_on_page_writeback(page); - if (page->index > next) - next = page->index; - next++; truncate_complete_page(mapping, page); unlock_page(page); } @@ -201,17 +194,13 @@ unsigned long invalidate_mapping_pages(s pagevec_init(&pvec, 0); while (next <= end && - pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) { + pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) { for (i = 0; i < pagevec_count(&pvec); i++) { struct page *page = pvec.pages[i]; if (TestSetPageLocked(page)) { - next++; continue; } - if (page->index > next) - next = page->index; - next++; if (PageDirty(page) || PageWriteback(page)) goto unlock; if (page_mapped(page)) @@ -250,14 +239,13 @@ void invalidate_inode_pages2(struct addr int i; pagevec_init(&pvec, 0); - while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) { + while (pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) { for (i = 0; i < pagevec_count(&pvec); i++) { struct page *page = pvec.pages[i]; lock_page(page); if (page->mapping == mapping) { /* truncate race? */ wait_on_page_writeback(page); - next = page->index + 1; if (page_mapped(page)) clear_page_dirty(page); else