diff --git a/src/sys/ubixfsv2/ubixfs.cpp b/src/sys/ubixfsv2/ubixfs.cpp index e74c7c5..0ad3bc7 100644 --- a/src/sys/ubixfsv2/ubixfs.cpp +++ b/src/sys/ubixfsv2/ubixfs.cpp @@ -125,6 +125,209 @@ return 0; } // UbixFS::init +int +UbixFS::vfs_format(device_t * dev) { + cout << "vfs_format()" << endl; + char sector[512]; + uInt32 blocks, batSect, batSize; + if (dev == NULL) return -1; + + // zero out the sector + memset(§or, 0x0, sizeof(sector)); + + // fill the drive in with zeroed out sectors + cout << "dev->sectors: " << dev->sectors << endl; + cout << "clearing device..."; + + for (unsigned int i = 0; i < dev->sectors; i++) { + dev->write(dev, §or, i, 1); + } // for i + + cout << "done" << endl; + + // allocate a new superBlock and clear it + + diskSuperBlock *sb = new diskSuperBlock; + if (sb == NULL) return -1; + memset(sb, 0, sizeof(diskSuperBlock)); + + // dev->sectors is the number of 512 byte sectors + + blocks = (dev->sectors-1) / 8; // 4k blocks + batSize = (dev->sectors-1) % 8; // remainder + + // compute the BAT size + + while ((batSize * 4096) < blocks) { + batSize += 8; + --blocks; + } // while + + // batSize is in sectors + batSect = blocks * 8; + + strcpy(sb->name, "UbixFS"); + sb->magic1 = UBIXFS_MAGIC1; + sb->fsByteOrder = 0; + sb->blockSize = 4096; + sb->blockShift = 12; + sb->numBlocks = blocks; + sb->usedBlocks = 2; // root dir takes two blocks (inode + bTree header) + sb->inodeCount = 1; + sb->inodeSize = 4096; + sb->magic2 = UBIXFS_MAGIC2; + sb->blocksPerAG = 2048; + sb->AGShift = 11; + sb->numAGs = (sb->numBlocks+2047) / 2048; + sb->lastUsedAG = 0; + + // the BAT exists outside our official block count, so no + // entries in the BAT need to be set for it + sb->batSectors = batSize; + + sb->flags = 0x434C454E; // CLEN + sb->logBlocks.AG = 0; + sb->logBlocks.start = 0; + sb->logBlocks.len = 0; + sb->logStart = 0; + sb->logEnd = 0; + sb->magic3 = UBIXFS_MAGIC3; + sb->indicies.AG = 0; + sb->indicies.start = 0; + sb->indicies.len = 0; + + sb->rootDir.AG = 0; + sb->rootDir.start = 0; + sb->rootDir.len = 1; + + // write out the superBlock + + dev->write(dev, sb, dev->sectors-1, 1); + + // mark the first two 4k blocks used + memset(§or, 0, sizeof(sector)); + sector[0] = (1 << 7) | (1 << 6); + + // write out the first sector of the BAT + + dev->write(dev, §or, batSect, 1); + // clear the rest + sector[0] = 0; + + // write out the rest of the BAT + + for (unsigned int i = 1; i < batSize; i++) { + dev->write(dev, §or, (batSect)+i, 1); + } // for i + + /* allocate part of the root dir */ + + // sanity checks + assert(sb->blockSize); + assert((unsigned)sb->blockSize >= sizeof(bTreeHeader)); + + bTreeHeader * bth = new bTreeHeader; + assert(bth); + memset(bth, 0, sizeof(bTreeHeader)); + + bth->firstDeleted = -1; + bth->firstNodeOffset = -1; + bth->treeDepth = 1; + bth->treeWidth = 0; + bth->treeLeafCount = 0; + + /* create the root dir inode here */ + + ubixfsInode * inode = new ubixfsInode; + assert(inode); + if (inode == NULL) return -1; + memset(inode, 0, sizeof(ubixfsInode)); + + inode->magic1 = UBIXFS_INODE_MAGIC; + + // inodes point to themselves + inode->inodeNum.AG = 0; + inode->inodeNum.start = 0; + inode->inodeNum.len = 1; + + // root dir has no parent directory + inode->parent.iAddr.AG = 0; + inode->parent.iAddr.start = 0; + inode->parent.iAddr.len = 0; + + /* this is part of the root dir structure (the bTreeHeader) */ + inode->blocks.direct[0].AG = 0; + inode->blocks.direct[0].start = 1; + inode->blocks.direct[0].len = 1; + + inode->blocks.maxDirectRange = sizeof(bTreeHeader); + inode->blocks.size = sizeof(bTreeHeader); + + strcpy(inode->name, "/"); + inode->uid = getuid(); + inode->gid = getgid(); + // inode->mode + inode->flags = INODE_DIRECTORY; + // inode->createTime + // inode->lastModifiedTime + // inode->type + + inode->attributes.AG = 0; + inode->attributes.start = 0; + inode->attributes.len = 0; + + inode->inodeSize = sb->inodeSize; + + /* + * next and prev are used in memory to hold pointers to the next/prev + * inodes in this dir. On disk they may have another value, but for + * now they should be set to null. + */ + + inode->next.offset = 0; + inode->prev.offset = 0; + + // write out the "root" dir inode + + dev->write(dev, + inode, + ((inode->inodeNum.AG << sb->AGShift) + + inode->inodeNum.start) * (sb->blockSize / 512), + sb->inodeSize / 512 + ); // dev->write + + // write out the "root" dir + + dev->write(dev, + bth, + ((inode->blocks.direct[0].AG << sb->AGShift) + + inode->blocks.direct[0].start) * (sb->blockSize / 512), + sb->blockSize / 512 + ); // dev->write + + delete inode; + delete bth; + delete sb; + cout << "format complete" << endl; + return 0; +} // UbixFS::vfs_format + +void * +UbixFS::vfs_mknod(const char *path, mode_t mode) { + return mknod(path, 0); +} // UbixFS::mknod + +int +UbixFS::vfs_open(const char * filename, fileDescriptor * fd, int flags, ...) { + if (filename == NULL || fd == NULL) return -1; + flags = flags; + fd->inode = NULL; + fd->offset = 0; + fd->size = 0; + // look up the file here + return 0; +} // UbixFS::vfs_open + size_t UbixFS::vfs_read(fileDescriptor * fd, void * data, off_t offset, size_t size) { @@ -221,6 +424,49 @@ return totalSize; } // UbixFS::vfs_write +int +UbixFS::vfs_stop(void) { + if (vfs_sync() != 0) return -1; + + // you must delete the root dir first, in case it needs to + // still write anything out + + if (root != NULL) { + ubixfsInode * rootInode = static_cast(root->inode); + delete rootInode->data.btPtr; + delete rootInode; + root->inode = NULL; + + } // if + + delete root; + delete [] freeBlockList; + delete superBlock; + + freeBlockList = NULL; + superBlock = NULL; + root = NULL; + + /* + * The device isn't null at this point, allowing for people to restart + * the mount point. Or, alternatively, to blow things up. + */ + + return 0; +} // UbixFS::vfs_stop + +int +UbixFS::vfs_sync(void) { + if (device == NULL || superBlock == NULL || freeBlockList == NULL) return -1; + device->write(device, + freeBlockList, + device->sectors - superBlock->batSectors - 1, + superBlock->batSectors + ); + device->write(device, superBlock, device->sectors-1, 1); + return 0; +} // UbixFS::vfs_sync + void UbixFS::setFreeBlock(blockRun ibr) { signed char * ptr; @@ -491,9 +737,14 @@ // inode->flags // inode->createTime // inode->lastModifiedTime - // inode->type inode->inodeSize = superBlock->inodeSize; + inode->attributes.AG = 0; + inode->attributes.start = 0; + inode->attributes.len = 0; + + // inode->type + /* * next and prev are used in memory to hold pointers to the next/prev * inodes in this dir. On disk they may have another value, but for @@ -502,15 +753,11 @@ inode->next.offset = 0; inode->prev.offset = 0; + inode->refCount = 0; ++superBlock->inodeCount; return inode; } // UbixFS::mknod -void * -UbixFS::vfs_mknod(const char *path, mode_t mode) { - return mknod(path, 0); -} // UbixFS::mknod - void UbixFS::printFreeBlockList(uInt32 AG) { unsigned int j; @@ -532,231 +779,6 @@ return; } // UbixFS::printFreeBlockList -int -UbixFS::vfs_format(device_t * dev) { - cout << "vfs_format()" << endl; - char sector[512]; - uInt32 blocks, batSect, batSize; - if (dev == NULL) return -1; - - // zero out the sector - memset(§or, 0x0, sizeof(sector)); - - // fill the drive in with zeroed out sectors - cout << "dev->sectors: " << dev->sectors << endl; - cout << "clearing device..."; - - for (unsigned int i = 0; i < dev->sectors; i++) { - dev->write(dev, §or, i, 1); - } // for i - - cout << "done" << endl; - - // allocate a new superBlock and clear it - - diskSuperBlock *sb = new diskSuperBlock; - if (sb == NULL) return -1; - memset(sb, 0, sizeof(diskSuperBlock)); - - // dev->sectors is the number of 512 byte sectors - - blocks = (dev->sectors-1) / 8; // 4k blocks - batSize = (dev->sectors-1) % 8; // remainder - - // compute the BAT size - - while ((batSize * 4096) < blocks) { - batSize += 8; - --blocks; - } // while - - // batSize is in sectors - batSect = blocks * 8; - - strcpy(sb->name, "UbixFS"); - sb->magic1 = UBIXFS_MAGIC1; - sb->fsByteOrder = 0; - sb->blockSize = 4096; - sb->blockShift = 12; - sb->numBlocks = blocks; - sb->usedBlocks = 2; // root dir takes two blocks (inode + bTree header) - sb->inodeCount = 1; - sb->inodeSize = 4096; - sb->magic2 = UBIXFS_MAGIC2; - sb->blocksPerAG = 2048; - sb->AGShift = 11; - sb->numAGs = (sb->numBlocks+2047) / 2048; - sb->lastUsedAG = 0; - - // the BAT exists outside our official block count, so no - // entries in the BAT need to be set for it - sb->batSectors = batSize; - - sb->flags = 0x434C454E; // CLEN - sb->logBlocks.AG = 0; - sb->logBlocks.start = 0; - sb->logBlocks.len = 0; - sb->logStart = 0; - sb->logEnd = 0; - sb->magic3 = UBIXFS_MAGIC3; - sb->indicies.AG = 0; - sb->indicies.start = 0; - sb->indicies.len = 0; - - sb->rootDir.AG = 0; - sb->rootDir.start = 0; - sb->rootDir.len = 1; - - // write out the superBlock - - dev->write(dev, sb, dev->sectors-1, 1); - - // mark the first two 4k blocks used - memset(§or, 0, sizeof(sector)); - sector[0] = (1 << 7) | (1 << 6); - - // write out the first sector of the BAT - - dev->write(dev, §or, batSect, 1); - // clear the rest - sector[0] = 0; - - // write out the rest of the BAT - - for (unsigned int i = 1; i < batSize; i++) { - dev->write(dev, §or, (batSect)+i, 1); - } // for i - - /* allocate part of the root dir */ - - // sanity checks - assert(sb->blockSize); - assert((unsigned)sb->blockSize >= sizeof(bTreeHeader)); - - bTreeHeader * bth = new bTreeHeader; - assert(bth); - memset(bth, 0, sizeof(bTreeHeader)); - - bth->firstDeleted = -1; - bth->firstNodeOffset = -1; - bth->treeDepth = 1; - bth->treeWidth = 0; - bth->treeLeafCount = 0; - - /* create the root dir inode here */ - - ubixfsInode * inode = new ubixfsInode; - assert(inode); - if (inode == NULL) return -1; - memset(inode, 0, sizeof(ubixfsInode)); - - inode->magic1 = UBIXFS_INODE_MAGIC; - - // inodes point to themselves - inode->inodeNum.AG = 0; - inode->inodeNum.start = 0; - inode->inodeNum.len = 1; - - // root dir has no parent directory - inode->parent.iAddr.AG = 0; - inode->parent.iAddr.start = 0; - inode->parent.iAddr.len = 0; - - /* this is part of the root dir structure (the bTreeHeader) */ - inode->blocks.direct[0].AG = 0; - inode->blocks.direct[0].start = 1; - inode->blocks.direct[0].len = 1; - - inode->blocks.maxDirectRange = sizeof(bTreeHeader); - inode->blocks.size = sizeof(bTreeHeader); - - strcpy(inode->name, "/"); - inode->uid = getuid(); - inode->gid = getgid(); - // inode->mode - inode->flags = INODE_DIRECTORY; - // inode->createTime - // inode->lastModifiedTime - // inode->type - inode->inodeSize = sb->inodeSize; - - /* - * next and prev are used in memory to hold pointers to the next/prev - * inodes in this dir. On disk they may have another value, but for - * now they should be set to null. - */ - - inode->next.offset = 0; - inode->prev.offset = 0; - - // write out the "root" dir inode - - dev->write(dev, - inode, - ((inode->inodeNum.AG << sb->AGShift) + - inode->inodeNum.start) * (sb->blockSize / 512), - sb->inodeSize / 512 - ); // dev->write - - // write out the "root" dir - - dev->write(dev, - bth, - ((inode->blocks.direct[0].AG << sb->AGShift) + - inode->blocks.direct[0].start) * (sb->blockSize / 512), - sb->blockSize / 512 - ); // dev->write - - delete inode; - delete bth; - delete sb; - cout << "format complete" << endl; - return 0; -} // UbixFS::vfs_format - -int -UbixFS::vfs_stop(void) { - if (vfs_sync() != 0) return -1; - - // you must delete the root dir first, in case it needs to - // still write anything out - - if (root != NULL) { - ubixfsInode * rootInode = static_cast(root->inode); - delete rootInode->data.btPtr; - delete rootInode; - root->inode = NULL; - - } // if - - delete root; - delete [] freeBlockList; - delete superBlock; - - freeBlockList = NULL; - superBlock = NULL; - root = NULL; - - /* - * The device isn't null at this point, allowing for people to restart - * the mount point. Or, alternatively, to blow things up. - */ - - return 0; -} // UbixFS::vfs_stop - -int -UbixFS::vfs_sync(void) { - if (device == NULL || superBlock == NULL || freeBlockList == NULL) return -1; - device->write(device, - freeBlockList, - device->sectors - superBlock->batSectors - 1, - superBlock->batSectors - ); - device->write(device, superBlock, device->sectors-1, 1); - return 0; -} // UbixFS::vfs_sync - UbixFS::~UbixFS(void) { delete [] freeBlockList; return; diff --git a/src/sys/ubixfsv2/ubixfs.h b/src/sys/ubixfsv2/ubixfs.h index cf8a12e..486a75a 100644 --- a/src/sys/ubixfsv2/ubixfs.h +++ b/src/sys/ubixfsv2/ubixfs.h @@ -108,24 +108,25 @@ } dataStream; typedef struct ubixfsInode { - int32 magic1 __attribute__ ((packed)); - inodeAddr inodeNum __attribute__ ((packed)); + int32 magic1 __attribute__ ((packed)); + inodeAddr inodeNum __attribute__ ((packed)); char name[MAX_FILENAME_LENGTH] __attribute__ ((packed)); - uid_t uid __attribute__ ((packed)); - gid_t gid __attribute__ ((packed)); - int32 mode __attribute__ ((packed)); - int32 flags __attribute__ ((packed)); - // uInt64 createTime __attribute_ ((packed)); - // uInt64 lastModifiedTime __attribute__ (packed)); -// inodeAddr attributes __attribute__ ((packed)); - uInt32 type __attribute__ ((packed)); - int32 inodeSize __attribute__ ((packed)); - uPtr parent __attribute__ ((packed)); - uPtr next __attribute__ ((packed)); - uPtr prev __attribute__ ((packed)); - uPtr data __attribute__ ((packed)); - dataStream blocks __attribute__ ((packed)); - char smallData[3212] __attribute__ ((packed)); + uid_t uid __attribute__ ((packed)); + gid_t gid __attribute__ ((packed)); + int32 mode __attribute__ ((packed)); + int32 flags __attribute__ ((packed)); + // uInt64 createTime __attribute__ ((packed)); + // uInt64 lastModifiedTime __attribute__ (packed)); + inodeAddr attributes __attribute__ ((packed)); + uInt32 type __attribute__ ((packed)); + uInt32 inodeSize __attribute__ ((packed)); + uPtr parent __attribute__ ((packed)); + uPtr next __attribute__ ((packed)); + uPtr prev __attribute__ ((packed)); + uPtr data __attribute__ ((packed)); + dataStream blocks __attribute__ ((packed)); + uInt64 refCount __attribute__ ((packed)); + char smallData[3200] __attribute__ ((packed)); } ubixfsInode; class UbixFS : public vfs_abstract { @@ -133,21 +134,23 @@ signed char * freeBlockList; diskSuperBlock * superBlock; fileDescriptor * root; + blockRun getFreeBlock(blockRun); blockRun getFreeBlock(uInt32); blockRun getFreeBlock(void); blockRun get8FreeBlocks(uInt32); - void setFreeBlock(blockRun); - void * mknod(const char *, ubixfsInode *); uInt32 getNextAG(void); + void * mknod(const char *, ubixfsInode *); void printSuperBlock(void); void printFreeBlockList(uInt32); + void setFreeBlock(blockRun); public: UbixFS(void); UbixFS(device_t *); virtual int vfs_init(void); virtual int vfs_format(device_t *); virtual void * vfs_mknod(const char *, mode_t); + virtual int vfs_open(const char *, fileDescriptor *,int,...); virtual size_t vfs_read(fileDescriptor *, void *, off_t, size_t); virtual size_t vfs_write(fileDescriptor *, void *, off_t, size_t); virtual int vfs_sync(void);