--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