summaryrefslogtreecommitdiffstats
path: root/mm/swapfile.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-05-07 02:55:41 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-05-07 02:55:41 +0000
commitdcec8a13bf565e47942a1751a9cec21bec5648fe (patch)
tree548b69625b18cc2e88c3e68d0923be546c9ebb03 /mm/swapfile.c
parent2e0f55e79c49509b7ff70ff1a10e1e9e90a3dfd4 (diff)
o Merge with Linux 2.1.99.
o Fix ancient bug in the ELF loader making ldd crash. o Fix ancient bug in the keyboard code for SGI, SNI and Jazz.
Diffstat (limited to 'mm/swapfile.c')
-rw-r--r--mm/swapfile.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 8608db8d8..f9cd0d47e 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -52,6 +52,8 @@ static inline int scan_swap_map(struct swap_info_struct *si)
offset = si->cluster_next++;
if (si->swap_map[offset])
continue;
+ if (test_bit(offset, si->swap_lockmap))
+ continue;
si->cluster_nr--;
goto got_page;
}
@@ -60,6 +62,8 @@ static inline int scan_swap_map(struct swap_info_struct *si)
for (offset = si->lowest_bit; offset <= si->highest_bit ; offset++) {
if (si->swap_map[offset])
continue;
+ if (test_bit(offset, si->swap_lockmap))
+ continue;
si->lowest_bit = offset;
got_page:
si->swap_map[offset] = 1;
@@ -424,6 +428,8 @@ asmlinkage int sys_swapoff(const char * specialfile)
p->swap_device = 0;
vfree(p->swap_map);
p->swap_map = NULL;
+ free_page((long) p->swap_lockmap);
+ p->swap_lockmap = NULL;
p->flags = 0;
err = 0;
out:
@@ -483,7 +489,6 @@ asmlinkage int sys_swapon(const char * specialfile, int swap_flags)
int error = -EPERM;
struct file filp;
static int least_priority = 0;
- unsigned char *avail_map = 0;
lock_kernel();
if (!suser())
@@ -501,6 +506,7 @@ asmlinkage int sys_swapon(const char * specialfile, int swap_flags)
p->swap_file = NULL;
p->swap_device = 0;
p->swap_map = NULL;
+ p->swap_lockmap = NULL;
p->lowest_bit = 0;
p->highest_bit = 0;
p->cluster_nr = 0;
@@ -543,24 +549,24 @@ asmlinkage int sys_swapon(const char * specialfile, int swap_flags)
}
} else if (!S_ISREG(swap_dentry->d_inode->i_mode))
goto bad_swap;
- avail_map = (unsigned char *) get_free_page(GFP_USER);
- if (!avail_map) {
+ p->swap_lockmap = (unsigned char *) get_free_page(GFP_USER);
+ if (!p->swap_lockmap) {
printk("Unable to start swapping: out of memory :-)\n");
error = -ENOMEM;
goto bad_swap;
}
- rw_swap_page_nocache(READ, SWP_ENTRY(type,0), (char *) avail_map);
- if (memcmp("SWAP-SPACE",avail_map+PAGE_SIZE-10,10)) {
+ rw_swap_page_nocache(READ, SWP_ENTRY(type,0), (char *) p->swap_lockmap);
+ if (memcmp("SWAP-SPACE",p->swap_lockmap+PAGE_SIZE-10,10)) {
printk("Unable to find swap-space signature\n");
error = -EINVAL;
goto bad_swap;
}
- memset(avail_map+PAGE_SIZE-10,0,10);
+ memset(p->swap_lockmap+PAGE_SIZE-10,0,10);
j = 0;
p->lowest_bit = 0;
p->highest_bit = 0;
for (i = 1 ; i < 8*PAGE_SIZE ; i++) {
- if (test_bit(i,avail_map)) {
+ if (test_bit(i,p->swap_lockmap)) {
if (!p->lowest_bit)
p->lowest_bit = i;
p->highest_bit = i;
@@ -579,12 +585,13 @@ asmlinkage int sys_swapon(const char * specialfile, int swap_flags)
goto bad_swap;
}
for (i = 1 ; i < p->max ; i++) {
- if (test_bit(i,avail_map))
+ if (test_bit(i,p->swap_lockmap))
p->swap_map[i] = 0;
else
p->swap_map[i] = 0x80;
}
p->swap_map[0] = 0x80;
+ memset(p->swap_lockmap,0,PAGE_SIZE);
p->flags = SWP_WRITEOK;
p->pages = j;
nr_swap_pages += j;
@@ -611,15 +618,15 @@ bad_swap:
if(filp.f_op && filp.f_op->release)
filp.f_op->release(filp.f_dentry->d_inode,&filp);
bad_swap_2:
+ free_page((long) p->swap_lockmap);
vfree(p->swap_map);
dput(p->swap_file);
p->swap_device = 0;
p->swap_file = NULL;
p->swap_map = NULL;
+ p->swap_lockmap = NULL;
p->flags = 0;
out:
- if (avail_map)
- free_page((long) avail_map);
unlock_kernel();
return error;
}