summaryrefslogtreecommitdiffstats
path: root/mm/page_io.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-01-27 01:05:20 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-01-27 01:05:20 +0000
commit546db14ee74118296f425f3b91634fb767d67290 (patch)
tree22b613a3da8d4bf663eec5e155af01b87fdf9094 /mm/page_io.c
parent1e25e41c4f5474e14452094492dbc169b800e4c8 (diff)
Merge with Linux 2.3.23. The new bootmem stuff has broken various
platforms. At this time I've only verified that IP22 support compiles and IP27 actually works.
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);
}