libsrc/disk.cxx

Go to the documentation of this file.
00001 /**********************************************************************
00002  * Copyright 2002 Jeff Rush <jrush@taupro.com>
00003  * Original Copyright 1979-2002 Udanax.com
00004  *
00005  * This file is part of the Udanax xanalogical storage system.
00006  *
00007  * Udanax is free software; you can redistribute it and/or modify it
00008  * under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * Udanax is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with Udanax; if not, write to the Free Software Foundation,
00019  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  **********************************************************************/
00021 
00030 /* Modification History:
00031  * $Log: disk.cxx,v $
00032  * Revision 1.11  2004/09/11 13:59:21  jrush
00033  * Changed all fprintf's to stderr to use the Nana library L() macro.  Also
00034  * removed a 2-3 minor compiler warnings.
00035  *
00036  * Revision 1.10  2004/09/04 16:02:17  jrush
00037  * Added Doxygen headers before each and every function definition.
00038  *
00039  * Revision 1.9  2004/08/28 13:35:26  jrush
00040  * Catching up CVS to various incomplete versions on local disk.
00041  *
00042  * Revision 1.8  2002/07/26 04:30:29  jrush
00043  * Replaced gerror() with assert()
00044  *
00045  * Revision 1.7  2002/05/28 04:22:29  jrush
00046  * Adjusted source files to comply with GPL licensing.
00047  *
00048  * Revision 1.6  2002/05/28 02:49:42  jrush
00049  * Made static any functions and global variables private to this source file
00050  * and commented out any unused functions.
00051  *
00052  * Revision 1.5  2002/04/12 11:56:42  jrush
00053  * Reorganized include file layout, renamed xanadu.h to udanax.h and
00054  * typecontext/typecrumcontext to C++ class Context/CrumContext.
00055  *
00056  * Revision 1.4  2002/04/06 19:51:30  jrush
00057  * Renamed TRUE/FALSE constant use to the C++ standard of true/false.
00058  *
00059  * Revision 1.3  2002/04/06 15:01:17  jrush
00060  * Changed INT to just 'int'.
00061  *
00062  * Revision 1.2  2002/02/14 09:27:43  jrush
00063  * Cleaned up source:
00064  *
00065  * 1. ran thru the indent tool to achieve a standard look,
00066  * 2. added structured comments at top for use with DOxygen reporting
00067  *    as well as CVS keywords,
00068  * 3. fixed compiler warnings re ambiguous assign/compares,
00069  *    needed casts and unused/uninitialized variables,
00070  * 4. fixed funcs that didn't specify a return type,
00071  * 5. centralized prototypes in protos.h, removing incomplete ones,
00072  * 6. cleaned up use of bool/BOOLEAN type to suit C++ type,
00073  * 7. fixed initializer nesting in tumbler constants,
00074  * 8. renamed vars that conflict with C++ keywords (new, this),
00075  * 9. fixed global/extern confusion re some global vars.
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 /* number of blocks read from disk in session */ ;
00092 int nolwrote = 0 /* same for writes */ ;
00093 
00094 int enffiledes; /* enfilade file descriptor where disk stuff is */
00095 bool enffileread;       /* yeah another external */
00096 
00104     int
00105 findnumberofdamnsons(
00106     typediskloafptr diskptr)
00107 {
00108     if (diskptr.diskblocknumber == DISKPTRNULL)
00109         assert(0); // null diskptr in changerefcount
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 /* loafp += 3; */
00161     hgetfromloaf(&size, loafp);
00162     hgetfromloaf(&isapex, loafp);
00163 // if (isapex) { assert(0); /* attempt to read apex in chengerefcount */); }
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 /* L("changeunterrefcount A \n"); */
00176     if ((int) refcount > 0) {
00177 /* L("changeunterrefcount B \n"); */
00178         if (oldlength == newlength) {
00179 /* (void)humberput(refcount, loafp-oldlength, &dummylength); */
00180         } else {
00181 /* L("changeunterrefcount C \n"); */
00182 /* L("changeunterrefcoun bt oldlength = %d newlength = %d\n",oldlength,newlength); */
00183             lengthdif = newlength - oldlength;
00184             if (newlength > oldlength) {
00185 /* L("changeunterrefcount D \n"); */
00186                 movmem(loafp, loafp - oldlength + newlength, sizeof(typeuberrawdiskloaf) - foo - newlength);
00187             } else if (newlength > oldlength) {
00188 /* L("changeunterrefcount E \n"); */
00189                 movmem(loafp, loafp - oldlength + newlength, sizeof(typeuberrawdiskloaf) - foo - oldlength);
00190             }
00191 /* L("changeunterrefcount F \n"); */
00192             size = size + oldlength - newlength;
00193             (void)humber3put(size, (humber) originalloafp, &dummy);
00194 /* L("changeunterrefcount G \n"); */
00195         }
00196 /* L("changeunterrefcount H \n"); */
00197 
00198         (void)humberput((int) refcount, (humber) refcountloafp /*-oldlength*/ , &dummylength);
00199 /* L("changeunterrefcount I \n"); */
00200 /* dumphexstuff(originalloafp); */
00201 /* L("changeunterrefcount J \n"); */
00202     } else {
00203 /* L("changeunterrefcount K \n"); */
00204         movmem(originalloafp + size, originalloafp + 1, sizeof(typeuberrawdiskloaf) - foo - size + 3);
00205 /* L("changeunterrefcount L \n"); */
00206         *originalloafp = 1;
00207 /* diskfree (diskptr.diskblocknumber); */
00208     }
00209 /* L("leaving changeunterrefoount \n"); */
00210     return ret;
00211 }
00212 
00220     int
00221 changerefcount(
00222     typediskloafptr diskptr,
00223     int             delta)
00224 {
00225     if (diskptr.diskblocknumber == DISKPTRNULL)
00226         assert(0); // null diskptr in changerefcount
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( /* sizeof(typediskloaf), */ &loaf, diskptr.diskblocknumber);
00237     else
00238         diskfree(diskptr.diskblocknumber);
00239 
00240     return refcount;
00241 }
00242 
00250 /* Reads whats on disk at place named by loafptr in * place pointed to by loaf */
00251     void
00252 readloaf(
00253     typediskloaf    *loafptr,
00254     typediskloafptr  diskptr)
00255 {
00256     typeuberrawdiskloaf uberrawloaf;
00257     humber temp;
00258 
00259 /* L("entering readloaf diskblocknumber = %d insdiediskblocknumber =
00260  * %d\n",diskptr.diskblocknumber,diskptr.insidediskblocknumber); */
00261     actuallyreadrawloaf(&uberrawloaf, diskptr.diskblocknumber);
00262 /* L("in readloaf dumping loaf\n"); */
00263 /* dumphexstuff(&uberrawloaf); */
00264     temp = (humber) findinsideloaf((typeuberdiskloaf *) & uberrawloaf, diskptr.insidediskblocknumber);
00265     if (!temp) {
00266         temp = (humber) (((char *)&uberrawloaf) + 6);
00267     }
00268     movmem(temp, loafptr, intof(temp)); /* humber at temp is length of loaf */
00269 }
00270 
00278     void
00279 actuallyreadrawloaf(
00280     typeuberrawdiskloaf *loafptr,
00281     int                  blocknumber)
00282 {
00283 /* L("entering actuallyreadloaf diskblocknumber = %d\n",blocknumber); */
00284     if (!loafptr || blocknumber == DISKPTRNULL) {
00285 #ifndef DISTRIBUTION
00286         L("loafptr = %d\n", blocknumber);
00287         if (loafptr)
00288             dumpsubtree((typecuc *) loafptr);
00289         assert(0); // bad readloaf call
00290 #else
00291         assert(0); // bad call
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); // open
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); // lseek failed
00319     }
00320 
00321     int nbytes = read(enffiledes, (char *) loafptr, sizeof(*loafptr));
00322     assert(nbytes > 0); // Incorrect Usage of Assertion
00323 
00324     // dumphexstuff(loafptr);
00325     // if ((int) loafptr->xdbcloaf.xdbchedr.refcount < 0) {
00326     //     assert(0); // readloaf read a loaf with refcount < 0
00327     // }
00328     ++nolread;
00329 
00330     // return true;
00331 }
00332 
00340 /* Writes stuff at loaf onto piece of disk named by loafptr */
00341     void
00342 writeloaf(
00343     typediskloaf    *loafptr,
00344     typediskloafptr  diskptr,
00345     int              newloaf)
00346 {
00347 /* typeuberdiskloaf loaf; */
00348     typeuberrawdiskloaf loaf;
00349     char *temp;
00350     char *last, *end;
00351     int s;
00352     short loaftemp;
00353 
00354 /* L("entering writeloaf newloaf flag = %d diskblocknumber = %d insdiediskblocknumber =
00355  * %d\n",newloaf,diskptr.diskblocknumber,diskptr.insidediskblocknumber); */
00356     if (diskptr.insidediskblocknumber > 100) {
00357 #ifndef DISTRIBUTION
00358         assert(0); // in write laof large diskblocknumber
00359 #else
00360         assert(0); // bad
00361 #endif
00362     }
00363 /* dumphexstuff(loafptr); */
00364     (void)intof((humber) loafptr);     /* test it to see if it starts with length */
00365 
00366 /* test diskalloc if alloced read in else do as old version */
00367 
00368     if (!newloaf) {
00369 /* L("writeloaf 1\n"); */
00370         actuallyreadrawloaf(&loaf, diskptr.diskblocknumber);
00371 /* dumphexstuff(&loaf); */
00372 /* L("writeloaf 2\n"); */
00373         temp = findinsideloaf((typeuberdiskloaf *) & loaf, diskptr.insidediskblocknumber);
00374 /* L("numberofunterloafs = %d\n",loaf.xuberdiskloaf.numberofunterloafs); */
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 /* dumphexstuff(last); */
00380 /* L("last = %x\n",last); */
00381             end = last + intof((humber) last);
00382         }
00383         s = sizeof(typeuberrawdiskloaf) - (end - (char *)&loaf) - SIZEOFUBERDISKHEADER;
00384 /* L("s = %d\n",s); */
00385         movmem(loafptr, /* ((char*)&loaf)+6 */ temp, s);
00386         loaf.xuberdiskloaf.versiondisknumber = 1;
00387         loaftemp = ntohs(loaf.xuberdiskloaf.numberofunterloafs) + 1;
00388         loaf.xuberdiskloaf.numberofunterloafs = htons(loaftemp);
00389     } else {
00390 /* L("writeloaf A\n"); */
00391         movmem(loafptr, ((char *)&loaf) + 6, sizeof(typeuberrawdiskloaf) - SIZEOFUBERDISKHEADER);
00392 /* L("writeloaf B\n"); */
00393         loaf.xuberdiskloaf.versiondisknumber = htonl(1);
00394         loaf.xuberdiskloaf.numberofunterloafs = htons(1);
00395 
00396     }
00397 /* dumphexstuff(&loaf); */
00398     actuallywriteloaf( /* size, */ &loaf, diskptr.diskblocknumber);
00399 /* L("leaving wrietloaf\n"); */
00400 }
00401 
00409     void
00410 actuallywriteloaf(
00411     /* int               size, */
00412     typeuberrawdiskloaf *loafptr,
00413     int                  diskblocknumber)
00414 {
00415     if (!loafptr || diskblocknumber == DISKPTRNULL /* || (int) loafptr->xdbcloaf.xdbchedr.refcount < 0 */ )
00416         assert(0); // bad call
00417 
00418     assert(goodblock(diskblocknumber)); // ERROR: unallocated block
00419 
00420     if (lseek(enffiledes, (long)diskblocknumber * NUMBYTESINLOAF, 0) < 0) {
00421         perror("lseek");
00422         assert(0); // lseek failed
00423     }
00424 
00425     int nbytes = write(enffiledes, (char *)loafptr, sizeof(*loafptr));
00426     assert(nbytes >= 0); // Incorrect Usage of Assert
00427 
00428     ++nolwrote;
00429 }
00430 
00438     bool                                   /* return false if new file */
00439 initenffile(
00440     const char *filename)
00441 {
00442     //    static long times = 0;
00443     //    assert(times == 0); // too many inits
00444     //    ++times;
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); // cant open enf.enf or creatit
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); // close failed
00486     }
00487 }

Generated on Sun Aug 21 04:18:14 2005 for Udanax-Green by doxygen1.3.4