From 546db14ee74118296f425f3b91634fb767d67290 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 27 Jan 2000 01:05:20 +0000 Subject: 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. --- mm/page_io.c | 53 ++++++++++++++++++----------------------------------- 1 file changed, 18 insertions(+), 35 deletions(-) (limited to 'mm/page_io.c') 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); } -- cgit v1.2.3