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