00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 #include <stdlib.h>
00080 #include <memory.h>
00081 #include <sys/types.h>
00082 #include <netinet/in.h>
00083 #include "udanax.h"
00084
00085 struct freediskconscell {
00086 freediskconscell *next;
00087 freediskentry *stuff;
00088 };
00089
00090 #define SIZEOFFREEDISKBUCKET 50
00091 #define NUMBEROFFREEDISKBUCKETS (NUMBYTESINLOAF/SIZEOFFREEDISKBUCKET+1)
00092 static freediskconscell *fdorderedtable[NUMBEROFFREEDISKBUCKETS];
00093
00094 #define FDHASHTABLESIZE 10000
00095
00096 #define FDHASHMULT 723754349
00097
00098 static freediskconscell *fdhashtable[FDHASHTABLESIZE];
00099
00107 static void
00108 dumpfreediskentry(
00109 freediskentry *ptr)
00110 {
00111 #ifndef DISTRIBUTION
00112 L("partialdiskblocknumber = %d freespaceinloaf = %d\n", ntohl(ptr->partialdiskblocknumber),
00113 ntohs(ptr->freespaceinloaf));
00114 #endif
00115 }
00116
00124 static void
00125 dumpfdhashtable()
00126 {
00127 #ifndef DISTRIBUTION
00128 int i;
00129 freediskconscell *ptr;
00130
00131 L("dumping fdhashtable\n");
00132 for (i = 0; i < FDHASHTABLESIZE; i++) {
00133 if (fdhashtable[i]) {
00134 L("hashtable[%d]\n ", i);
00135 for (ptr = fdhashtable[i]; ptr; ptr = ptr->next)
00136 dumpfreediskentry(ptr->stuff);
00137 }
00138 }
00139 L("exiting dumping fdhashtable\n");
00140 #endif
00141 }
00142
00150 static void
00151 dumpfdorderedtable()
00152 {
00153 #ifndef DISTRIBUTION
00154 int i;
00155 freediskconscell *ptr;
00156
00157 L("dumping fdorderedtable\n");
00158 for (i = 0; i < NUMBEROFFREEDISKBUCKETS; i++) {
00159 if (fdorderedtable[i]) {
00160 L("fdorderedtable[%d] s = %d\n", i, (i + 1) * SIZEOFFREEDISKBUCKET);
00161 for (ptr = fdorderedtable[i]; ptr; ptr = ptr->next) {
00162 dumpfreediskentry(ptr->stuff);
00163 }
00164 }
00165 }
00166 L("exiting dumping fdorderedtable\n");
00167 #endif
00168 }
00169
00177 static void
00178 dumpincoretables()
00179 {
00180 #ifndef DISTRIBUTION
00181 dumpfdorderedtable();
00182 dumpfdhashtable();
00183 #endif
00184 }
00185
00193 void
00194 initincorealloctables()
00195 {
00196
00197 int i;
00198
00199 for (i = 0; i < NUMBEROFFREEDISKBUCKETS; i++)
00200 fdorderedtable[i] = NULL;
00201
00202 for (i = 0; i < FDHASHTABLESIZE; i++)
00203 fdhashtable[i] = NULL;
00204 }
00205
00213 void
00214 savepartialdiskalloctabletodisk()
00215 {
00216 freediskarray loaf;
00217 int blocknumber, i;
00218 int bucket;
00219 freediskconscell *ptr;
00220 typediskloafptr diskalloc(), dl;
00221
00222 bucket = 0;
00223 ptr = fdorderedtable[bucket];
00224 blocknumber = PARTIALFREEDISKLOCATION;
00225 for (i = 0;; i++, ptr = ptr->next) {
00226 for (; ptr == 0;) {
00227 bucket++;
00228 if (bucket >= NUMBEROFFREEDISKBUCKETS) {
00229
00230 loaf.numberofentrysinthisblock = htonl(i);
00231 loaf.nextdiskblocknumber = 0;
00232 actuallywriteloaf((typeuberrawdiskloaf *) & loaf, blocknumber);
00233 return;
00234 }
00235 ptr = fdorderedtable[bucket];
00236 }
00237 loaf.freeentryarray[i] = *(ptr->stuff);
00238 if (i >= (int) NFREEENTRYS - 1) {
00239 dl = diskalloc();
00240 loaf.nextdiskblocknumber = htonl(dl.diskblocknumber);
00241 loaf.numberofentrysinthisblock = htonl(NFREEENTRYS);
00242 actuallywriteloaf((typeuberrawdiskloaf *) & loaf, blocknumber);
00243 i = 0;
00244 blocknumber = dl.diskblocknumber;
00245 }
00246 }
00247 }
00248
00256 static int
00257 fdhash(
00258 int diskblocknumber)
00259 {
00260 return abs(diskblocknumber * FDHASHMULT) % FDHASHTABLESIZE;
00261 }
00262
00270 static void
00271 addtofreediskstructures(
00272 freediskentry *diskentry)
00273 {
00274 freediskconscell *newcons;
00275 freediskentry *newde;
00276 int i;
00277
00278
00279
00280 newde = (freediskentry *) malloc(sizeof(freediskentry));
00281 newcons = (freediskconscell *) malloc(sizeof(freediskconscell));
00282 newcons->stuff = newde;
00283 *newde = *diskentry;
00284 i = ntohs(diskentry->freespaceinloaf) / SIZEOFFREEDISKBUCKET;
00285
00286 newcons->next = fdorderedtable[i];
00287 fdorderedtable[i] = newcons;
00288
00289 newcons = (freediskconscell *) malloc(sizeof(freediskconscell));
00290 newcons->stuff = newde;
00291 i = fdhash(ntohl(diskentry->partialdiskblocknumber));
00292
00293 newcons->next = fdhashtable[i];
00294 fdhashtable[i] = newcons;
00295
00296
00297
00298 }
00299
00307 void
00308 readpartialdiskalloctablefromdisk()
00309 {
00310 int first = true;
00311
00312 freediskarray loaf;
00313 int blocknumber;
00314 for (blocknumber = PARTIALFREEDISKLOCATION; blocknumber; blocknumber = ntohl(loaf.nextdiskblocknumber)) {
00315
00316
00317 actuallyreadrawloaf((typeuberrawdiskloaf *) &loaf, blocknumber);
00318 if (!first)
00319 diskfree(blocknumber);
00320
00321 first = false;
00322 if (ntohl(loaf.numberofentrysinthisblock) > NFREEENTRYS)
00323 assert(0);
00324
00325 int i;
00326 for (i = 0; i < (int) ntohl(loaf.numberofentrysinthisblock); i++)
00327 addtofreediskstructures(&(loaf.freeentryarray[i]));
00328 }
00329 }
00330
00338 void
00339 addallocatedloaftopartialallocedtables(
00340 typediskloafptr dp,
00341 int size)
00342 {
00343 freediskentry stuff;
00344
00345
00346 stuff.partialdiskblocknumber = htonl(dp.diskblocknumber);
00347 stuff.freespaceinloaf = htons(sizeof(typeuberrawdiskloaf) - size - SIZEOFUBERDISKHEADER);
00348 addtofreediskstructures(&stuff);
00349
00350 }
00351
00352 #define BESTFIT
00353 #ifdef BESTFIT
00354
00361 static freediskentry *
00362 findfreeenoughloafinbucket(
00363 int size)
00364 {
00365 int i;
00366 freediskconscell *ptr;
00367
00368 for (i = size / SIZEOFFREEDISKBUCKET + 1; i < (int) NUMBEROFFREEDISKBUCKETS; i++) {
00369 for (ptr = fdorderedtable[i]; ptr; ptr->next) {
00370 if ((int) ntohs(ptr->stuff->freespaceinloaf) >= size)
00371 return ptr->stuff;
00372 }
00373 }
00374 return NULL;
00375 }
00376 #else
00377
00384 static freediskentry *
00385 findfreeenoughloafinbucket(
00386 int size)
00387 {
00388 int i;
00389 freediskconscell *ptr;
00390
00391 for (i = NUMBEROFFREEDISKBUCKETS - 1; i >= size / SIZEOFFREEDISKBUCKET; i--) {
00392 for (ptr = fdorderedtable[i]; ptr; ptr = ptr->next) {
00393 if (ntohs(ptr->stuff->freespaceinloaf) >= size)
00394 return ptr->stuff;
00395 }
00396 }
00397 return NULL;
00398 }
00399 #endif
00400
00408 static void
00409 changefreediskstructures(
00410 freediskentry *diskentry,
00411 int newsize)
00412 {
00413 int temp;
00414 freediskconscell *ptr, *newptr = NULL, *oldptr;
00415
00416
00417
00418
00419 temp = fdhash(ntohl(diskentry->partialdiskblocknumber));
00420 oldptr = 0;
00421 for (ptr = fdhashtable[temp]; ptr; ptr = ptr->next) {
00422 if (ptr->stuff->partialdiskblocknumber == diskentry->partialdiskblocknumber) {
00423 newptr = ptr;
00424 break;
00425 }
00426 oldptr = ptr;
00427 }
00428
00429 if (oldptr == newptr)
00430 assert(0);
00431
00432 if (oldptr == 0) {
00433 fdhashtable[temp] = newptr->next;
00434 } else {
00435 oldptr->next = newptr->next;
00436 }
00437
00438
00439
00440
00441 temp = ntohs(diskentry->freespaceinloaf) / SIZEOFFREEDISKBUCKET;
00442 oldptr = 0;
00443 for (ptr = fdorderedtable[temp]; ptr; ptr = ptr->next) {
00444 if (ptr->stuff->partialdiskblocknumber == diskentry->partialdiskblocknumber) {
00445 newptr = ptr;
00446 break;
00447 }
00448 oldptr = ptr;
00449 }
00450 if (oldptr == 0) {
00451 fdorderedtable[temp] = newptr->next;
00452 } else {
00453 oldptr->next = newptr->next;
00454 }
00455
00456 newptr->stuff->freespaceinloaf = htons(newsize);
00457 addtofreediskstructures(newptr->stuff);
00458
00459 free((char *)newptr->stuff);
00460 free((char *)newptr);
00461
00462
00463 }
00464
00472 static int
00473 findandallocateinsidediskblocknumber(
00474 int diskblocknumber,
00475 int size,
00476 typeuberdiskloaf *loafp)
00477 {
00478 char *lp;
00479 int number;
00480 int i;
00481 int temp;
00482 short loaftemp;
00483
00484
00485 lp = (char *)loafp + 6;
00486
00487 number = ntohs(loafp->numberofunterloafs);
00488 for (i = 0; i < number; i++) {
00489 temp = intof((humber) lp);
00490 lp += temp;
00491 }
00492
00493
00494 loaftemp = ntohs(loafp->numberofunterloafs) + 1;
00495 loafp->numberofunterloafs = htons(loaftemp);
00496 temp = sizeof(typeuberrawdiskloaf) - (lp - (char *)loafp) - size;
00497 #ifndef DISTRIBUTION
00498 if (temp < 0) {
00499 dumphexstuff(lp);
00500 dumphexstuff((char *) loafp);
00501 L("2temp = %d lp = %x loafp = %x i = %d size = %d \n", temp, (int) lp, (int) loafp, i, size);
00502 L("lp - loafp = %d ", lp - (char *)loafp);
00503 L("expression = %d diskblocknumber = %d number = %d\n", temp, diskblocknumber, number);
00504 dumpincoretables();
00505 assert(0);
00506 L("expression negative in findandallocateinsidediskblocknumber");
00507 return i;
00508 }
00509 #endif
00510 movmem(lp, lp + size, sizeof(typeuberrawdiskloaf) - (lp - (char *)loafp) - size);
00511
00512
00513 return i;
00514 }
00515
00523 typediskloafptr
00524 partialdiskalloc(
00525 int size,
00526 int *newloafp)
00527 {
00528 freediskentry diskentry, *freeentry;
00529 typediskloafptr dlp;
00530 typeuberdiskloaf loaf;
00531
00532 #ifndef DISTRIBUTION
00533 if (size != 1010 && size > 990) {
00534 L("partialdiskalloc size = %d\n", size);
00535 }
00536 #endif
00537 freeentry = findfreeenoughloafinbucket(size);
00538
00539 if (!freeentry) {
00540 dlp = diskalloc();
00541 dlp.insidediskblocknumber = 0 ;
00542 diskentry.partialdiskblocknumber = htonl(dlp.diskblocknumber);
00543 diskentry.freespaceinloaf = htons(NUMBYTESINLOAF - size - SIZEOFUBERDISKHEADER);
00544 addtofreediskstructures(&diskentry);
00545
00546 *newloafp = true;
00547 return dlp;
00548 } else {
00549 if (size >= ntohs(freeentry->freespaceinloaf)) {
00550 dumpincoretables();
00551 #ifndef DISTRIBUTION
00552 L("size = %d number = %d\n ", size, ntohl(freeentry->partialdiskblocknumber));
00553 assert(0);
00554 #else
00555 assert(0);
00556 #endif
00557 }
00558 dlp.diskblocknumber = ntohl(freeentry->partialdiskblocknumber);
00559 actuallyreadrawloaf((typeuberrawdiskloaf *) & loaf, ntohl(freeentry->partialdiskblocknumber));
00560 dlp.insidediskblocknumber = findandallocateinsidediskblocknumber(dlp.diskblocknumber, size, &loaf);
00561
00562 if (dlp.insidediskblocknumber > 100)
00563 assert(0);
00564
00565 changefreediskstructures(freeentry, (int) (ntohs(freeentry->freespaceinloaf) - size));
00566 *newloafp = false;
00567
00568 return dlp;
00569 }
00570 }
00571
00579 int
00580 numberofliveunterloafs(
00581 typeuberdiskloaf *loafp)
00582 {
00583 char *lp;
00584 unsigned int number, n;
00585 int i;
00586 int ret;
00587 unsigned int temp;
00588
00589 ret = 0;
00590 lp = (char *)loafp + 6;
00591 number = ntohs(loafp->numberofunterloafs);
00592 for (i = 0; i < (int) number; i++) {
00593 n = lengthof((humber) lp);
00594 temp = intof((humber) lp);
00595 if (n >= temp) {
00596 lp += n;
00597 } else {
00598 lp += temp;
00599 }
00600 if (n != temp) {
00601 ret++;
00602 }
00603 }
00604 return ret;
00605 }
00606
00614 char *
00615 findinsideloaf(
00616 typeuberdiskloaf *loafp,
00617 int ninsideloaf)
00618 {
00619 char *lp;
00620 unsigned int number, n;
00621 int i;
00622 unsigned int temp;
00623
00624
00625
00626
00627 lp = (char *)loafp + 6;
00628
00629 number = ntohs(loafp->numberofunterloafs);
00630
00631 for (i = 0; i < (int) number; i++) {
00632 n = lengthof((humber) loafp);
00633
00634 if (i == ninsideloaf) {
00635
00636 return lp;
00637 }
00638 temp = intof((humber) lp);
00639 if (n >= temp) {
00640 lp += n;
00641 } else {
00642 lp += temp;
00643 }
00644 }
00645
00646 return lp;
00647 }