Add mkdir support

This commit is contained in:
2017-04-25 22:01:21 -05:00
parent c5410c8755
commit 52f326f96c
2 changed files with 47 additions and 20 deletions
+20 -14
View File
@@ -35,6 +35,8 @@ class FileSystem {
public: public:
virtual ~FileSystem() {}; virtual ~FileSystem() {};
virtual int mkdir(const char *path) = 0;
virtual int read(const char *path, void *buffer, size_t buffSize) = 0; virtual int read(const char *path, void *buffer, size_t buffSize) = 0;
virtual int read(uint64_t inode, void *buffer, size_t size) = 0; virtual int read(uint64_t inode, void *buffer, size_t size) = 0;
@@ -107,7 +109,7 @@ class FileSystemTemplate: public FileSystem {
struct __attribute__((packed)) Directory { struct __attribute__((packed)) Directory {
/** /**
* Number of files in this directory. * Number of bytes after this Directory struct.
*/ */
typename FileStore::FsSize_t size = 0; typename FileStore::FsSize_t size = 0;
@@ -126,7 +128,7 @@ class FileSystemTemplate: public FileSystem {
explicit FileSystemTemplate(void *buff); explicit FileSystemTemplate(void *buff);
int mkdir(const char *path); int mkdir(const char *path) override;
int read(const char *path, void *buffer, size_t buffSize) override; int read(const char *path, void *buffer, size_t buffSize) override;
@@ -174,7 +176,8 @@ typename FileStore::InodeId_t FileSystemTemplate<FileStore, FS_TYPE>::INODE_ROOT
template<typename FileStore, FsType FS_TYPE> template<typename FileStore, FsType FS_TYPE>
int FileSystemTemplate<FileStore, FS_TYPE>::mkdir(const char *path) { int FileSystemTemplate<FileStore, FS_TYPE>::mkdir(const char *path) {
return 0; Directory dir;
return write(path, &dir, sizeof(dir), FileType::Directory);
} }
template<typename FileStore, FsType FS_TYPE> template<typename FileStore, FsType FS_TYPE>
@@ -316,10 +319,12 @@ int FileSystemTemplate<FileStore, FS_TYPE>::write(const char *path, void *buffer
inode = 0; inode = 0;
} }
} }
insertDirectoryEntry(dirPath, fileName, inode); err = insertDirectoryEntry(dirPath, fileName, inode);
} }
err = write(inode, buffer, size, fileType); if (!err) {
err = write(inode, buffer, size, fileType);
}
return err; return err;
} }
@@ -348,8 +353,8 @@ uint64_t FileSystemTemplate<FileStore, FS_TYPE>::findInodeOf(const char *path) {
char fileName[pathLen]; char fileName[pathLen];
uint64_t inode = INODE_ROOT_DIR; uint64_t inode = INODE_ROOT_DIR;
while (it.hasNext()) { while (it.hasNext()) {
auto dirStat = m_store->stat(inode); auto dirStat = stat(inode);
if (dirStat.size >= sizeof(Directory)) { if (dirStat.inode && dirStat.size >= sizeof(Directory)) {
uint8_t dirBuffer[dirStat.size]; uint8_t dirBuffer[dirStat.size];
auto dir = (Directory*) dirBuffer; auto dir = (Directory*) dirBuffer;
if (read(inode, dirBuffer, dirStat.size) == 0) { if (read(inode, dirBuffer, dirStat.size) == 0) {
@@ -405,10 +410,10 @@ uint8_t *FileSystemTemplate<FileStore, FS_TYPE>::buff() {
template<typename FileStore, FsType FS_TYPE> template<typename FileStore, FsType FS_TYPE>
uint8_t *FileSystemTemplate<FileStore, FS_TYPE>::format(void *buffer, typename FileStore::FsSize_t size, bool useDirectories) { uint8_t *FileSystemTemplate<FileStore, FS_TYPE>::format(void *buffer, typename FileStore::FsSize_t size, bool useDirectories) {
buffer = FileStore::format((uint8_t*) buffer, size, (uint16_t) FS_TYPE); buffer = FileStore::format((uint8_t*) buffer, size, (uint16_t) FS_TYPE);
FileSystemTemplate<FileStore, FS_TYPE> fs(buffer);
if (buffer && useDirectories) { if (buffer && useDirectories) {
Directory dir; Directory dir;
FileSystemTemplate<FileStore, FS_TYPE> fs(buffer);
fs.write(INODE_ROOT_DIR, &dir, sizeof(dir), FileType::Directory); fs.write(INODE_ROOT_DIR, &dir, sizeof(dir), FileType::Directory);
} }
@@ -425,13 +430,13 @@ template<typename FileStore, FsType FS_TYPE>
int FileSystemTemplate<FileStore, FS_TYPE>::insertDirectoryEntry(const char *dirPath, const char *fileName, uint64_t inode) { int FileSystemTemplate<FileStore, FS_TYPE>::insertDirectoryEntry(const char *dirPath, const char *fileName, uint64_t inode) {
auto s = stat(dirPath); auto s = stat(dirPath);
if (s.inode) { if (s.inode) {
size_t dirBuffSize = s.size + DirectoryEntry::spaceNeeded(fileName) + 100; size_t dirBuffSize = s.size + DirectoryEntry::spaceNeeded(fileName);
uint8_t dirBuff[dirBuffSize]; uint8_t dirBuff[dirBuffSize];
int err = read(s.inode, dirBuff, dirBuffSize); int err = read(s.inode, dirBuff, dirBuffSize);
if (!err) { if (!err) {
auto dir = (Directory*) dirBuff; auto dir = (Directory*) dirBuff;
dir->size += DirectoryEntry::spaceNeeded(fileName); dir->size++;
auto entry = (DirectoryEntry*) &dirBuff[s.size]; auto entry = (DirectoryEntry*) &dirBuff[s.size];
entry->inode = inode; entry->inode = inode;
entry->setName(fileName); entry->setName(fileName);
@@ -455,11 +460,12 @@ uint64_t FileSystemTemplate<FileStore, FS_TYPE>::Directory::getFileInode(const c
uint64_t inode = 0; uint64_t inode = 0;
auto current = files(); auto current = files();
if (current) { if (current) {
auto end = (DirectoryEntry*) (((uint8_t*) files()) + buffSize); for (uint64_t i = 1; ox_strcmp(current->getName(), name) != 0; i++) {
while (current && ox_strcmp(current->getName(), name) != 0) { if (i < this->size) {
current = (DirectoryEntry*) (((uint8_t*) current) + current->size()); current = (DirectoryEntry*) (((uint8_t*) current) + current->size());
if (current >= end) { } else {
current = nullptr; current = nullptr;
break;
} }
} }
if (current) { if (current) {
+27 -6
View File
@@ -6,6 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#include <iostream>
#include <assert.h> #include <assert.h>
#include <map> #include <map>
#include <string> #include <string>
@@ -133,21 +134,41 @@ map<string, int(*)(string)> tests = {
[](string) { [](string) {
// this value will likely need to change if anything about the // this value will likely need to change if anything about the
// random number generator changes // random number generator changes
const auto targetInode = 58542; //const auto targetInode = ox_rand();
int retval = 0; int retval = 0;
auto path = "/charset.gbag"; auto path = "/usr/share/test.txt";
auto data = "test"; auto data = "test";
const auto size = 1024; const auto size = 1024 * 1024 * 10;
uint8_t buff[size]; auto buff = new uint8_t[size];
FileSystem32::format(buff, (FileStore32::FsSize_t) size, true); FileSystem32::format(buff, (FileStore32::FsSize_t) size, true);
auto fs = (FileSystem32*) createFileSystem(buff, size); auto fs = (FileSystem32*) createFileSystem(buff, size);
retval |= fs->write(path, &data, ox_strlen(data)); fs->mkdir("/usr");
retval |= !(fs->findInodeOf(path) == targetInode); fs->mkdir("/usr/share");
fs->mkdir("/usr/lib");
cout << fs->mkdir("/usr/src") << endl;
retval |= fs->write(path, &data, ox_strlen(data) + 1);
auto inode = fs->findInodeOf("/");
cout << "/ inode: " << inode << endl;
inode = fs->findInodeOf("/usr");
cout << "/usr inode: " << inode << endl;
inode = fs->findInodeOf("/usr/share");
cout << "/usr/share inode: " << inode << endl;
inode = fs->findInodeOf(path);
cout << path << " inode: " << inode << endl;
//retval |= !(fs->findInodeOf(path) == targetInode);
delete fs; delete fs;
delete []buff;
return retval; return retval;
} }
}, },