Add a bounded read option for the file system

This commit is contained in:
2017-04-13 20:16:42 -05:00
parent 9183815634
commit bf110e5341
3 changed files with 85 additions and 20 deletions
+53 -10
View File
@@ -103,7 +103,7 @@ class FileStore {
struct StatInfo { struct StatInfo {
InodeId_t inodeId; InodeId_t inodeId;
typename Header::FsSize_t size; typename Header::FsSize_t size;
uint8_t fileType; uint8_t fileType;
}; };
@@ -143,7 +143,7 @@ class FileStore {
typename Header::FsSize_t getRight(); typename Header::FsSize_t getRight();
void setData(void *data, typename Header::FsSize_t size); void setData(void *data, typename Header::FsSize_t size);
void *getData(); uint8_t *getData();
}; };
Header m_header; Header m_header;
@@ -186,6 +186,20 @@ class FileStore {
*/ */
int read(InodeId_t id, void *data, typename Header::FsSize_t *size); int read(InodeId_t id, void *data, typename Header::FsSize_t *size);
/**
* Reads the "file" at the given id. You are responsible for freeing
* the data when done with it.
* @param id id of the "file"
* @param readStart where in the data to start reading
* @param readSize how much data to read
* @param data pointer to the pointer where the data is stored
* @param size pointer to a value that will be assigned the size of data
* @return 0 if read is a success
*/
int read(InodeId_t id, typename Header::FsSize_t readStart,
typename Header::FsSize_t readSize, void *data,
typename Header::FsSize_t *size);
/** /**
* Reads the stat information of the inode of the given inode id. * Reads the stat information of the inode of the given inode id.
* If the returned inode id is 0, then the requested inode was not found. * If the returned inode id is 0, then the requested inode was not found.
@@ -240,6 +254,20 @@ class FileStore {
*/ */
Inode *getInodeParent(Inode *root, InodeId_t id, typename Header::FsSize_t targetAddr); Inode *getInodeParent(Inode *root, InodeId_t id, typename Header::FsSize_t targetAddr);
/**
* Reads the "file" at the given id. You are responsible for freeing
* the data when done with it.
* @param inode inode of the "file"
* @param readStart where in the data to start reading
* @param readSize how much data to read
* @param data pointer to the pointer where the data is stored
* @param size pointer to a value that will be assigned the size of data
* @return 0 if read is a success
*/
int read(Inode *inode, typename Header::FsSize_t readStart,
typename Header::FsSize_t readSize, void *data,
typename Header::FsSize_t *size);
/** /**
* Removes the inode of the given ID. * Removes the inode of the given ID.
* @param id the id of the file * @param id the id of the file
@@ -391,8 +419,8 @@ void FileStore<Header>::Inode::setData(void *data, typename Header::FsSize_t siz
template<typename Header> template<typename Header>
void *FileStore<Header>::Inode::getData() { uint8_t *FileStore<Header>::Inode::getData() {
return this + 1; return (uint8_t*) (this + 1);
} }
@@ -538,14 +566,29 @@ void FileStore<Header>::updateInodeAddress(InodeId_t id, typename Header::FsSize
template<typename Header> template<typename Header>
int FileStore<Header>::read(InodeId_t id, void *data, typename Header::FsSize_t *size) { int FileStore<Header>::read(InodeId_t id, void *data, typename Header::FsSize_t *size) {
auto inode = getInode(ptr<Inode*>(m_header.getRootInode()), id); auto inode = getInode(ptr<Inode*>(m_header.getRootInode()), id);
return inode ? read(inode, 0, inode->getDataLen(), data, size) : 1;
}
template<typename Header>
int FileStore<Header>::read(InodeId_t id, typename Header::FsSize_t readStart,
typename Header::FsSize_t readSize, void *data, typename Header::FsSize_t *size) {
auto inode = getInode(ptr<Inode*>(m_header.getRootInode()), id);
return inode ? read(inode, readStart, readSize, data, size) : 1;
}
template<typename Header>
int FileStore<Header>::read(Inode *inode, typename Header::FsSize_t readStart,
typename Header::FsSize_t readSize, void *data, typename Header::FsSize_t *size) {
int retval = 1; int retval = 1;
if (inode) { // be sure read size is not greater than what is available to read
if (size) { if (inode->getDataLen() + readStart < readSize) {
*size = inode->getDataLen(); readSize = inode->getDataLen();
}
ox_memcpy(data, inode->getData(), inode->getDataLen());
retval = 0;
} }
if (size) {
*size = readSize;
}
ox_memcpy(data, inode->getData() + readStart, inode->getDataLen());
retval = 0;
return retval; return retval;
} }
+30 -9
View File
@@ -34,7 +34,9 @@ class FileSystem {
public: public:
virtual ~FileSystem() {}; virtual ~FileSystem() {};
virtual int read(uint64_t inode, void *buffer, size_t size) = 0; virtual int read(uint64_t inode, void *buffer, size_t *size) = 0;
virtual int read(uint64_t inode, size_t readStart, size_t readSize, void *buffer, size_t *size) = 0;
virtual uint8_t *read(uint64_t inode, size_t *size) = 0; virtual uint8_t *read(uint64_t inode, size_t *size) = 0;
@@ -110,9 +112,11 @@ class FileSystemTemplate: public FileSystem {
int read(const char *path, void *buffer); int read(const char *path, void *buffer);
uint8_t *read(uint64_t inode, size_t *size) override; int read(uint64_t inode, void *buffer, size_t *size) override;
int read(uint64_t inode, void *buffer, size_t size) override; int read(uint64_t inode, size_t readStart, size_t readSize, void *buffer, size_t *size);
uint8_t *read(uint64_t inode, size_t *size) override;
void resize(uint64_t size = 0) override; void resize(uint64_t size = 0) override;
@@ -174,18 +178,35 @@ FileStat FileSystemTemplate<FileStore, FS_TYPE>::stat(uint64_t inode) {
#pragma warning(disable:4244) #pragma warning(disable:4244)
#endif #endif
template<typename FileStore, FsType FS_TYPE> template<typename FileStore, FsType FS_TYPE>
int FileSystemTemplate<FileStore, FS_TYPE>::read(uint64_t inode, void *buffer, size_t size) { int FileSystemTemplate<FileStore, FS_TYPE>::read(uint64_t inode, void *buffer, size_t *size) {
auto err = 1; if (size) {
auto s = store->stat(inode); auto stat = store->stat(inode);
if (size == s.size) { *size = stat.size;
err = store->read(inode, buffer, nullptr);
} }
return err; return store->read(inode, buffer, nullptr);
;
} }
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(default:4244) #pragma warning(default:4244)
#endif #endif
#ifdef _MSC_VER
#pragma warning(disable:4244)
#endif
template<typename FileStore, FsType FS_TYPE>
int FileSystemTemplate<FileStore, FS_TYPE>::read(uint64_t inode, size_t readStart,
size_t readSize, void *buffer,
size_t *size) {
if (size) {
auto stat = store->stat(inode);
*size = stat.size;
}
return store->read(inode, readStart, readSize, buffer, nullptr);
}
#ifdef _MSC_VER
#pragma warning(disable:4244)
#endif
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(disable:4244) #pragma warning(disable:4244)
#endif #endif
+2 -1
View File
@@ -201,6 +201,7 @@ int write(int argc, char **args, bool expand) {
auto needed = fs->size() + fs->spaceNeeded(srcSize); auto needed = fs->size() + fs->spaceNeeded(srcSize);
fsSize = needed; fsSize = needed;
fs = expandCopyCleanup(fs, needed); fs = expandCopyCleanup(fs, needed);
fsBuff = fs->buff();
} }
err |= fs->write(inode, srcBuff, srcSize); err |= fs->write(inode, srcBuff, srcSize);
@@ -231,7 +232,7 @@ int write(int argc, char **args, bool expand) {
err = 1; err = 1;
} }
} }
delete []fsBuff; delete []srcBuff;
} else { } else {
err = 1; err = 1;
fprintf(stderr, "Could not load source file: %s.\n", srcPath); fprintf(stderr, "Could not load source file: %s.\n", srcPath);