Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 179987
b: refs/heads/master
c: 0531b2a
h: refs/heads/master
i:
  179985: 632f9bd
  179983: d88a830
v: v3
  • Loading branch information
Linus Torvalds committed Jan 27, 2010
1 parent 7383877 commit 26d242d
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 33 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: caf0801e0cc482497c14a9ce349469c33c60beec
refs/heads/master: 0531b2aac59c2296570ac52bfc032ef2ace7d5e1
2 changes: 2 additions & 0 deletions trunk/include/linux/pagemap.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ extern struct page * read_cache_page_async(struct address_space *mapping,
extern struct page * read_cache_page(struct address_space *mapping,
pgoff_t index, filler_t *filler,
void *data);
extern struct page * read_cache_page_gfp(struct address_space *mapping,
pgoff_t index, gfp_t gfp_mask);
extern int read_cache_pages(struct address_space *mapping,
struct list_head *pages, filler_t *filler, void *data);

Expand Down
100 changes: 68 additions & 32 deletions trunk/mm/filemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1634,14 +1634,15 @@ EXPORT_SYMBOL(generic_file_readonly_mmap);
static struct page *__read_cache_page(struct address_space *mapping,
pgoff_t index,
int (*filler)(void *,struct page*),
void *data)
void *data,
gfp_t gfp)
{
struct page *page;
int err;
repeat:
page = find_get_page(mapping, index);
if (!page) {
page = page_cache_alloc_cold(mapping);
page = __page_cache_alloc(gfp | __GFP_COLD);
if (!page)
return ERR_PTR(-ENOMEM);
err = add_to_page_cache_lru(page, mapping, index, GFP_KERNEL);
Expand All @@ -1661,31 +1662,18 @@ static struct page *__read_cache_page(struct address_space *mapping,
return page;
}

/**
* read_cache_page_async - read into page cache, fill it if needed
* @mapping: the page's address_space
* @index: the page index
* @filler: function to perform the read
* @data: destination for read data
*
* Same as read_cache_page, but don't wait for page to become unlocked
* after submitting it to the filler.
*
* Read into the page cache. If a page already exists, and PageUptodate() is
* not set, try to fill the page but don't wait for it to become unlocked.
*
* If the page does not get brought uptodate, return -EIO.
*/
struct page *read_cache_page_async(struct address_space *mapping,
static struct page *do_read_cache_page(struct address_space *mapping,
pgoff_t index,
int (*filler)(void *,struct page*),
void *data)
void *data,
gfp_t gfp)

{
struct page *page;
int err;

retry:
page = __read_cache_page(mapping, index, filler, data);
page = __read_cache_page(mapping, index, filler, data, gfp);
if (IS_ERR(page))
return page;
if (PageUptodate(page))
Expand All @@ -1710,8 +1698,67 @@ struct page *read_cache_page_async(struct address_space *mapping,
mark_page_accessed(page);
return page;
}

/**
* read_cache_page_async - read into page cache, fill it if needed
* @mapping: the page's address_space
* @index: the page index
* @filler: function to perform the read
* @data: destination for read data
*
* Same as read_cache_page, but don't wait for page to become unlocked
* after submitting it to the filler.
*
* Read into the page cache. If a page already exists, and PageUptodate() is
* not set, try to fill the page but don't wait for it to become unlocked.
*
* If the page does not get brought uptodate, return -EIO.
*/
struct page *read_cache_page_async(struct address_space *mapping,
pgoff_t index,
int (*filler)(void *,struct page*),
void *data)
{
return do_read_cache_page(mapping, index, filler, data, mapping_gfp_mask(mapping));
}
EXPORT_SYMBOL(read_cache_page_async);

static struct page *wait_on_page_read(struct page *page)
{
if (!IS_ERR(page)) {
wait_on_page_locked(page);
if (!PageUptodate(page)) {
page_cache_release(page);
page = ERR_PTR(-EIO);
}
}
return page;
}

/**
* read_cache_page_gfp - read into page cache, using specified page allocation flags.
* @mapping: the page's address_space
* @index: the page index
* @gfp: the page allocator flags to use if allocating
*
* This is the same as "read_mapping_page(mapping, index, NULL)", but with
* any new page allocations done using the specified allocation flags. Note
* that the Radix tree operations will still use GFP_KERNEL, so you can't
* expect to do this atomically or anything like that - but you can pass in
* other page requirements.
*
* If the page does not get brought uptodate, return -EIO.
*/
struct page *read_cache_page_gfp(struct address_space *mapping,
pgoff_t index,
gfp_t gfp)
{
filler_t *filler = (filler_t *)mapping->a_ops->readpage;

return wait_on_page_read(do_read_cache_page(mapping, index, filler, NULL, gfp));
}
EXPORT_SYMBOL(read_cache_page_gfp);

/**
* read_cache_page - read into page cache, fill it if needed
* @mapping: the page's address_space
Expand All @@ -1729,18 +1776,7 @@ struct page *read_cache_page(struct address_space *mapping,
int (*filler)(void *,struct page*),
void *data)
{
struct page *page;

page = read_cache_page_async(mapping, index, filler, data);
if (IS_ERR(page))
goto out;
wait_on_page_locked(page);
if (!PageUptodate(page)) {
page_cache_release(page);
page = ERR_PTR(-EIO);
}
out:
return page;
return wait_on_page_read(read_cache_page_async(mapping, index, filler, data));
}
EXPORT_SYMBOL(read_cache_page);

Expand Down

0 comments on commit 26d242d

Please sign in to comment.