lkml.org 
[lkml]   [1998]   [Jul]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectNew patch: Swap fix plus patch for >128MB swap partitions
This patch obsoletes linux-patches ticket PR#218.  It implements large
swap partitions and fixes the 7-bit limit in the kernel's internal swap
map as before. The only difference from the last version is that it now
keeps the first 1k of the swap signature page unused, in line with
ext2fs, to allow space for boot/partitioning information.

--Stephen

----------------------------------------------------------------
--- include/linux/swap.h.~1~ Fri Jul 3 21:33:11 1998
+++ include/linux/swap.h Thu Jul 9 15:45:10 1998
@@ -7,6 +7,23 @@

#define MAX_SWAPFILES 8

+union swap_header {
+ struct
+ {
+ char reserved[PAGE_SIZE - 10];
+ char magic[10];
+ } magic;
+ struct
+ {
+ char bootbits[1024]; /* Space for disklabel etc. */
+ unsigned int version;
+ unsigned int last_page;
+ unsigned int nr_badpages;
+ unsigned int padding[125];
+ unsigned int badpages[1];
+ } info;
+};
+
#ifdef __KERNEL__

#undef DEBUG_SWAP
@@ -18,11 +35,14 @@

#define SWAP_CLUSTER_MAX 32

+#define SWAP_MAP_MAX 0x7fff
+#define SWAP_MAP_BAD 0x8000
+
struct swap_info_struct {
unsigned int flags;
kdev_t swap_device;
struct dentry * swap_file;
- unsigned char * swap_map;
+ unsigned short * swap_map;
unsigned char * swap_lockmap;
unsigned int lowest_bit;
unsigned int highest_bit;
--- mm/swapfile.c.~1~ Fri Jul 3 21:33:11 1998
+++ mm/swapfile.c Thu Jul 9 15:43:45 1998
@@ -116,10 +116,7 @@
}
}

-/*
- * If the swap count overflows (swap_map[] == 127), the entry is considered
- * "permanent" and can't be reclaimed until the swap device is closed.
- */
+
void swap_free(unsigned long entry)
{
struct swap_info_struct * p;
@@ -147,7 +144,7 @@
p->highest_bit = offset;
if (!p->swap_map[offset])
goto bad_free;
- if (p->swap_map[offset] < 127) {
+ if (p->swap_map[offset] < SWAP_MAP_MAX) {
if (!--p->swap_map[offset])
nr_swap_pages++;
}
@@ -309,7 +306,7 @@
* Find a swap page in use and read it in.
*/
for (i = 1 , entry = 0; i < si->max ; i++) {
- if (si->swap_map[i] > 0 && si->swap_map[i] != 0x80) {
+ if (si->swap_map[i] > 0 && si->swap_map[i] != SWAP_MAP_BAD) {
entry = SWP_ENTRY(type, i);
break;
}
@@ -334,7 +331,7 @@
delete_from_swap_cache(page_map);
free_page(page);
if (si->swap_map[i] != 0) {
- if (si->swap_map[i] != 127)
+ if (si->swap_map[i] != SWAP_MAP_MAX)
printk("try_to_unuse: entry %08lx "
"not in use\n", entry);
si->swap_map[i] = 0;
@@ -425,7 +422,7 @@
p->swap_device = 0;
vfree(p->swap_map);
p->swap_map = NULL;
- free_page((long) p->swap_lockmap);
+ vfree(p->swap_lockmap);
p->swap_lockmap = NULL;
p->flags = 0;
err = 0;
@@ -458,7 +455,7 @@
usedswap = 0;
for (j = 0; j < ptr->max; ++j)
switch (ptr->swap_map[j]) {
- case 128:
+ case SWAP_MAP_BAD:
case 0:
continue;
default:
@@ -486,7 +483,12 @@
int error = -EPERM;
struct file filp;
static int least_priority = 0;
-
+ union swap_header *swap_header = 0;
+ int swap_header_version;
+ int lock_map_size = PAGE_SIZE;
+ int nr_good_pages = 0;
+ char tmp_lock_map = 0;
+
lock_kernel();
if (!capable(CAP_SYS_ADMIN))
goto out;
@@ -546,54 +548,114 @@
}
} else if (!S_ISREG(swap_dentry->d_inode->i_mode))
goto bad_swap;
- p->swap_lockmap = (unsigned char *) get_free_page(GFP_USER);
- if (!p->swap_lockmap) {
+ swap_header = (void *) __get_free_page(GFP_USER);
+ if (!swap_header) {
printk("Unable to start swapping: out of memory :-)\n");
error = -ENOMEM;
goto bad_swap;
}
- rw_swap_page_nocache(READ, SWP_ENTRY(type,0), (char *) p->swap_lockmap);
- if (memcmp("SWAP-SPACE",p->swap_lockmap+PAGE_SIZE-10,10)) {
+
+ p->swap_lockmap = &tmp_lock_map;
+ rw_swap_page_nocache(READ, SWP_ENTRY(type,0), (char *) swap_header);
+ p->swap_lockmap = 0;
+
+ if (!memcmp("SWAP-SPACE",swap_header->magic.magic,10))
+ swap_header_version = 1;
+ else if (!memcmp("SWAPSPACE2",swap_header->magic.magic,10))
+ swap_header_version = 2;
+ else {
printk("Unable to find swap-space signature\n");
error = -EINVAL;
goto bad_swap;
}
- 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,p->swap_lockmap)) {
- if (!p->lowest_bit)
- p->lowest_bit = i;
- p->highest_bit = i;
- p->max = i+1;
- j++;
+
+ switch (swap_header_version) {
+ case 1:
+ memset(((char *) swap_header)+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,(char *) swap_header)) {
+ if (!p->lowest_bit)
+ p->lowest_bit = i;
+ p->highest_bit = i;
+ p->max = i+1;
+ j++;
+ }
+ }
+ nr_good_pages = j;
+ p->swap_map = vmalloc(p->max * sizeof(short));
+ if (!p->swap_map) {
+ error = -ENOMEM;
+ goto bad_swap;
}
+ for (i = 1 ; i < p->max ; i++) {
+ if (test_bit(i,(char *) swap_header))
+ p->swap_map[i] = 0;
+ else
+ p->swap_map[i] = SWAP_MAP_BAD;
+ }
+ break;
+
+ case 2:
+ /* Check the swap header's sub-version and the size of
+ the swap file and bad block lists */
+ if (swap_header->info.version != 1) {
+ printk(KERN_WARNING
+ "Unable to handle swap header version %d\n",
+ swap_header->info.version);
+ error = -EINVAL;
+ goto bad_swap;
+ }
+
+ p->lowest_bit = 1;
+ p->highest_bit = swap_header->info.last_page - 1;
+ p->max = swap_header->info.last_page;
+
+ if (p->max >= 0x7fffffffL/PAGE_SIZE ||
+ (void *) &swap_header->info.badpages[swap_header->info.nr_badpages-1] >= (void *) swap_header->magic.magic) {
+ error = -EINVAL;
+ goto bad_swap;
+ }
+
+ /* OK, set up the swap map and apply the bad block list */
+ if (!(p->swap_map = vmalloc (p->max * sizeof(short)))) {
+ error = -ENOMEM;
+ goto bad_swap;
+ }
+
+ error = 0;
+ memset(p->swap_map, 0, p->max * sizeof(short));
+ for (i=0; i<swap_header->info.nr_badpages; i++) {
+ int page = swap_header->info.badpages[i];
+ if (page <= 0 || page >= swap_header->info.last_page)
+ error = -EINVAL;
+ else
+ p->swap_map[page] = SWAP_MAP_BAD;
+ }
+ nr_good_pages = swap_header->info.last_page - i;
+ lock_map_size = (p->max + 7) / 8;
+ if (error)
+ goto bad_swap;
}
- if (!j) {
- printk("Empty swap-file\n");
+
+ if (!nr_good_pages) {
+ printk(KERN_WARNING "Empty swap-file\n");
error = -EINVAL;
goto bad_swap;
}
- p->swap_map = (unsigned char *) vmalloc(p->max);
- if (!p->swap_map) {
+ p->swap_map[0] = SWAP_MAP_BAD;
+ if (!(p->swap_lockmap = vmalloc (lock_map_size))) {
error = -ENOMEM;
goto bad_swap;
}
- for (i = 1 ; i < p->max ; i++) {
- 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);
+ memset(p->swap_lockmap,0,lock_map_size);
p->flags = SWP_WRITEOK;
- p->pages = j;
- nr_swap_pages += j;
+ p->pages = nr_good_pages;
+ nr_swap_pages += nr_good_pages;
printk(KERN_INFO "Adding Swap: %dk swap-space (priority %d)\n",
- j<<(PAGE_SHIFT-10), p->prio);
+ nr_good_pages<<(PAGE_SHIFT-10), p->prio);

/* insert swap space into swap_list: */
prev = -1;
@@ -615,8 +677,10 @@
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);
+ if (p->swap_lockmap)
+ vfree(p->swap_lockmap);
+ if (p->swap_map)
+ vfree(p->swap_map);
dput(p->swap_file);
p->swap_device = 0;
p->swap_file = NULL;
@@ -624,6 +688,8 @@
p->swap_lockmap = NULL;
p->flags = 0;
out:
+ if (swap_header)
+ free_page((long) swap_header);
unlock_kernel();
return error;
}
@@ -638,7 +704,7 @@
continue;
for (j = 0; j < swap_info[i].max; ++j)
switch (swap_info[i].swap_map[j]) {
- case 128:
+ case SWAP_MAP_BAD:
continue;
case 0:
++val->freeswap;
----------------------------------------------------------------
begin 644 mkbigswap.c.gz
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
L+O?3QNDN5;CY_X\P;=PJV,PCP6K0S:[R#6PDWVXT"'WJ#OX#X!T?;Q86````
`
end
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu

\
 
 \ /
  Last update: 2005-03-22 13:43    [W:0.203 / U:0.176 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site