mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-15 23:25:07 +00:00
[GFS2] Bug fix to gfs2_readpages()
This fixes a bug where we were releasing a page incorrectly sometimes when reading a stuffed file. This fixes the bug that Kevin reported when using Xen. Cc: Kevin Anderson <kanderso@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
This commit is contained in:
parent
dc3e130a08
commit
ffeb874b2b
1 changed files with 5 additions and 5 deletions
|
@ -249,8 +249,6 @@ static int gfs2_readpage(struct file *file, struct page *page)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define list_to_page(head) (list_entry((head)->prev, struct page, lru))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gfs2_readpages - Read a bunch of pages at once
|
* gfs2_readpages - Read a bunch of pages at once
|
||||||
*
|
*
|
||||||
|
@ -290,7 +288,8 @@ static int gfs2_readpages(struct file *file, struct address_space *mapping,
|
||||||
struct pagevec lru_pvec;
|
struct pagevec lru_pvec;
|
||||||
pagevec_init(&lru_pvec, 0);
|
pagevec_init(&lru_pvec, 0);
|
||||||
for (page_idx = 0; page_idx < nr_pages; page_idx++) {
|
for (page_idx = 0; page_idx < nr_pages; page_idx++) {
|
||||||
struct page *page = list_to_page(pages);
|
struct page *page = list_entry(pages->prev, struct page, lru);
|
||||||
|
prefetchw(&page->flags);
|
||||||
list_del(&page->lru);
|
list_del(&page->lru);
|
||||||
if (!add_to_page_cache(page, mapping,
|
if (!add_to_page_cache(page, mapping,
|
||||||
page->index, GFP_KERNEL)) {
|
page->index, GFP_KERNEL)) {
|
||||||
|
@ -298,8 +297,9 @@ static int gfs2_readpages(struct file *file, struct address_space *mapping,
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
if (!pagevec_add(&lru_pvec, page))
|
if (!pagevec_add(&lru_pvec, page))
|
||||||
__pagevec_lru_add(&lru_pvec);
|
__pagevec_lru_add(&lru_pvec);
|
||||||
|
} else {
|
||||||
|
page_cache_release(page);
|
||||||
}
|
}
|
||||||
page_cache_release(page);
|
|
||||||
}
|
}
|
||||||
pagevec_lru_add(&lru_pvec);
|
pagevec_lru_add(&lru_pvec);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
@ -321,7 +321,7 @@ static int gfs2_readpages(struct file *file, struct address_space *mapping,
|
||||||
out_unlock:
|
out_unlock:
|
||||||
/* unlock all pages, we can't do any I/O right now */
|
/* unlock all pages, we can't do any I/O right now */
|
||||||
for (page_idx = 0; page_idx < nr_pages; page_idx++) {
|
for (page_idx = 0; page_idx < nr_pages; page_idx++) {
|
||||||
struct page *page = list_to_page(pages);
|
struct page *page = list_entry(pages->prev, struct page, lru);
|
||||||
list_del(&page->lru);
|
list_del(&page->lru);
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
page_cache_release(page);
|
page_cache_release(page);
|
||||||
|
|
Loading…
Reference in a new issue