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,struct vfs_mountPoint *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(struct vfs_mountPoint *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