Messages in this thread Patch in this message | | | Date | Thu, 9 Jul 1998 20:35:14 +0100 | From | "Stephen C. Tweedie" <> | Subject | New 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 M'XL("%0%I34"`VUK8FEG<W=A<"YC`+58:W?;N!']3/V*L7)LDPHE2TK29N78 MNWDHJ;M)-K7LY)RZ/CH0"4I84Z#*AVWMKO][9P;@0Y(W[9?J^"$"@YD[@YF+ M`8\Z+>C`\B:[$ZM>`%W(9`[%"@3$2A?W0.,0REL52!0D6?>M!X,??AC`1Q3( MX"));T4<9CVX6*@,(A5+6(HUS"2D,E19GJI9D<L01`8KF9*&?"%Y\3T$R6J= MJODB[^'X4:MUQ!:&_=Y@V$,+T'5RM92H:RYT#SXD.7S]!'=)>J/T'-8RRV4: MDJTUA`D-Y00!GQ9"ASV+]S(KQ%R.K(]PU0VNK4-PE:G?9%?I[BQ.@IOLVJQP MN@%$28KP12AFL8I5OH9@(0.VZA:9!(4QTK',,E@G!8A4PN3R?+SG69,7Z*`U M84,A@$V4HZA=@%HB+D@B2+3T`8-DX*M,'^:D16I$$6#D7)I3^6$&&B.P+((% M1(7&9:@D6(A4!!B'4O6HZY6>?Q$YPL8]29,E_"KF\_5/JR)=Q3+OA7*9Z%Z0 M](H;<#^I&PE_%W/<+0_R!#'C,VX2Z=B,$*S0VE*2N625JT2+&$08(L9O^/M> MS@!>PJ`_>O9L]/P99<F+$LM;W))YB>7?A=*QT#_EJ=`9JA.(9`GN.Z&5C.$? M9I:A9,5JE:0<CEBD&"[>0TJRC/R_*"1;'3Z'_G#T8CAZ_I*LOK3I]$3I("Y" M":^R/%1);W':&"HT)F>X.4;9JN>;8U&@\WA;+(S5;&MLG1VI)-@1Q>$L%_GF MJ,B61RO<?1IM/0EEI+2$-Q]__C"^F)S]<PS]^\'P+WUR(-(X"],I5^-TVGH" M5OHVB46.<6@]D3I44:WF8CRYF+ZY?/]^?#[]\OK#>`(OJ[E/KS^<O9U.+L[/ M/G^`]N3;ZR^3+Z_?CH?M2N+K^'QR]LMG&+1:!%L%G&$8_E6:S''OIQKW'TZ@ M;<JI?;PE9K*PE/I\^?%C):%T#N_&7W&X.Z@&XP1KRL`\@?Z&+)<<CSK.4<<^ M4F'.1`@V'W&7&RMP@J*:&57()IPNTP46,F9L+/4\7V!]L;TI!WJVSB5KP6S` M?&J*_]YR,!V*`"M.S-%`R\$1A]U,92;36QE>U8JZF/;7QZ4`K[@R(P_FZ;A2 MI["N&]H<H,\L2?*9RC-<-'Q^?4P.3U8"ZYD<QL*\B<4,:T/F08_@.DZA,S77 M6'7D^*U,,\1_O#T>BRR?4DAV9G0Z+:.U,[?"DL8RN!H,7USO3):KK@;&.?+F MN/5P7.7+;B0CE58P+,5_M=E+-8Y\!/,@@!N=W"'M",N#82*)"3'8>9$B^W]; M2`UYND9D?(@D>'HL5ZR#Q`M-II9*JWN_*@Z8JUO<7P%W(M6XT,=3B*GU7N6N M9ZC6%A0?4-6ZAC;#)=7,;:)"B$0NXJE,TR1U@T1G>9G^T3*?&A+Q6KC!T0J_ MYI&+A('"?CWK-\O);Q2-AT%E=`/\]E!7=9%A^!!RTW+[,N.3;3\SI]H1ZCGB MRKNR!]J_=-NK5(1*(I!T2\=^-H(VX#BT6;K%#G*Q38T6ET;8G8U$"(HTE;I* M+QH*DVDF)=7L@-.])H99$44RK>L%<Z?E-#68DG54!.X>&_>H`!VS^91H+>=N M0?%W-U:],MQAA&EQ">'@`&+ZXB+C^,TEG0J#/QF/?YY.QA<>[)U0,3XJY>&, M0Z%KL]Y((`@*P$:(VK1M;-^M8^#6[+!WPMT$@[&Q\&L6\O###A@-O`$=#P[J MNNE1E?6JTBN_/!U<PRFM(P:IUC66,?.8OQZ0H/$D3^B0U^L&DQH/;/P;@?#J M5:S7]C&%MMV1M`O_.]:GUQB3K:1QG'J:'A^VMH%''TQ:E)*$R)95>S]D%VA\ M/\/T]4LAOQ(_'7@_MK/VJ,U`MV$V:!#1U8SXT-HXH+##5>$TB2+JCEU*]2CT MN0K,&%<')WJPH,PFO)Q^X)*@$?*A[V'"]KTJKZN4IV`:T8-@X<.`Y`9;<O;K MH`F.ZS`I,%KV/+38&`]]76!S[:,/=X0*_]DRHT/%I3DNU2WW"`;-><?\#SHG M,"0L9CD-'5?%2&.OC%B7$?.IQHQ(YI>8D2=&ZJG1"4<P)"SL]JY=7.!QRAEC M^$AI(3&6-&@1FU%,B]WU?:^.E#5KB;01L;E$&L:^MDG=T*&FLHR;$X6&TAR2 M([P1.9*LI'9)SH=?IN?OOIU[=O]PEC:6BWAEB)75,?B2S<M$YBZ1T=8='VX\ M6?+@]*34$\1))E&,E90ND1`>,R\&0ZO0:3%$*JU&'MAE3156@_$'X\';(Y3F MC,'6.O#M&=:AI]LZH_&H7:[J[H7BR'^0QBSMSY.DK!OC(1E)(K<N-F)8V*!4 M9!1PVZ]C/$^66.UXL"=%R29&"6$B&N\8.%3T&QTHC]>92.+=+IQ2\5#X:-:0 MBE5V>]6_QA]"<M@]]$JV:YZ]AH2=LAU%C_,D+M?Z!Q@'O^^=GEIB_]O9^XON MH&_XCW5U4,(0IF//:YY[@#*!G<WVV&HN4QRL*YVG3^T,*\ON%-[CFCZ40`.! MBPZ#PY$YC$ZPE&=()3?'UE8DBC@?P0:6*@V;4##,>XV#M`Q`52@;03JJ=[). MZKV=.&[U/F2<FPTNCQ%\3NX6,N4&T+YRX*M=HG\D'B?IYGXS^-H/:]3@1*KL M_T\FV0!>U@5H*<.,3-/5'-MDB7TR[,?AS9O'C",A]^DZ71WG1T!=^O<PG8+; MO__K>_/YV`R9.>K!?LI(_ZGT\:Y;P#[9CG:$E5/H`+D-CZG:073M.^X8JX][ MA&Z82QJ376-7_4W*(R'D//CC#XB(#DQO<V"9P=OAPZT>=Y<6]R;3LPDRHFM5 M])`[EDDH^3PP^4U'%Q<*DTPMEJ)R.$'FO.\_ZS.D/YE\WK?<X[:_J3CF]REX MI:A>>E``RU<T&@[WLT,BI-;WKI_.1JM<28LX*/#&()D<P308)%UQ)9S8;>C6 MU]8N]\WD7"WVZ@1JT)>:6JZMFNEF=%$<;?=D98\TD3DGAY5F81_LH8%)8N[` M)E%L5E;6.\U$9,>L77NS(X^J7L=D0-^'JJ^N<!<5[E3>*1T:W";2[3*C*`,W M.^5&!^R;!'U4HS#ZP*)BA<C=.EBMW<>;87_C30CI?JPYM+=J#)-]*_*(3'7# 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
| |