00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 #include <ubixfs/ubixfs.h>
00031 #include <ubixfs/dirCache.h>
00032 #include <vfs/vfs.h>
00033 #include <ubixos/types.h>
00034 #include <ubixos/sched.h>
00035 #include <ubixos/kpanic.h>
00036 #include <ubixos/exec.h>
00037 #include <lib/kmalloc.h>
00038 #include <lib/string.h>
00039 #include <lib/kprintf.h>
00040 #include <assert.h>
00041 
00042 
00043 static int ubixfs_loadData(fileDescriptor *fd,char *data,uInt32 size,uInt32 batIndex);
00044 
00045   
00046 static int openFileUbixFS(const char *file, fileDescriptor *fd) {
00047   
00048 
00049   struct cacheNode * cacheNode = NULL;
00050   
00051   struct ubixFSInfo *fsInfo = fd->mp->fsInfo;
00052   
00053 
00054   
00055 
00056 
00057 
00058   assert(fd);
00059   assert(fd->mp);
00060   assert(fd->mp->device);
00061   assert(fd->mp->device->devInfo);
00062   assert(fd->mp->device->devInfo->read);
00063   assert(fsInfo);
00064   assert(fsInfo->dirCache);
00065   assert(file);
00066   
00067   if ((fd->mode & fileRead) == fileRead) {
00068     do {
00069       cacheNode = ubixfs_cacheFind(fsInfo->dirCache,(char *) file);
00070       if (cacheNode == NULL) return 0;
00071       if (cacheNode->present == 1) break;
00072       assert(cacheNode->size);
00073       if (*cacheNode->size != 0 && cacheNode->info == NULL) {
00074         
00075         cacheNode->info = kmalloc(UBIXFS_ALIGN(*cacheNode->size));
00076         fd->size = *cacheNode->size; 
00077         assert(cacheNode->startCluster);
00078         ubixfs_loadData(fd,
00079                         cacheNode->info,
00080                         *cacheNode->size,
00081                         *cacheNode->startCluster);
00082         cacheNode->present = 1;
00083       } 
00084     } while(1);
00085 
00086     assert(cacheNode);
00087     if (cacheNode == NULL) return 0; 
00088 
00089     fd->start    = *cacheNode->startCluster;
00090     fd->size     = *cacheNode->size;
00091     fd->perms    = *cacheNode->permissions;
00092     fd->cacheNode = cacheNode; 
00093     
00094 
00095 
00096 
00097 
00098 
00099 
00100     return(0x1);
00101   } 
00102   else 
00103     if ((fd->mode & fileWrite) == fileWrite) {
00104 kprintf("Ouch! in filewrite!\n");
00105 #if 0
00106       fd->start    = dirEntry->startCluster;
00107       fd->size     = dirEntry->size;
00108       fd->perms    = dirEntry->permissions;
00109      
00110 #endif
00111       return(0x1);
00112     }
00113     
00114   return 0;
00115 
00116   }
00117 
00118 int writeFileByte(int ch, fileDescriptor *fd, long offset) {
00119 
00120   int blockCount = 0x0,batIndex = 0x0,batIndexPrev = 0x0;
00121   uInt32 i = 0x0;
00122   struct directoryEntry *dirEntry = 0x0;
00123   struct ubixFSInfo *fsInfo = NULL;
00124 
00125   assert(fd);
00126   assert(fd->mp);
00127   assert(fd->mp->diskLabel);
00128 
00129   batIndexPrev = fd->start;
00130   fsInfo = fd->mp->fsInfo;
00131 
00132   
00133   blockCount = (offset/4096);
00134   
00135   
00136   for (i=0x0; i <= fd->mp->diskLabel->partitions[fd->mp->partition].pBatSize;
00137        i++) {
00138     batIndex = fsInfo->blockAllocationTable[batIndexPrev].nextBlock;
00139     if (batIndex == 0x0) {
00140       break;
00141       }
00142     batIndexPrev = batIndex;
00143     }
00144 
00145   if ((offset%4096 == 0) && (fd->status == fdRead)) {
00146       fd->status = fdOpen;
00147       }    
00148 
00149   
00150   if (batIndex == 0x0) {
00151     for (i=1;i < fsInfo->batEntries;i++) {
00152       if (fsInfo->blockAllocationTable[i].attributes == 0x0) {
00153         fsInfo->blockAllocationTable[batIndexPrev].nextBlock = i;
00154         fsInfo->blockAllocationTable[batIndex].nextBlock     = -1;
00155         batIndex  = i;
00156         fd->start = i;
00157         break;
00158         }
00159       }
00160     
00161     fd->buffer[offset-(blockCount*4096)] = ch;
00162     fd->mp->device->devInfo->write(fd->mp->device->devInfo->info,fd->buffer,fd->mp->diskLabel->partitions[fd->mp->partition].pOffset+fsInfo->blockAllocationTable[batIndex].realSector,8);
00163     }
00164   else {
00165     if (fd->status != fdRead) {    
00166       fd->mp->device->devInfo->read(fd->mp->device->devInfo->info,fd->buffer,fd->mp->diskLabel->partitions[fd->mp->partition].pOffset+fsInfo->blockAllocationTable[batIndex].realSector,8);
00167       fd->status = fdRead;
00168       }
00169     fd->buffer[offset-(blockCount*4096)] = ch;
00170     fd->mp->device->devInfo->write(fd->mp->device->devInfo->info,fd->buffer,fd->mp->diskLabel->partitions[fd->mp->partition].pOffset+fsInfo->blockAllocationTable[batIndex].realSector,8);
00171     }    
00172   if ((uInt32)offset > fd->size) {
00173     fd->size = offset;
00174     dirEntry = (struct directoryEntry *)kmalloc(4096);
00175   
00176 
00177 
00178     for (i=0x0;i<(4096/sizeof(struct directoryEntry));i++) {
00179       if ((int)!strcmp(dirEntry[i].fileName,fd->fileName))
00180         break;
00181       }  
00182     dirEntry[i].size = fd->size;
00183 
00184 
00185 
00186     kfree(dirEntry);
00187     }
00188   return(ch);
00189   }
00190 
00191 
00192 
00193     
00194 int readUbixFS(fileDescriptor *fd,char *data,uInt32 offset,long size) {
00195   int i = 0x0;
00196   char *buffer = 0x0;
00197   struct ubixFSInfo *fsInfo = NULL;
00198 
00199   assert(fd);
00200   assert(fd->mp);
00201   assert(fd->mp->fsInfo);
00202 
00203   fsInfo = fd->mp->fsInfo;
00204   
00205   if (fd->cacheNode->present != 1) 
00206     kpanic("ERROR with cache node\n");
00207     
00208   buffer = (char *)fd->cacheNode->info;
00209   
00210   for (i=0x0; i<size; i++) {
00211     if (offset > fd->size) {
00212       
00213       
00214       fd->status = fdEof;
00215       return(size);
00216       }
00217     
00218     data[i] = buffer[i + offset];
00219     }
00220   
00221   return(size);
00222   }
00223 
00224 
00225 
00226 
00227 
00228 
00229 
00230 
00231 
00232 int writeUbixFS(fileDescriptor *fd,char *data,long offset,long size) {
00233   uInt32 blockOffset    = 0x0;
00234   uInt32 blockIndex;
00235   uInt32 blockIndexPrev;
00236   uInt32 i              = 0x0;
00237   struct ubixFSInfo *fsInfo = NULL;
00238   struct directoryEntry *dirEntry = 0x0;
00239 
00240   assert(fd);
00241   assert(fd->mp);
00242   assert(fd->mp->fsInfo);
00243   assert(fd->mp->device);
00244   assert(fd->mp->device->devInfo);
00245 
00246   blockIndex = blockIndexPrev = fd->start;
00247   fsInfo = fd->mp->fsInfo;
00248 
00249   blockOffset = (offset/0x1000);
00250 
00251   if (fd->size != 0x0) {
00252     for (i = 0x0;i < blockOffset;i++) {
00253       blockIndex = fsInfo->blockAllocationTable[blockIndexPrev].nextBlock;
00254         if ((int)blockIndex == EOBC) {
00255           blockIndex = getFreeBlocks(1,fd);
00256           fsInfo->blockAllocationTable[blockIndexPrev].nextBlock = blockIndex;
00257           fsInfo->blockAllocationTable[blockIndex].nextBlock = EOBC;
00258           break;
00259           }
00260         blockIndexPrev = blockIndex;
00261       }
00262     }
00263 
00264   fd->mp->device->devInfo->read(fd->mp->device->devInfo->info,fd->buffer,fd->mp->diskLabel->partitions[fd->mp->partition].pOffset+fsInfo->blockAllocationTable[blockIndex].realSector,blockSize);
00265   for (i = 0x0;i < (uInt32)size;i++) {
00266 
00267     fd->buffer[(offset- (blockOffset *0x1000))] = data[i];
00268     offset++;
00269 
00270     if (offset%4096 == 0x0) {
00271       blockOffset++;
00272       fd->mp->device->devInfo->write(fd->mp->device->devInfo->info,fd->buffer,fd->mp->diskLabel->partitions[fd->mp->partition].pOffset+fsInfo->blockAllocationTable[blockIndex].realSector,blockSize);
00273  
00274       if (fsInfo->blockAllocationTable[blockIndex].nextBlock == EOBC) {
00275         blockIndexPrev = blockIndex;
00276         blockIndex = getFreeBlocks(1,fd);
00277         fsInfo->blockAllocationTable[blockIndexPrev].nextBlock = blockIndex;
00278         fsInfo->blockAllocationTable[blockIndex].nextBlock     = EOBC;
00279         }
00280       else {
00281         blockIndex = fsInfo->blockAllocationTable[blockIndex].nextBlock;
00282         fd->mp->device->devInfo->read(fd->mp->device->devInfo->info,fd->buffer,fd->mp->diskLabel->partitions[fd->mp->partition].pOffset+fsInfo->blockAllocationTable[blockIndex].realSector,blockSize);
00283         }
00284       }
00285     }
00286   fd->mp->device->devInfo->write(fd->mp->device->devInfo->info,fd->buffer,fd->mp->diskLabel->partitions[fd->mp->partition].pOffset+fsInfo->blockAllocationTable[blockIndex].realSector,blockSize);
00287 
00288   if ((uInt32)offset > fd->size) {
00289     fd->size = offset;
00290     dirEntry = (struct directoryEntry *)kmalloc(4096);
00291 
00292 
00293 
00294     for (i=0x0;i<(4096/sizeof(struct directoryEntry));i++) {
00295       if ((int)!strcmp(dirEntry[i].fileName,fd->fileName))
00296         break;
00297       }
00298     dirEntry[i].size = fd->size;
00299     dirEntry[i].startCluster = fd->start;
00300 
00301 
00302 
00303     kfree(dirEntry);
00304     }
00305   
00306   return(size);
00307   }
00308 
00309 void ubixFSUnlink(char *path,vfs_mountPoint_t *mp) {
00310   int x=0;
00311   struct directoryEntry *dirEntry = (struct directoryEntry *)kmalloc(0x1000);
00312   struct ubixFSInfo *fsInfo = mp->fsInfo;
00313   
00314   mp->device->devInfo->read(mp->device->devInfo->info,dirEntry,(mp->diskLabel->partitions[mp->partition].pOffset+fsInfo->blockAllocationTable[fsInfo->rootDir].realSector),8);
00315 
00316   for (x=0;(uInt32)x<(4096/sizeof(struct directoryEntry));x++) {
00317     if ((int)!strcmp(dirEntry[x].fileName,path)) {
00318       dirEntry[x].attributes |= typeDeleted;
00319       dirEntry[x].fileName[0] = '?';
00320       mp->device->devInfo->write(mp->device->devInfo->info,dirEntry,(mp->diskLabel->partitions[mp->partition].pOffset+fsInfo->blockAllocationTable[fsInfo->rootDir].realSector),8);
00321       return;
00322       }
00323     }
00324   kprintf("File Not Found\n");
00325   return;
00326   }
00327   
00328   
00329 
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 
00338 
00339 
00340     
00341 static int ubixfs_loadData(fileDescriptor *fd,char *data,uInt32 size,uInt32 batIndex) {
00342   uInt32 i = 0x0;
00343 
00344   struct ubixFSInfo *fsInfo = NULL;
00345 
00346   assert(fd);
00347   assert(fd->mp);
00348   assert(fd->mp->fsInfo);
00349 
00350   fsInfo = fd->mp->fsInfo;
00351 
00352   size = UBIXFS_ALIGN(size);
00353   
00354   
00355   for (i=0x0; i<size; i += (UBIXFS_BLOCKSIZE_BYTES)) {
00356   
00357     if (i != 0x0)
00358       batIndex = fsInfo->blockAllocationTable[batIndex].nextBlock;
00359   
00360     fd->mp->device->devInfo->read(fd->mp->device->devInfo->info,data+i,fd->mp->diskLabel->partitions[fd->mp->partition].pOffset+fsInfo->blockAllocationTable[batIndex].realSector,blockSize);
00361     }
00362   
00363   return(0x0);
00364   }
00365 
00366 
00367 
00368 
00369 
00370 
00371 
00372 
00373 
00374 
00375   
00376 int ubixfs_initialize(vfs_mountPoint_t *mp) {
00377   struct ubixFSInfo *fsInfo = 0x0;
00378 
00379   assert(mp);
00380   assert(mp->diskLabel);
00381   assert(mp->diskLabel->partitions);
00382 
00383   mp->fsInfo = (struct ubixFSInfo *)kmalloc(sizeof(struct ubixFSInfo));
00384   assert(mp->fsInfo);
00385   
00386   fsInfo = mp->fsInfo;
00387   fsInfo->rootDir = 0x0; 
00388   
00389   
00390 
00391 
00392   if ((mp->diskLabel->magicNum == UBIXDISKMAGIC) &&  (mp->diskLabel->magicNum2 == UBIXDISKMAGIC)) {
00393     
00394     
00395     fsInfo->blockAllocationTable = (struct blockAllocationTableEntry *)kmalloc(mp->diskLabel->partitions[mp->partition].pBatSize * 512);
00396     assert(fsInfo->blockAllocationTable);
00397 
00398     
00399     fsInfo->batEntries = (mp->diskLabel->partitions[mp->partition].pBatSize*512) / sizeof(struct blockAllocationTableEntry);
00400 
00401     
00402     assert(mp->device->devInfo->read);
00403     mp->device->devInfo->read(mp->device->devInfo->info, 
00404                              fsInfo->blockAllocationTable,
00405                              mp->diskLabel->partitions[mp->partition].pOffset,
00406                              mp->diskLabel->partitions[mp->partition].pBatSize);
00407     
00408     
00409     fsInfo->dirCache = ubixfs_cacheNew("/");
00410     assert(fsInfo->dirCache);
00411     fsInfo->dirCache->info = (struct directoryEntry *)kmalloc(0x4000);  
00412     fsInfo->dirCache->present = 1;
00413     fsInfo->dirCache->size = kmalloc(sizeof(fsInfo->dirCache->size));
00414     fsInfo->dirCache->startCluster = kmalloc(sizeof(fsInfo->dirCache->startCluster));
00415     fsInfo->dirCache->attributes = kmalloc(sizeof(fsInfo->dirCache->attributes));
00416     fsInfo->dirCache->permissions = kmalloc(sizeof(fsInfo->dirCache->permissions));
00417 
00418     *fsInfo->dirCache->size = 0x4000;
00419     *fsInfo->dirCache->startCluster = fsInfo->rootDir;
00420     
00421     assert(fsInfo->dirCache->info);
00422     
00423     mp->device->devInfo->read(mp->device->devInfo->info,
00424                               fsInfo->dirCache->info,
00425                               (mp->diskLabel->partitions[mp->partition].pOffset+fsInfo->blockAllocationTable[fsInfo->rootDir].realSector),
00426                               0x4000 / 512);
00427 
00428     
00429     
00430 
00431 
00432 
00433     kprintf("  Offset: [%i], Partition: [%i]\n",
00434     mp->diskLabel->partitions[mp->partition].pOffset,mp->partition);
00435     kprintf("UbixFS Initialized\n");
00436     return(0x1);
00437     }
00438     
00439   kprintf("Not a valid UbixFS disk.\n");
00440   
00441   return(0x0);
00442   }
00443   
00444 
00445 
00446 
00447 
00448 
00449 
00450 
00451 
00452 
00453 
00454 
00455   
00456 int ubixfs_init() {
00457   
00458   struct fileSystem ubixFileSystem = 
00459    {NULL,                         
00460     NULL,                         
00461     (void *)ubixfs_initialize,    
00462     (void *)readUbixFS,           
00463     (void *)writeUbixFS,          
00464     (void *)openFileUbixFS,       
00465     (void *)ubixFSUnlink,         
00466     (void *)ubixFSmkDir,          
00467     NULL,                         
00468     NULL,                         
00469     0                             
00470    }; 
00471 
00472   
00473   if (vfsRegisterFS(ubixFileSystem) != 0x0) {
00474     kpanic("Unable To Enable UbixFS");
00475     return(0x1);
00476     }
00477 
00478   
00479   return(0x0);
00480   }
00481 
00482 
00483 
00484 
00485 
00486 
00487 
00488 
00489 
00490 
00491 
00492 
00493 
00494 
00495 
00496 
00497 
00498 
00499 
00500 
00501 
00502 
00503 
00504 
00505 
00506 
00507 
00508 
00509 
00510 
00511 
00512 
00513 
00514 
00515 
00516 
00517 
00518 
00519 
00520 
00521 
00522 
00523 
00524 
00525 
00526 
00527 
00528 
00529 
00530 
00531 
00532 
00533 
00534 
00535 
00536 
00537 
00538 
00539 
00540 
00541 
00542 
00543 
00544 
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 
00553 
00554 
00555 
00556 
00557 
00558 
00559 
00560 
00561 
00562 
00563 
00564 
00565 
00566 
00567 
00568 
00569 
00570 
00571 
00572 
00573 
00574 
00575 
00576 
00577 
00578 
00579 
00580 
00581 
00582 
00583 
00584 
00585 
00586 
00587 
00588 
00589 
00590 
00591 
00592 
00593 
00594 
00595 
00596 
00597 
00598 
00599 
00600 
00601 
00602 
00603 
00604 
00605 
00606 
00607 
00608 
00609 
00610 
00611 
00612 
00613 
00614 
00615 
00616 
00617 
00618 
00619 
00620 
00621 
00622 
00623 
00624 
00625 
00626 
00627 
00628 
00629 
00630 
00631 
00632 
00633 
00634 
00635 
00636 
00637 
00638 
00639 
00640