patch-2.1.120 linux/mm/swapfile.c
Next file: linux/net/Config.in
Previous file: linux/mm/swap_state.c
Back to the patch index
Back to the overall index
- Lines: 123
- Date:
Mon Aug 31 13:04:26 1998
- Orig file:
v2.1.119/linux/mm/swapfile.c
- Orig date:
Thu Aug 27 19:56:30 1998
diff -u --recursive --new-file v2.1.119/linux/mm/swapfile.c linux/mm/swapfile.c
@@ -297,30 +297,36 @@
{
struct swap_info_struct * si = &swap_info[type];
struct task_struct *p;
- unsigned long page = 0;
struct page *page_map;
- unsigned long entry;
+ unsigned long entry, page;
int i;
while (1) {
/*
* Find a swap page in use and read it in.
*/
- for (i = 1 , entry = 0; i < si->max ; i++) {
+ for (i = 1; i < si->max ; i++) {
if (si->swap_map[i] > 0 && si->swap_map[i] != SWAP_MAP_BAD) {
- entry = SWP_ENTRY(type, i);
- break;
+ goto found_entry;
}
}
- if (!entry)
- break;
+ break;
+
+ found_entry:
+ entry = SWP_ENTRY(type, i);
/* Get a page for the entry, using the existing swap
cache page if there is one. Otherwise, get a clean
page and read the swap into it. */
page_map = read_swap_cache(entry);
- if (!page_map)
- return -ENOMEM;
+ if (!page_map) {
+ /*
+ * Continue searching if the entry became unused.
+ */
+ if (si->swap_map[i] == 0)
+ continue;
+ return -ENOMEM;
+ }
page = page_address(page_map);
read_lock(&tasklist_lock);
for_each_task(p)
@@ -331,11 +337,15 @@
page we've been using. */
if (PageSwapCache(page_map))
delete_from_swap_cache(page_map);
- free_page(page);
+ __free_page(page_map);
+ /*
+ * Check for and clear any overflowed swap map counts.
+ */
if (si->swap_map[i] != 0) {
if (si->swap_map[i] != SWAP_MAP_MAX)
- printk("try_to_unuse: entry %08lx "
- "not in use\n", entry);
+ printk(KERN_ERR
+ "try_to_unuse: entry %08lx count=%d\n",
+ entry, si->swap_map[i]);
si->swap_map[i] = 0;
nr_swap_pages++;
}
@@ -376,10 +386,9 @@
prev = type;
}
err = -EINVAL;
- if (type < 0){
- dput(dentry);
- goto out;
- }
+ if (type < 0)
+ goto out_dput;
+
if (prev < 0) {
swap_list.head = p->next;
} else {
@@ -392,7 +401,6 @@
p->flags = SWP_USED;
err = try_to_unuse(type);
if (err) {
- dput(dentry);
/* re-insert swap space back into swap_list */
for (prev = -1, i = swap_list.head; i >= 0; prev = i, i = swap_info[i].next)
if (p->prio >= swap_info[i].prio)
@@ -403,7 +411,7 @@
else
swap_info[prev].next = p - swap_info;
p->flags = SWP_WRITEOK;
- goto out;
+ goto out_dput;
}
if(p->swap_device){
memset(&filp, 0, sizeof(filp));
@@ -418,9 +426,9 @@
}
dput(dentry);
- nr_swap_pages -= p->pages;
- dput(p->swap_file);
+ dentry = p->swap_file;
p->swap_file = NULL;
+ nr_swap_pages -= p->pages;
p->swap_device = 0;
vfree(p->swap_map);
p->swap_map = NULL;
@@ -428,6 +436,9 @@
p->swap_lockmap = NULL;
p->flags = 0;
err = 0;
+
+out_dput:
+ dput(dentry);
out:
unlock_kernel();
return err;
@@ -719,4 +730,3 @@
val->totalswap <<= PAGE_SHIFT;
return;
}
-
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov