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 <stdio.h>
00080 #include <memory.h>
00081 #include <stdlib.h>
00082 #include <unistd.h>
00083 #include <sys/types.h>
00084 #include <sys/stat.h>
00085 #include <fcntl.h>
00086 #include <netinet/in.h>
00087 #include <errno.h>
00088
00089 #include "udanax.h"
00090
00091 int nolread = 0 ;
00092 int nolwrote = 0 ;
00093
00094 int enffiledes;
00095 bool enffileread;
00096
00104 int
00105 findnumberofdamnsons(
00106 typediskloafptr diskptr)
00107 {
00108 if (diskptr.diskblocknumber == DISKPTRNULL)
00109 assert(0);
00110
00111 typeuberrawdiskloaf loaf;
00112 actuallyreadrawloaf(&loaf, diskptr.diskblocknumber);
00113
00114 char *loafp = findinsideloaf((typeuberdiskloaf *) &loaf, diskptr.insidediskblocknumber);
00115
00116 int size;
00117 hgetfromloaf(&size, loafp);
00118
00119 int isapex;
00120 hgetfromloaf(&isapex, loafp);
00121
00122 int height;
00123 hgetfromloaf(&height, loafp);
00124
00125 int enftype;
00126 hgetfromloaf(&enftype, loafp);
00127
00128 int numberofsons;
00129 hgetfromloaf(&numberofsons, loafp);
00130
00131 return numberofsons;
00132 }
00133
00141 static int
00142 changeunterrefcount(
00143 typediskloaf *wholeloafp,
00144 char *originalloafp,
00145 int delta)
00146 {
00147 int ret;
00148 int numberofsons;
00149 char *loafp;
00150 int height, enftype;
00151 int isapex;
00152 unsigned int refcount;
00153 int foo;
00154 unsigned int oldlength, newlength, dummylength, dummy;
00155 int lengthdif;
00156 int size;
00157 char *refcountloafp;
00158
00159 loafp = (char *)originalloafp;
00160
00161 hgetfromloaf(&size, loafp);
00162 hgetfromloaf(&isapex, loafp);
00163
00164 hgetfromloaf(&height, loafp);
00165 hgetfromloaf(&enftype, loafp);
00166 hgetfromloaf(&numberofsons, loafp);
00167 refcountloafp = loafp;
00168 hgetfromloaf((int *) &refcount, loafp);
00169 foo = loafp - (char *)wholeloafp;
00170
00171 oldlength = intlengthoflength(refcount);
00172 refcount += delta;
00173 ret = refcount;
00174 newlength = intlengthoflength(refcount);
00175
00176 if ((int) refcount > 0) {
00177
00178 if (oldlength == newlength) {
00179
00180 } else {
00181
00182
00183 lengthdif = newlength - oldlength;
00184 if (newlength > oldlength) {
00185
00186 movmem(loafp, loafp - oldlength + newlength, sizeof(typeuberrawdiskloaf) - foo - newlength);
00187 } else if (newlength > oldlength) {
00188
00189 movmem(loafp, loafp - oldlength + newlength, sizeof(typeuberrawdiskloaf) - foo - oldlength);
00190 }
00191
00192 size = size + oldlength - newlength;
00193 (void)humber3put(size, (humber) originalloafp, &dummy);
00194
00195 }
00196
00197
00198 (void)humberput((int) refcount, (humber) refcountloafp , &dummylength);
00199
00200
00201
00202 } else {
00203
00204 movmem(originalloafp + size, originalloafp + 1, sizeof(typeuberrawdiskloaf) - foo - size + 3);
00205
00206 *originalloafp = 1;
00207
00208 }
00209
00210 return ret;
00211 }
00212
00220 int
00221 changerefcount(
00222 typediskloafptr diskptr,
00223 int delta)
00224 {
00225 if (diskptr.diskblocknumber == DISKPTRNULL)
00226 assert(0);
00227
00228 typeuberrawdiskloaf loaf;
00229 actuallyreadrawloaf(&loaf, diskptr.diskblocknumber);
00230
00231 char *loafp = findinsideloaf((typeuberdiskloaf *) &loaf, diskptr.insidediskblocknumber);
00232 int refcount = changeunterrefcount((typediskloaf *) &loaf, loafp, delta);
00233 int numberofunterloafs = numberofliveunterloafs((typeuberdiskloaf *) &loaf);
00234
00235 if (refcount > 0 && numberofunterloafs > 0)
00236 actuallywriteloaf( &loaf, diskptr.diskblocknumber);
00237 else
00238 diskfree(diskptr.diskblocknumber);
00239
00240 return refcount;
00241 }
00242
00250
00251 void
00252 readloaf(
00253 typediskloaf *loafptr,
00254 typediskloafptr diskptr)
00255 {
00256 typeuberrawdiskloaf uberrawloaf;
00257 humber temp;
00258
00259
00260
00261 actuallyreadrawloaf(&uberrawloaf, diskptr.diskblocknumber);
00262
00263
00264 temp = (humber) findinsideloaf((typeuberdiskloaf *) & uberrawloaf, diskptr.insidediskblocknumber);
00265 if (!temp) {
00266 temp = (humber) (((char *)&uberrawloaf) + 6);
00267 }
00268 movmem(temp, loafptr, intof(temp));
00269 }
00270
00278 void
00279 actuallyreadrawloaf(
00280 typeuberrawdiskloaf *loafptr,
00281 int blocknumber)
00282 {
00283
00284 if (!loafptr || blocknumber == DISKPTRNULL) {
00285 #ifndef DISTRIBUTION
00286 L("loafptr = %d\n", blocknumber);
00287 if (loafptr)
00288 dumpsubtree((typecuc *) loafptr);
00289 assert(0);
00290 #else
00291 assert(0);
00292 #endif
00293 }
00294
00295 if (!enffileread) {
00296 if (close(enffiledes) != 0)
00297 perror("close failed in readloaf");
00298
00299 if ((enffiledes = open("enf.enf", O_RDWR, 0)) == -1) {
00300 perror("open");
00301 assert(0);
00302 }
00303 enffileread = true;
00304 }
00305
00306 if (!goodblock(blocknumber)) {
00307 #ifndef DISTRIBUTION
00308 L("loaf = %x\n", blocknumber);
00309 L("unallocated block in readloaf.\n");
00310 #endif
00311 abort();
00312 }
00313
00314 if (lseek(enffiledes, (long)blocknumber * NUMBYTESINLOAF, 0) < 0) {
00315 #ifndef DISTRIBUTION
00316 perror("lseek in readloaf");
00317 #endif
00318 assert(0);
00319 }
00320
00321 int nbytes = read(enffiledes, (char *) loafptr, sizeof(*loafptr));
00322 assert(nbytes > 0);
00323
00324
00325
00326
00327
00328 ++nolread;
00329
00330
00331 }
00332
00340
00341 void
00342 writeloaf(
00343 typediskloaf *loafptr,
00344 typediskloafptr diskptr,
00345 int newloaf)
00346 {
00347
00348 typeuberrawdiskloaf loaf;
00349 char *temp;
00350 char *last, *end;
00351 int s;
00352 short loaftemp;
00353
00354
00355
00356 if (diskptr.insidediskblocknumber > 100) {
00357 #ifndef DISTRIBUTION
00358 assert(0);
00359 #else
00360 assert(0);
00361 #endif
00362 }
00363
00364 (void)intof((humber) loafptr);
00365
00366
00367
00368 if (!newloaf) {
00369
00370 actuallyreadrawloaf(&loaf, diskptr.diskblocknumber);
00371
00372
00373 temp = findinsideloaf((typeuberdiskloaf *) & loaf, diskptr.insidediskblocknumber);
00374
00375 if (diskptr.insidediskblocknumber == loaf.xuberdiskloaf.numberofunterloafs) {
00376 end = temp + intof((humber) temp);
00377 } else {
00378 last = findinsideloaf((typeuberdiskloaf *) & loaf, (int) ntohs(loaf.xuberdiskloaf.numberofunterloafs) - 1);
00379
00380
00381 end = last + intof((humber) last);
00382 }
00383 s = sizeof(typeuberrawdiskloaf) - (end - (char *)&loaf) - SIZEOFUBERDISKHEADER;
00384
00385 movmem(loafptr, temp, s);
00386 loaf.xuberdiskloaf.versiondisknumber = 1;
00387 loaftemp = ntohs(loaf.xuberdiskloaf.numberofunterloafs) + 1;
00388 loaf.xuberdiskloaf.numberofunterloafs = htons(loaftemp);
00389 } else {
00390
00391 movmem(loafptr, ((char *)&loaf) + 6, sizeof(typeuberrawdiskloaf) - SIZEOFUBERDISKHEADER);
00392
00393 loaf.xuberdiskloaf.versiondisknumber = htonl(1);
00394 loaf.xuberdiskloaf.numberofunterloafs = htons(1);
00395
00396 }
00397
00398 actuallywriteloaf( &loaf, diskptr.diskblocknumber);
00399
00400 }
00401
00409 void
00410 actuallywriteloaf(
00411
00412 typeuberrawdiskloaf *loafptr,
00413 int diskblocknumber)
00414 {
00415 if (!loafptr || diskblocknumber == DISKPTRNULL )
00416 assert(0);
00417
00418 assert(goodblock(diskblocknumber));
00419
00420 if (lseek(enffiledes, (long)diskblocknumber * NUMBYTESINLOAF, 0) < 0) {
00421 perror("lseek");
00422 assert(0);
00423 }
00424
00425 int nbytes = write(enffiledes, (char *)loafptr, sizeof(*loafptr));
00426 assert(nbytes >= 0);
00427
00428 ++nolwrote;
00429 }
00430
00438 bool
00439 initenffile(
00440 const char *filename)
00441 {
00442
00443
00444
00445
00446 initincorealloctables();
00447 bool ret = true;
00448
00449 int fd = open(filename, O_RDWR, 0);
00450 if (fd == -1) {
00451 errno = 0;
00452 if ((fd = creat(filename, 0660)) == -1) {
00453 perror("initenffile");
00454 assert(0);
00455 }
00456 initheader();
00457 enffileread = false;
00458 ret = false;
00459
00460 } else {
00461 ret = readallocinfo(fd);
00462 enffileread = true;
00463 }
00464
00465 if (!ret)
00466 writeallocinfo(fd);
00467
00468 enffiledes = fd;
00469 return ret;
00470 }
00471
00479 void
00480 closediskfile()
00481 {
00482 diskallocexit(enffiledes);
00483 if (close(enffiledes) != 0) {
00484 perror("close in closediskfile");
00485 assert(0);
00486 }
00487 }