summaryrefslogtreecommitdiffstats
path: root/mm/page_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/page_io.c')
-rw-r--r--mm/page_io.c53
1 files changed, 18 insertions, 35 deletions
diff --git a/mm/page_io.c b/mm/page_io.c
index c89416bf9..3ce1a186c 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -33,7 +33,7 @@
* that shared pages stay shared while being swapped.
*/
-static void rw_swap_page_base(int rw, unsigned long entry, struct page *page, int wait)
+static int rw_swap_page_base(int rw, pte_t entry, struct page *page, int wait)
{
unsigned long type, offset;
struct swap_info_struct * p;
@@ -42,17 +42,10 @@ static void rw_swap_page_base(int rw, unsigned long entry, struct page *page, in
kdev_t dev = 0;
int block_size;
-#ifdef DEBUG_SWAP
- printk ("DebugVM: %s_swap_page entry %08lx, page %p (count %d), %s\n",
- (rw == READ) ? "read" : "write",
- entry, (char *) page_address(page), page_count(page),
- wait ? "wait" : "nowait");
-#endif
-
type = SWP_TYPE(entry);
if (type >= nr_swapfiles) {
printk("Internal error: bad swap-device\n");
- return;
+ return 0;
}
/* Don't allow too many pending pages in flight.. */
@@ -63,23 +56,16 @@ static void rw_swap_page_base(int rw, unsigned long entry, struct page *page, in
offset = SWP_OFFSET(entry);
if (offset >= p->max) {
printk("rw_swap_page: weirdness\n");
- return;
+ return 0;
}
if (p->swap_map && !p->swap_map[offset]) {
- printk(KERN_ERR "rw_swap_page: "
- "Trying to %s unallocated swap (%08lx)\n",
- (rw == READ) ? "read" : "write", entry);
- return;
+ pte_ERROR(entry);
+ return 0;
}
if (!(p->flags & SWP_USED)) {
printk(KERN_ERR "rw_swap_page: "
"Trying to swap to unused swap-device\n");
- return;
- }
-
- if (!PageLocked(page)) {
- printk(KERN_ERR "VM: swap page is unlocked\n");
- return;
+ return 0;
}
if (rw == READ) {
@@ -104,13 +90,13 @@ static void rw_swap_page_base(int rw, unsigned long entry, struct page *page, in
for (i=0, j=0; j< PAGE_SIZE ; i++, j += block_size)
if (!(zones[i] = bmap(swapf,block++))) {
printk("rw_swap_page: bad swap file\n");
- return;
+ return 0;
}
zones_used = i;
dev = swapf->i_dev;
} else {
printk(KERN_ERR "rw_swap_page: no swap file or device\n");
- return;
+ return 0;
}
if (!wait) {
set_bit(PG_decr_after, &page->flags);
@@ -124,20 +110,15 @@ static void rw_swap_page_base(int rw, unsigned long entry, struct page *page, in
* decrementing the page count, and unlocking the page in the
* swap lock map - in the IO completion handler.
*/
- if (!wait) {
- return;
- }
+ if (!wait)
+ return 1;
+
wait_on_page(page);
/* This shouldn't happen, but check to be sure. */
if (page_count(page) == 0)
printk(KERN_ERR "rw_swap_page: page unused while waiting!\n");
-#ifdef DEBUG_SWAP
- printk ("DebugVM: %s_swap_page finished on page %p (count %d)\n",
- (rw == READ) ? "read" : "write",
- (char *) page_address(page),
- page_count(page));
-#endif
+ return 1;
}
/*
@@ -149,7 +130,7 @@ static void rw_swap_page_base(int rw, unsigned long entry, struct page *page, in
*/
void rw_swap_page(int rw, struct page *page, int wait)
{
- unsigned long entry = page->offset;
+ pte_t entry = get_pagecache_pte(page);
if (!PageLocked(page))
PAGE_BUG(page);
@@ -157,7 +138,8 @@ void rw_swap_page(int rw, struct page *page, int wait)
PAGE_BUG(page);
if (page->inode != &swapper_inode)
PAGE_BUG(page);
- rw_swap_page_base(rw, entry, page, wait);
+ if (!rw_swap_page_base(rw, entry, page, wait))
+ UnlockPage(page);
}
/*
@@ -165,7 +147,7 @@ void rw_swap_page(int rw, struct page *page, int wait)
* Therefore we can't use it. Later when we can remove the need for the
* lock map and we can reduce the number of functions exported.
*/
-void rw_swap_page_nolock(int rw, unsigned long entry, char *buf, int wait)
+void rw_swap_page_nolock(int rw, pte_t entry, char *buf, int wait)
{
struct page *page = mem_map + MAP_NR(buf);
@@ -173,5 +155,6 @@ void rw_swap_page_nolock(int rw, unsigned long entry, char *buf, int wait)
PAGE_BUG(page);
if (PageSwapCache(page))
PAGE_BUG(page);
- rw_swap_page_base(rw, entry, page, wait);
+ if (!rw_swap_page_base(rw, entry, page, wait))
+ UnlockPage(page);
}