# dirCache.c

Go to the documentation of this file.

    00001 /*****************************************************************************************
    00002  Copyright (c) 2002 The UbixOS Project
    00003  All rights reserved.
    00004
    00005 Redistribution and use in source and binary forms, with or without modification, are
    00006 permitted provided that the following conditions are met:
    00007
    00008 Redistributions of source code must retain the above copyright notice, this list of
    00009 conditions, the following disclaimer and the list of authors.  Redistributions in binary
    00010 form must reproduce the above copyright notice, this list of conditions, the following
    00011 disclaimer and the list of authors in the documentation and/or other materials provided
    00012 with the distribution. Neither the name of the UbixOS Project nor the names of its
    00013 contributors may be used to endorse or promote products derived from this software
    00014 without specific prior written permission.
    00015
    00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
    00017 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    00018 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
    00019 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    00020 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
    00021 OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    00022 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
    00023 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    00024 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00025
    00026 $Id: dirCache_8c-source.html 88 2016-01-12 00:11:29Z reddawg $
    00027
    00028 *****************************************************************************************/
    00029
    00030 #include <assert.h>
    00031 #include <ubixfs/dirCache.h>
    00032 #include <ubixfs/ubixfs.h>
    00033 #include <lib/kmalloc.h>
    00034 #include <lib/kprintf.h>
    00035 #include <lib/string.h>
    00036
    00037 #include <ubixos/spinlock.h>
    00038
    00039 static spinLock_t dca_spinLock = SPIN_LOCK_INITIALIZER;
    00040
    00041 static
    00042 struct directoryEntry *
    00043 ubixfs_findName(struct directoryEntry * dirList, uInt32 size, char * name) {
    00044   unsigned int i;
    00045
    00046   if (dirList == NULL || name == NULL) return NULL;
    00047   //UBU kprintf("dirList: [0x%X],name: [0x%X]\n",dirList,name);
    00048   for (i = 0; i < (size / sizeof(struct directoryEntry)) ; i++) {
    00049     if (strcmp(dirList[i].fileName, name) == 0) return &dirList[i];
    00050   } /* for */
    00051   return NULL;
    00052 } /* ubixfs_findName */
    00053
    00054 struct cacheNode *
    00055 ubixfs_cacheFind(struct cacheNode * head, char * name) {
    00056   struct cacheNode * tmp = head;
    00057   struct directoryEntry * dirList = NULL;
    00058   unsigned int i = 0x0;
    00059   char dirName[256];
    00060   char * nextDir = NULL;
    00061 /* kprintf("looking for %s\n", name);  */
    00062 assert(name);
    00063 assert(head);
    00064 assert(*name);
    00065   spinLock(&dca_spinLock);
    00066   spinUnlock(&dca_spinLock);
    00067   if (name == NULL || head == NULL) return NULL;
    00068   if (*name == '\0') return NULL;
    00069
    00070   /*
    00071    * walk down the tree recursively until we find the node we're looking
    00072    * for
    00073    */
    00074   i = 0;
    00075   while (name[i] != '\0' && name[i] != '/' && i < sizeof(dirName)) {
    00076     dirName[i] = name[i];
    00077     i++;
    00078   } /* while */
    00079   assert(i < sizeof(dirName));
    00080   if (i == sizeof(dirName)) return NULL;
    00081
    00082   if (i == 0) dirName[i++] = '/';
    00083
    00084   dirName[i] = '\0';
    00085
    00086   nextDir = &name[i];
    00087   if (*nextDir == '/') nextDir++;
    00088
    00089   /*
    00090    * nextDir points to the next dir
    00091    * name points to a null terminated directory name
    00092    * if nextDir isn't null, then make sure that this dir is present
    00093    */
    00094 /* kprintf("nextdir: %s  -- dirName: %s\n", nextDir, dirName); */
    00095   if (*nextDir != '\0') {
    00096     while (tmp != NULL) {
    00097       //UBU kprintf("tmp->name: [0x%X],dirName: [0x%X]\n",tmp->name,dirName);
    00098       if (strcmp(tmp->name, dirName) == 0) {
    00099
    00100         if ((*tmp->attributes & typeFile) == typeFile
    00101             || tmp->fileListHead == NULL) {
    00102
    00103           /* if we're here, then there are no subdirs cached to look through */
    00104           dirList = ubixfs_findName((struct directoryEntry *)head->info,
    00105                                     *head->size, nextDir);
    00106           if (dirList == NULL) return NULL;
    00107 /* kprintf("creating new node %s", dirList->fileName); */
    00108           tmp = ubixfs_cacheAdd(tmp, ubixfs_cacheNew(dirList->fileName));
    00109           tmp->attributes = &dirList->attributes;
    00110           tmp->permissions = &dirList->permissions;
    00111           tmp->size = &dirList->size;
    00112 /* kprintf("   size: %d\n", *tmp->size); */
    00113           tmp->startCluster = &dirList->startCluster;
    00114           tmp->present = 0;
    00115           return tmp;
    00116         } else {
    00117           return ubixfs_cacheFind(tmp->fileListHead, nextDir);
    00118         }
    00119       } /* if */
    00120       tmp = tmp->next;
    00121     } /* while */
    00122     /* it wasn't present, return NULL */
    00123     return NULL;
    00124   } /* if */
    00125
    00126   /*
    00127    * if nextDir was null, then we're at the bottom level. Look for the
    00128    * dir listing here
    00129    */
    00130   while (tmp != NULL) {
    00131
    00132     assert(tmp->name);
    00133     assert(name);
    00134 /* don't forget to check to see if it's a directory */
    00135     //UBU kprintf("tmpName: [0x%X], name: [0x%X]\n",tmp->name,name);
    00136     if (strcmp(tmp->name, name) == 0) {
    00137
    00138       /*
    00139        * we found the node. Move it to the front of the list
    00140        * (if it isn't already)
    00141        */
    00142 #if 0
    00143       assert(tmp->parent);
    00144       if (tmp != tmp->parent->fileListHead) {
    00145
    00146         /* if we're the tail, point the tail to our prev */
    00147         if (tmp == tmp->parent->fileListTail) {
    00148           tmp->parent->fileListTail = tmp->prev;
    00149         } /* if */
    00150
    00151         if (tmp->next != NULL) tmp->next->prev = tmp->prev;
    00152         if (tmp->prev != NULL) tmp->prev->next = tmp->next;
    00153         tmp->next = tmp->parent->fileListHead;
    00154         tmp->prev = NULL;
    00155         tmp->parent->fileListHead = tmp;
    00156       } /* if */
    00157 #endif
    00158       return tmp;
    00159     } /* if */
    00160     tmp = tmp->next;
    00161   } /* while */
    00162     /* if we're here, then one level of the dir isn't cached */
    00163
    00164   tmp = head->parent;
    00165   assert(tmp);
    00166   assert(tmp->info);
    00167   dirList = ubixfs_findName((struct directoryEntry *)tmp->info,
    00168                             *tmp->size, name);
    00169   if (dirList == NULL) return NULL;
    00170 /* kprintf("creating new node/size %s/%d", dirList->fileName, dirList->size);*/
    00171   tmp = ubixfs_cacheAdd(tmp, ubixfs_cacheNew(dirList->fileName));
    00172   tmp->attributes = &dirList->attributes;
    00173   tmp->permissions = &dirList->permissions;
    00174   tmp->size = &dirList->size;
    00175 /* kprintf("   size: %d\n", *tmp->size); */
    00176   tmp->startCluster = &dirList->startCluster;
    00177   tmp->present = 0;
    00178   return tmp;
    00179 #if 0
    00180   return NULL;  /* couldn't find it */
    00181 #endif
    00182 } /* ubixfs_cacheFind */
    00183
    00184 struct cacheNode *
    00185 ubixfs_cacheNew(const char * name) {
    00186   struct cacheNode * tmp = kmalloc(sizeof(struct cacheNode));
    00187   assert(tmp);
    00188   tmp->parent = tmp;
    00189   tmp->prev = tmp->next = tmp->fileListHead = tmp->fileListTail = NULL;
    00190   tmp->info = NULL;
    00191   tmp->size = NULL;
    00192   tmp->present = tmp->dirty = 0;
    00193   tmp->startCluster = NULL;
    00194   tmp->attributes = NULL;
    00195   tmp->permissions = NULL;
    00196   tmp->name = (char *)kmalloc(strlen(name)+1);
    00197   strcpy(tmp->name, name);
    00198   return tmp;
    00199 } /* ubixfs_cacheNew */
    00200
    00201 void
    00202 ubixfs_cacheDelete(struct cacheNode ** head) {
    00203   struct cacheNode * tmp = NULL;
    00204   struct cacheNode * del = NULL;
    00205
    00206   if (head == NULL) return;
    00207   if (*head == NULL) return;
    00208
    00209   tmp = *head;
    00210   while (tmp != NULL) {
    00211     /* if there are any child nodes, delete them first */
    00212
    00213     /*
    00214      * the following commented out ``if'' statement is redundant, since it
    00215      * will be caught with the above checks
    00216      */
    00217     /* if (tmp->fileListHead != NULL) */
    00218     ubixfs_cacheDelete(&tmp->fileListHead);
    00219
    00220     kfree(tmp->info);
    00221     kfree(tmp->name);
    00222     del = tmp;
    00223     tmp = tmp->next;
    00224     kfree(del);
    00225   } /* while */
    00226   *head = NULL;
    00227   return;
    00228 } /* deleteNode */
    00229 #if 0
    00230 void
    00231 addNode(struct cacheNode ** node, struct cacheNode * newNode) {
    00232   if (node == NULL) return;
    00233   newNode->next = *node;
    00234   if (*node != NULL) (*node)->prev = newNode;
    00235   newNode->prev = NULL;
    00236   *node = newNode;
    00237   return;
    00238 } /* addNode */
    00239 #endif
    00240
    00241 struct cacheNode *
    00242 ubixfs_cacheAdd(struct cacheNode *node, struct cacheNode * newNode) {
    00243   struct cacheNode * tmp;
    00244
    00245   assert(node);
    00246   spinLock(&dca_spinLock);
    00247   newNode->parent = node;
    00248   newNode->next = node->fileListHead;
    00249   newNode->prev = NULL;
    00250   if (node->fileListHead == NULL)
    00251     node->fileListTail = newNode;
    00252   else
    00253     node->fileListHead->prev = newNode;
    00254
    00255   node->fileListHead = newNode;
    00256   tmp = node->fileListHead;
    00257   spinUnlock(&dca_spinLock);
    00258   return tmp;
    00259 } /* ubixfs_cacheAdd */
    00260
    00261 /***
    00262  $Log: dirCache_8c-source.html,v $
    00262  Revision 1.7  2006/12/15 17:47:04  reddawg
    00262  Updates
    00262
    00263  Revision 1.1.1.1  2006/06/01 12:46:17  reddawg
    00264  ubix2
    00265
    00266  Revision 1.2  2005/10/12 00:13:37  reddawg
    00267  Removed
    00268
    00269  Revision 1.1.1.1  2005/09/26 17:24:40  reddawg
    00270  no message
    00271
    00272  Revision 1.30  2004/08/14 11:23:02  reddawg
    00273  Changes
    00274
    00275  Revision 1.29  2004/08/09 12:58:05  reddawg
    00276  let me know when you got the surce
    00277
    00278  Revision 1.28  2004/08/01 17:58:39  flameshadow
    00279  chg: fixed string allocation bug in ubixfs_cacheNew()
    00280
    00281  Revision 1.27  2004/07/28 17:24:13  flameshadow
    00282  chg: no comment
    00283
    00284  Revision 1.26  2004/07/28 17:07:29  flameshadow
    00285  chg: re-added moving cached nodes to the front of the list when found
    00286  add: added an assert() in ubixfs.c
    00287
    00288  Revision 1.25  2004/07/27 19:24:31  flameshadow
    00289  chg: reduced the number of debugging statements in the kernel.
    00290
    00291  Revision 1.24  2004/07/27 12:02:01  reddawg
    00292  chg: fixed marks bug readFile did a lookup which is why it looked like it was loopping so much
    00293
    00294  Revision 1.23  2004/07/27 09:05:43  flameshadow
    00295  chg: fixed file not found bug. Still can't find looping issue
    00296
    00297  Revision 1.22  2004/07/27 04:05:20  flameshadow
    00298  chg: kinda fixed it. Added bunches of debug info
    00299
    00300  Revision 1.21  2004/07/25 22:21:52  flameshadow
    00301  chg: re-enabled kprintf() in ubixfs_cacheFind()
    00302
    00303  Revision 1.20  2004/07/24 17:19:24  flameshadow
    00304  chg: Temporarily disabled the moving of the found cache node to the front
    00305       of the list. It seems to cause problems later (race condition, possibly)
    00306
    00307  Revision 1.19  2004/07/22 23:01:51  reddawg
    00308  Ok checking in before I sleep
    00309
    00310  Revision 1.18  2004/07/22 19:54:50  flameshadow
    00311  chg: works now. Thanx ubu
    00312
    00313  Revision 1.17  2004/07/22 19:01:59  flameshadow
    00314  chg: more directory and file caching
    00315
    00316  Revision 1.16  2004/07/22 16:34:32  flameshadow
    00317  add: file and dir caching kinda work
    00318
    00319  Revision 1.15  2004/07/21 22:43:18  flameshadow
    00320  one more try
    00321
    00322  Revision 1.14  2004/07/21 22:42:25  flameshadow
    00323  try it now
    00324
    00325  Revision 1.13  2004/07/21 22:40:27  flameshadow
    00326  weird
    00327
    00328  Revision 1.12  2004/07/21 22:18:37  flameshadow
    00329  chg: renamed subDirsHead/Tail members of cacheNode to fileListHead/Tail
    00330
    00331  Revision 1.11  2004/07/21 22:12:22  flameshadow
    00332  add: attributes tag in cacheNode
    00333  add: setting of attributes in ubixfx_cacheNew() and ubixfs_cacheFind()
    00334
    00335  Revision 1.10  2004/07/21 22:07:18  flameshadow
    00336  chg: renamed caching functions (again)
    00337
    00338  Revision 1.9  2004/07/21 22:00:04  flameshadow
    00339  chg: ubixfws_dirCacheAdd now returns a pointer to the node it added
    00340  chg: minor fix in ubixfs_dirCacheFind()
    00341
    00342  Revision 1.6  2004/07/21 14:43:14  flameshadow
    00343  add: added cwc (current working container) to the osInfo strut
    00344
    00345  Revision 1.5  2004/07/20 19:21:30  reddawg
    00346  You like leaving out $Log: dirCache_8c-source.html,v $
    00346  You like leaving out Revision 1.7  2006/12/15 17:47:04  reddawg
    00346  You like leaving out Updates
    00346  You like leaving out
    00347  You like leaving out Revision 1.1.1.1  2006/06/01 12:46:17  reddawg
    00348  You like leaving out ubix2
    00349  You like leaving out
    00350  You like leaving out Revision 1.2  2005/10/12 00:13:37  reddawg
    00351  You like leaving out Removed
    00352  You like leaving out
    00353  You like leaving out Revision 1.1.1.1  2005/09/26 17:24:40  reddawg
    00354  You like leaving out no message
    00355  You like leaving out
    00356  You like leaving out Revision 1.30  2004/08/14 11:23:02  reddawg
    00357  You like leaving out Changes
    00358  You like leaving out
    00359  You like leaving out Revision 1.29  2004/08/09 12:58:05  reddawg
    00360  You like leaving out let me know when you got the surce
    00361  You like leaving out
    00362  You like leaving out Revision 1.28  2004/08/01 17:58:39  flameshadow
    00363  You like leaving out chg: fixed string allocation bug in ubixfs_cacheNew()
    00364  You like leaving out
    00365  You like leaving out Revision 1.27  2004/07/28 17:24:13  flameshadow
    00366  You like leaving out chg: no comment
    00367  You like leaving out
    00368  You like leaving out Revision 1.26  2004/07/28 17:07:29  flameshadow
    00369  You like leaving out chg: re-added moving cached nodes to the front of the list when found
    00370  You like leaving out add: added an assert() in ubixfs.c
    00371  You like leaving out
    00372  You like leaving out Revision 1.25  2004/07/27 19:24:31  flameshadow
    00373  You like leaving out chg: reduced the number of debugging statements in the kernel.
    00374  You like leaving out
    00375  You like leaving out Revision 1.24  2004/07/27 12:02:01  reddawg
    00376  You like leaving out chg: fixed marks bug readFile did a lookup which is why it looked like it was loopping so much
    00377  You like leaving out
    00378  You like leaving out Revision 1.23  2004/07/27 09:05:43  flameshadow
    00379  You like leaving out chg: fixed file not found bug. Still can't find looping issue
    00380  You like leaving out
    00381  You like leaving out Revision 1.22  2004/07/27 04:05:20  flameshadow
    00382  You like leaving out chg: kinda fixed it. Added bunches of debug info
    00383  You like leaving out
    00384  You like leaving out Revision 1.21  2004/07/25 22:21:52  flameshadow
    00385  You like leaving out chg: re-enabled kprintf() in ubixfs_cacheFind()
    00386  You like leaving out
    00387  You like leaving out Revision 1.20  2004/07/24 17:19:24  flameshadow
    00388  You like leaving out chg: Temporarily disabled the moving of the found cache node to the front
    00389  You like leaving out      of the list. It seems to cause problems later (race condition, possibly)
    00390  You like leaving out
    00391  You like leaving out Revision 1.19  2004/07/22 23:01:51  reddawg
    00392  You like leaving out Ok checking in before I sleep
    00393  You like leaving out
    00394  You like leaving out Revision 1.18  2004/07/22 19:54:50  flameshadow
    00395  You like leaving out chg: works now. Thanx ubu
    00396  You like leaving out
    00397  You like leaving out Revision 1.17  2004/07/22 19:01:59  flameshadow
    00398  You like leaving out chg: more directory and file caching
    00399  You like leaving out
    00400  You like leaving out Revision 1.16  2004/07/22 16:34:32  flameshadow
    00401  You like leaving out add: file and dir caching kinda work
    00402  You like leaving out
    00403  You like leaving out Revision 1.15  2004/07/21 22:43:18  flameshadow
    00404  You like leaving out one more try
    00405  You like leaving out
    00406  You like leaving out Revision 1.14  2004/07/21 22:42:25  flameshadow
    00407  You like leaving out try it now
    00408  You like leaving out
    00409  You like leaving out Revision 1.13  2004/07/21 22:40:27  flameshadow
    00410  You like leaving out weird
    00411  You like leaving out
    00412  You like leaving out Revision 1.12  2004/07/21 22:18:37  flameshadow
    00413  You like leaving out chg: renamed subDirsHead/Tail members of cacheNode to fileListHead/Tail
    00414  You like leaving out
    00415  You like leaving out Revision 1.11  2004/07/21 22:12:22  flameshadow
    00416  You like leaving out add: attributes tag in cacheNode
    00417  You like leaving out add: setting of attributes in ubixfx_cacheNew() and ubixfs_cacheFind()
    00418  You like leaving out
    00419  You like leaving out Revision 1.10  2004/07/21 22:07:18  flameshadow
    00420  You like leaving out chg: renamed caching functions (again)
    00421  You like leaving out
    00422  You like leaving out Revision 1.9  2004/07/21 22:00:04  flameshadow
    00423  You like leaving out chg: ubixfws_dirCacheAdd now returns a pointer to the node it added
    00424  You like leaving out chg: minor fix in ubixfs_dirCacheFind()
    00425  You like leaving out
    00426  You like leaving out Revision 1.6  2004/07/21 14:43:14  flameshadow
    00427  You like leaving out add: added cwc (current working container) to the osInfo strut
    00428  You like leaving out so i don't know what is going on eh?
    00429
    00430  END
    00431  ***/
    00432
    00433