Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 140192
b: refs/heads/master
c: 03fb3d2
h: refs/heads/master
v: v3
  • Loading branch information
David Howells committed Apr 3, 2009
1 parent 1997a2b commit 1a2cc92
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8f0aa2f25b31ba27db84259141e52ee6ec0d2820
refs/heads/master: 03fb3d2af96c2783c3a5bc03f3d984cf422f0e69
2 changes: 1 addition & 1 deletion trunk/include/linux/page-flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ static inline int TestClearPage##uname(struct page *page) { return 0; }

struct page; /* forward declaration */

TESTPAGEFLAG(Locked, locked)
TESTPAGEFLAG(Locked, locked) TESTSETFLAG(Locked, locked)
PAGEFLAG(Error, error)
PAGEFLAG(Referenced, referenced) TESTCLEARFLAG(Referenced, referenced)
PAGEFLAG(Dirty, dirty) TESTSCFLAG(Dirty, dirty) __CLEARPAGEFLAG(Dirty, dirty)
Expand Down
39 changes: 37 additions & 2 deletions trunk/mm/readahead.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,41 @@ EXPORT_SYMBOL_GPL(file_ra_state_init);

#define list_to_page(head) (list_entry((head)->prev, struct page, lru))

/*
* see if a page needs releasing upon read_cache_pages() failure
* - the caller of read_cache_pages() may have set PG_private before calling,
* such as the NFS fs marking pages that are cached locally on disk, thus we
* need to give the fs a chance to clean up in the event of an error
*/
static void read_cache_pages_invalidate_page(struct address_space *mapping,
struct page *page)
{
if (PagePrivate(page)) {
if (!trylock_page(page))
BUG();
page->mapping = mapping;
do_invalidatepage(page, 0);
page->mapping = NULL;
unlock_page(page);
}
page_cache_release(page);
}

/*
* release a list of pages, invalidating them first if need be
*/
static void read_cache_pages_invalidate_pages(struct address_space *mapping,
struct list_head *pages)
{
struct page *victim;

while (!list_empty(pages)) {
victim = list_to_page(pages);
list_del(&victim->lru);
read_cache_pages_invalidate_page(mapping, victim);
}
}

/**
* read_cache_pages - populate an address space with some pages & start reads against them
* @mapping: the address_space
Expand All @@ -52,14 +87,14 @@ int read_cache_pages(struct address_space *mapping, struct list_head *pages,
list_del(&page->lru);
if (add_to_page_cache_lru(page, mapping,
page->index, GFP_KERNEL)) {
page_cache_release(page);
read_cache_pages_invalidate_page(mapping, page);
continue;
}
page_cache_release(page);

ret = filler(data, page);
if (unlikely(ret)) {
put_pages_list(pages);
read_cache_pages_invalidate_pages(mapping, pages);
break;
}
task_io_account_read(PAGE_CACHE_SIZE);
Expand Down

0 comments on commit 1a2cc92

Please sign in to comment.