From 89e80dcc10429c78c707fb6ae9c74984ac154fa4 Mon Sep 17 00:00:00 2001 From: ksherlock Date: Sat, 26 Feb 2011 02:11:46 +0000 Subject: [PATCH] use smart pointer for everything (not yet tested) git-svn-id: https://profuse.googlecode.com/svn/branches/v2@350 aa027e90-d47c-11dd-86d7-074df07e0730 --- Pascal/Entry.cpp | 1 - Pascal/Entry.h | 15 ++- Pascal/FileEntry.cpp | 105 ++++++++++++----- Pascal/FileEntry.h | 15 ++- Pascal/VolumeEntry.cpp | 251 +++++++++++++++++++++------------------- Pascal/VolumeEntry.h | 33 ++++-- bin/apfm.cpp | 18 +-- bin/fuse_pascal.cpp | 5 +- bin/fuse_pascal_ops.cpp | 53 ++++++--- bin/newfs_pascal.cpp | 6 +- 10 files changed, 305 insertions(+), 197 deletions(-) diff --git a/Pascal/Entry.cpp b/Pascal/Entry.cpp index e7bd872..6cb406e 100644 --- a/Pascal/Entry.cpp +++ b/Pascal/Entry.cpp @@ -64,7 +64,6 @@ Entry::Entry() _lastBlock = 0; _fileKind = 0; _inode = 0; - _parent = NULL; _address = NULL; } diff --git a/Pascal/Entry.h b/Pascal/Entry.h index c4438d9..c122951 100644 --- a/Pascal/Entry.h +++ b/Pascal/Entry.h @@ -1,6 +1,8 @@ #ifndef __PASCAL_ENTRY_H__ #define __PASCAL_ENTRY_H__ +#include + #include @@ -31,7 +33,14 @@ namespace Pascal { class FileEntry; class VolumeEntry; - class Entry { + + typedef std::tr1::shared_ptr FileEntryPointer; + typedef std::tr1::shared_ptr VolumeEntryPointer; + + typedef std::tr1::weak_ptr FileEntryWeakPointer; + typedef std::tr1::weak_ptr VolumeEntryWeakPointer; + + class Entry : public std::tr1::enable_shared_from_this { public: @@ -47,7 +56,7 @@ namespace Pascal { unsigned inode() const { return _inode; } void setInode(unsigned inode) { _inode = inode; } - VolumeEntry *parent() { return _parent; } + VolumeEntryWeakPointer parent() { return _parent; } protected: @@ -70,7 +79,7 @@ namespace Pascal { friend class VolumeEntry; - VolumeEntry *_parent; + VolumeEntryWeakPointer _parent; unsigned _address; }; diff --git a/Pascal/FileEntry.cpp b/Pascal/FileEntry.cpp index 351214a..f4a1c18 100644 --- a/Pascal/FileEntry.cpp +++ b/Pascal/FileEntry.cpp @@ -42,6 +42,16 @@ unsigned FileEntry::ValidName(const char *cp) return Entry::ValidName(cp, 15); } +FileEntryPointer FileEntry::Open(void *vp) +{ + return FileEntryPointer(new FileEntry(vp)); +} + +FileEntryPointer FileEntry::Create(const char *name, unsigned fileKind) +{ + return FileEntryPointer(new FileEntry(name, fileKind)); +} + FileEntry::FileEntry(void *vp) : Entry(vp) { @@ -99,7 +109,10 @@ void FileEntry::setFileKind(unsigned kind) _pageSize = NULL; } - parent()->writeEntry(this); + VolumeEntryPointer v = parent().lock(); + + // throw if expired? + if (v) v->writeEntry(this); } @@ -194,7 +207,9 @@ int FileEntry::truncate(unsigned newSize) return -1; _modification = Date::Today(); - parent()->writeEntry(this); + + VolumeEntryPointer v = parent().lock(); + if (v) v->writeEntry(this); return 0; } @@ -211,6 +226,8 @@ int FileEntry::truncateCommon(unsigned newSize) unsigned currentSize = fileSize(); + VolumeEntryPointer v = parent().lock(); + if (newSize == currentSize) return 0; if (newSize > currentSize) { @@ -228,12 +245,13 @@ int FileEntry::truncateCommon(unsigned newSize) { // last page not full unsigned count = std::min(512 - _lastByte, remainder); - uint8_t *address = (uint8_t *)parent()->loadBlock(block); - - std::memset(address + _lastByte, 0, count); - - parent()->unloadBlock(block, true); + if (v) + { + uint8_t *address = (uint8_t *)v->loadBlock(block); + std::memset(address + _lastByte, 0, count); + v->unloadBlock(block, true); + } remainder -= count; } block++; @@ -241,12 +259,12 @@ int FileEntry::truncateCommon(unsigned newSize) while (remainder) { unsigned count = std::min(512u, remainder); - uint8_t *address = (uint8_t *)parent()->loadBlock(block); - - std::memset(address, 0, count); - - parent()->unloadBlock(block, true); - + if (v) + { + uint8_t *address = (uint8_t *)v->loadBlock(block); + std::memset(address, 0, count); + v->unloadBlock(block, true); + } remainder -= count; block++; } @@ -264,7 +282,15 @@ int FileEntry::write(TextWriter &text) { unsigned blocks = text.blocks(); - if (parent()->readOnly()) + VolumeEntryPointer v = parent().lock(); + if (!v) + { + errno = EROFS; + return -1; + } + + + if (v->readOnly()) { errno = EROFS; return -1; @@ -286,7 +312,7 @@ int FileEntry::write(TextWriter &text) for (unsigned i = 0; i < blocks; ++i) { void *buffer = text.data(i); - parent()->writeBlock(_firstBlock + i, buffer); + v->writeBlock(_firstBlock + i, buffer); } @@ -294,8 +320,8 @@ int FileEntry::write(TextWriter &text) setFileSize(blocks * 512); - parent()->writeEntry(this); - parent()->sync(); + v->writeEntry(this); + v->sync(); return blocks * 512; } @@ -304,8 +330,15 @@ int FileEntry::write(const uint8_t *buffer, unsigned size, unsigned offset) { #undef __METHOD__ #define __METHOD__ "FileEntry::write" - - if (parent()->readOnly()) + + VolumeEntryPointer v = parent().lock(); + if (!v) + { + errno = EROFS; + return -1; + } + + if (v->readOnly()) { errno = EROFS; return -1; @@ -342,10 +375,10 @@ int FileEntry::write(const uint8_t *buffer, unsigned size, unsigned offset) if (start) { unsigned count = std::min(512 - start, remainder); - uint8_t *address = (uint8_t *)parent()->loadBlock(block); + uint8_t *address = (uint8_t *)v->loadBlock(block); std::memcpy(address + start, buffer, count); - parent()->unloadBlock(block, true); + v->unloadBlock(block, true); remainder -= count; buffer += count; @@ -354,12 +387,12 @@ int FileEntry::write(const uint8_t *buffer, unsigned size, unsigned offset) while (remainder) { - uint8_t *address = (uint8_t *)parent()->loadBlock(block); + uint8_t *address = (uint8_t *)v->loadBlock(block); unsigned count = std::min(512u, size); std::memcpy(address, buffer, count); - parent()->unloadBlock(block, true); + v->unloadBlock(block, true); remainder -= count; buffer += count; @@ -371,7 +404,7 @@ int FileEntry::write(const uint8_t *buffer, unsigned size, unsigned offset) _modification = Date::Today(); - parent()->writeEntry(this); + v->writeEntry(this); return size; } @@ -419,6 +452,13 @@ int FileEntry::dataRead(uint8_t *buffer, unsigned size, unsigned offset) unsigned count = 0; unsigned block = 0; + + VolumeEntryPointer v = parent().lock(); + if (!v) + { + errno = EROFS; + return 0; + } block = _firstBlock + (offset / 512); @@ -433,7 +473,7 @@ int FileEntry::dataRead(uint8_t *buffer, unsigned size, unsigned offset) { unsigned bytes = std::min(offset % 512, size); - parent()->readBlock(block++, tmp); + v->readBlock(block++, tmp); std::memcpy(buffer, tmp + 512 - bytes, bytes); @@ -448,7 +488,7 @@ int FileEntry::dataRead(uint8_t *buffer, unsigned size, unsigned offset) while (size >= 512) { - parent()->readBlock(block++, buffer); + v->readBlock(block++, buffer); buffer += 512; count += 512; @@ -460,7 +500,7 @@ int FileEntry::dataRead(uint8_t *buffer, unsigned size, unsigned offset) */ if (size) { - parent()->readBlock(block, tmp); + v->readBlock(block, tmp); std::memcpy(buffer, tmp, size); count += size; @@ -589,13 +629,20 @@ unsigned FileEntry::textReadPage(unsigned block, uint8_t *in) // reads up to 2 blocks. // assumes block within _startBlock ... _lastBlock - 1 - parent()->readBlock(block, in); + VolumeEntryPointer v = parent().lock(); + if (!v) + { + errno = EROFS; + return 0; + } + + v->readBlock(block, in); if (block + 1 == _lastBlock) { return _lastByte; } - parent()->readBlock(block + 1, in + 512); + v->readBlock(block + 1, in + 512); if (block +2 == _lastBlock) { return 512 + _lastByte; diff --git a/Pascal/FileEntry.h b/Pascal/FileEntry.h index 721e80e..7bec9ac 100644 --- a/Pascal/FileEntry.h +++ b/Pascal/FileEntry.h @@ -22,8 +22,10 @@ namespace Pascal { static bool Uncompress(std::string& text); - FileEntry(const char *name, unsigned fileKind); - FileEntry(void *vp); + static FileEntryPointer Create(const char *name, unsigned fileKind); + static FileEntryPointer Open(void *vp); + + virtual ~FileEntry(); @@ -54,6 +56,15 @@ namespace Pascal { friend class VolumeEntry; + FileEntry(const char *name, unsigned fileKind); + FileEntry(void *vp); + + FileEntryPointer thisPointer() + { + return std::tr1::static_pointer_cast(shared_from_this()); + } + + void setName(const char *name); int truncateCommon(unsigned newSize); diff --git a/Pascal/VolumeEntry.cpp b/Pascal/VolumeEntry.cpp index 03e2f52..a4eff36 100644 --- a/Pascal/VolumeEntry.cpp +++ b/Pascal/VolumeEntry.cpp @@ -61,6 +61,26 @@ unsigned VolumeEntry::ValidName(const char *cp) return Entry::ValidName(cp, 7); } + +VolumeEntryPointer VolumeEntry::Open(Device::BlockDevicePointer device) +{ + VolumeEntryPointer ptr(new VolumeEntry(device)); + + return ptr; +} + +VolumeEntryPointer VolumeEntry::Create(Device::BlockDevicePointer device, const char *name) +{ + VolumeEntryPointer ptr(new VolumeEntry(device, name)); + + + // set up the weak references from the file entry to this. + if (ptr) ptr->setParents(); + + return ptr; +} + + VolumeEntry::VolumeEntry() { _fileNameLength = 0; @@ -74,7 +94,7 @@ VolumeEntry::VolumeEntry() _inodeGenerator = 1; } -VolumeEntry::VolumeEntry(const char *name, Device::BlockDevicePointer device) : +VolumeEntry::VolumeEntry(Device::BlockDevicePointer device, const char *name) : _device(device) { #undef __METHOD__ @@ -166,88 +186,79 @@ VolumeEntry::VolumeEntry(Device::BlockDevicePointer device) } // now load up all the children. - // if this throws, memory could be lost... - + // the parent cannot be set (yet), since we need a shared_ptr to create a weak_ptr. - try - { - - std::vector::iterator iter; - unsigned block; - - for (unsigned i = 1; i <= _fileCount; ++i) - { - std::auto_ptr child; - - // - child.reset(new FileEntry(buffer.get() + i * 0x1a)); - - child->setInode(++_inodeGenerator); - child->_parent = this; - child->_address = 512 * 2 + i * 0x1a; - - _files.push_back(child.release()); - } - - // sanity check _firstBlock, _lastBlock? - - block = _lastBlock; - - for (iter = _files.begin(); iter != _files.end(); ++iter) - { - FileEntry *e = *iter; - bool error = false; - if (e->_firstBlock > e->_lastBlock) - error = true; + std::vector::iterator iter; - if (e->_firstBlock >= _lastVolumeBlock) - error = true; - - if (e->_lastBlock > _lastVolumeBlock) - error = true; - - if (e->_firstBlock < block) - error = true; - - if (error) - throw ProDOSException(__METHOD__ ": Invalid file entry.", ProFUSE::dirError); - - block = e->_lastBlock; - - } - - - calcMaxFileSize(); - - } - catch (...) + unsigned block; + + for (unsigned i = 1; i <= _fileCount; ++i) { - std::vector::iterator iter; - - for(iter = _files.begin(); iter != _files.end(); ++iter) - { - if (*iter) delete *iter; - } - - throw; + FileEntryPointer child; + + // + child = FileEntry::Open(buffer.get() + i * 0x1a); + + child->setInode(++_inodeGenerator); + // need to set later.... + //child->_parent = this; + child->_address = 512 * 2 + i * 0x1a; + + _files.push_back(child); } + // sanity check _firstBlock, _lastBlock? + + block = _lastBlock; + + for (iter = _files.begin(); iter != _files.end(); ++iter) + { + FileEntryPointer e = *iter; + bool error = false; + if (e->_firstBlock > e->_lastBlock) + error = true; + if (e->_firstBlock >= _lastVolumeBlock) + error = true; + + if (e->_lastBlock > _lastVolumeBlock) + error = true; + + if (e->_firstBlock < block) + error = true; + + if (error) + throw ProDOSException(__METHOD__ ": Invalid file entry.", ProFUSE::dirError); + + block = e->_lastBlock; + + } + + + calcMaxFileSize(); } VolumeEntry::~VolumeEntry() { - - std::vector::iterator iter; - for(iter = _files.begin(); iter != _files.end(); ++iter) - { - if (*iter) delete *iter; - } - } +void VolumeEntry::setParents() +{ + // parent is this.... + + VolumeEntryWeakPointer parent(thisPointer()); + std::vector::iterator iter; + + for (iter = _files.begin(); iter != _files.end(); ++iter) + { + FileEntryPointer e = *iter; + + e->_parent = parent; + } +} + void VolumeEntry::init(void *vp) { #undef __METHOD__ @@ -278,20 +289,20 @@ void VolumeEntry::init(void *vp) } -FileEntry *VolumeEntry::fileAtIndex(unsigned i) const +FileEntryPointer VolumeEntry::fileAtIndex(unsigned i) const { - return i < _files.size() ? _files[i] : NULL; + return i < _files.size() ? _files[i] : FileEntryPointer(); } -FileEntry *VolumeEntry::fileByName(const char *name) const +FileEntryPointer VolumeEntry::fileByName(const char *name) const { - std::vector::const_iterator iter; + std::vector::const_iterator iter; for(iter = _files.begin(); iter != _files.end(); ++iter) { - FileEntry *e = *iter; + FileEntryPointer e = *iter; if (::strcasecmp(name, e->name()) == 0) return e; } - return NULL; + return FileEntryPointer(); } /* @@ -303,7 +314,7 @@ int VolumeEntry::unlink(const char *name) { unsigned index; - std::vector::iterator iter; + std::vector::iterator iter; if (_device->readOnly()) { @@ -315,7 +326,7 @@ int VolumeEntry::unlink(const char *name) for (iter = _files.begin(); iter != _files.end(); ++iter) { - FileEntry *e = *iter; + FileEntryPointer e = *iter; if (::strcasecmp(name, e->name()) == 0) { @@ -323,12 +334,11 @@ int VolumeEntry::unlink(const char *name) // _maxFileSize. if (iter != _files.begin()) { - FileEntry *prev = iter[-1]; + FileEntryPointer prev = iter[-1]; prev->_maxFileSize += e->_maxFileSize; } - delete e; - *iter = NULL; + iter->reset(); break; } } @@ -347,7 +357,7 @@ int VolumeEntry::unlink(const char *name) // reset addresses. for ( ; iter != _files.end(); ++iter) { - FileEntry *e = *iter; + FileEntryPointer e = *iter; e->_address -= 0x1a; } @@ -380,7 +390,7 @@ int VolumeEntry::unlink(const char *name) */ int VolumeEntry::rename(const char *oldName, const char *newName) { - FileEntry *e; + FileEntryPointer e; // check if read only. @@ -417,7 +427,7 @@ int VolumeEntry::rename(const char *oldName, const char *newName) // and commit to disk. - writeEntry(e); + writeEntry(e.get()); _cache->sync(); return 0; @@ -431,8 +441,8 @@ int VolumeEntry::rename(const char *oldName, const char *newName) */ int VolumeEntry::copy(const char *oldName, const char *newName) { - FileEntry *oldEntry; - FileEntry *newEntry; + FileEntryPointer oldEntry; + FileEntryPointer newEntry; // check if read only. if (_device->readOnly()) { @@ -482,14 +492,14 @@ int VolumeEntry::copy(const char *oldName, const char *newName) return -1; } - newEntry = NULL; + newEntry.reset(); if (unlink(newName) != 0) return -1; } } - if (newEntry == NULL) + if (!newEntry) { // newName does not exist (or was just deleted), so create a new file (if possible) and write to it. if (maxContiguousBlocks() < blocks) @@ -534,7 +544,7 @@ int VolumeEntry::copy(const char *oldName, const char *newName) * * */ -FileEntry *VolumeEntry::create(const char *name, unsigned blocks) +FileEntryPointer VolumeEntry::create(const char *name, unsigned blocks) { // 0. check read only access. // 1. verify < 77 file names. @@ -547,46 +557,45 @@ FileEntry *VolumeEntry::create(const char *name, unsigned blocks) unsigned lastBlock = _lastBlock; - std::auto_ptrentry; - FileEntry *prev = NULL; - FileEntry *curr = NULL; - std::vector::iterator iter; + FileEntryPointer entry; + FileEntryPointer prev; + FileEntryPointer curr; + std::vector::iterator iter; if (readOnly()) { errno = EROFS; - return NULL; + return FileEntryPointer(); } if (_fileCount == kMaxFiles) { errno = ENOSPC; - return NULL; + return FileEntryPointer(); } if (!FileEntry::ValidName(name)) { errno = EINVAL; - return NULL; + return FileEntryPointer(); } if (fileByName(name)) { errno = EEXIST; - return NULL; + return FileEntryPointer(); } - entry.reset(new FileEntry(name, kUntypedFile)); + entry = FileEntry::Create(name, kUntypedFile); - - std::auto_ptr buffer(readDirectoryHeader()); + ProFUSE::auto_array buffer(readDirectoryHeader()); for (iter = _files.begin(); iter != _files.end(); ++iter) { - FileEntry *e = *iter; + FileEntryPointer e = *iter; unsigned freeSpace = e->_firstBlock - _lastBlock; // this could do something stupid like selecting a slot with only 1 free block but too bad. @@ -611,12 +620,13 @@ FileEntry *VolumeEntry::create(const char *name, unsigned blocks) // keep track of the index *before* the insert. unsigned index = distance(_files.begin(), iter); // current index. - iter = _files.insert(iter, entry.get()); + iter = _files.insert(iter, entry); ++_fileCount; - curr = entry.release(); + curr = entry; - curr->_parent = this; + //curr->_parent = this; + curr->_parent = VolumeEntryWeakPointer(thisPointer()); curr->_firstBlock = lastBlock; curr->_lastBlock = lastBlock + 1; curr->_lastByte = 0; @@ -638,15 +648,16 @@ FileEntry *VolumeEntry::create(const char *name, unsigned blocks) if (freeSpace < blocks) { errno = ENOSPC; - return NULL; + return FileEntryPointer(); } - _files.push_back(entry.get()); + _files.push_back(entry); _fileCount++; - curr = entry.release(); + curr = entry; - curr->_parent = this; + //curr->_parent = this; + curr->_parent = VolumeEntryWeakPointer(thisPointer()); curr->_firstBlock = lastBlock; curr->_lastBlock = lastBlock + 1; curr->_lastByte = 0; @@ -658,7 +669,7 @@ FileEntry *VolumeEntry::create(const char *name, unsigned blocks) prev->_maxFileSize = prev->blocks() * 512; } - writeEntry(curr); + writeEntry(curr.get()); writeEntry(); // header. } @@ -670,7 +681,7 @@ FileEntry *VolumeEntry::create(const char *name, unsigned blocks) unsigned address = 2 * 512 + 0x1a; for (iter = _files.begin(); iter != _files.end(); ++iter, address += 0x1a) { - FileEntry *e = *iter; + FileEntryPointer e = *iter; e->_address = address; } @@ -706,7 +717,7 @@ int VolumeEntry::krunch() { unsigned prevBlock; - std::vector::const_iterator iter; + std::vector::const_iterator iter; bool gap = false; @@ -716,7 +727,7 @@ int VolumeEntry::krunch() for (iter = _files.begin(); iter != _files.end(); ++iter) { - FileEntry *e = *iter; + FileEntryPointer e = *iter; unsigned first = e->firstBlock(); unsigned last = e->lastBlock(); @@ -751,7 +762,7 @@ int VolumeEntry::krunch() unsigned offset = 0; for (iter = _files.begin(); iter != _files.end(); ++iter, ++offset) { - FileEntry *e = *iter; + FileEntryPointer e = *iter; b.setOffset(0x1a + 0x1a * offset); @@ -812,13 +823,13 @@ unsigned VolumeEntry::freeBlocks(bool krunched) const if (krunched) { - std::vector::const_iterator iter; + std::vector::const_iterator iter; lastBlock = _lastBlock; for (iter = _files.begin(); iter != _files.end(); ++iter) { - const FileEntry *e = *iter; + const FileEntryPointer e = *iter; freeBlocks += e->_firstBlock - lastBlock; lastBlock = e->_lastBlock; } @@ -842,13 +853,13 @@ unsigned VolumeEntry::freeBlocks(bool krunched) const bool VolumeEntry::canKrunch() const { - std::vector::const_iterator iter; + std::vector::const_iterator iter; unsigned lastBlock = _lastBlock; for (iter = _files.begin(); iter != _files.end(); ++iter) { - const FileEntry *e = *iter; + const FileEntryPointer e = *iter; if (e->_lastBlock != lastBlock) return true; lastBlock = e->_lastBlock; } @@ -864,13 +875,13 @@ unsigned VolumeEntry::maxContiguousBlocks() const { unsigned max = 0; - std::vector::const_iterator iter; + std::vector::const_iterator iter; unsigned lastBlock = _lastBlock; for (iter = _files.begin(); iter != _files.end(); ++iter) { - const FileEntry *e = *iter; + const FileEntryPointer e = *iter; unsigned free = e->_firstBlock - lastBlock; max = std::max(max, free); @@ -999,11 +1010,11 @@ void VolumeEntry::writeEntry(FileEntry *e) // set _maxFileSize for all entries. void VolumeEntry::calcMaxFileSize() { - std::vector::reverse_iterator riter; + std::vector::reverse_iterator riter; unsigned block = _lastVolumeBlock; for (riter = _files.rbegin(); riter != _files.rend(); ++riter) { - FileEntry *e = *riter; + FileEntryPointer e = *riter; e->_maxFileSize = (block - e->_firstBlock) * 512; block = e->_firstBlock; } diff --git a/Pascal/VolumeEntry.h b/Pascal/VolumeEntry.h index 2dcc0ea..4b3f8a4 100644 --- a/Pascal/VolumeEntry.h +++ b/Pascal/VolumeEntry.h @@ -9,20 +9,18 @@ namespace Pascal { - class FileEntry; class VolumeEntry : public Entry { public: - + static unsigned ValidName(const char *); + + static VolumeEntryPointer Open(Device::BlockDevicePointer); + static VolumeEntryPointer Create(Device::BlockDevicePointer, const char *name); + // - // create new - VolumeEntry(const char *name, Device::BlockDevicePointer); - - // open existing - VolumeEntry(Device::BlockDevicePointer); virtual ~VolumeEntry(); const char *name() const { return _fileName; } @@ -36,8 +34,8 @@ namespace Pascal { bool canKrunch() const; - FileEntry *fileAtIndex(unsigned i) const; - FileEntry *fileByName(const char *name) const; + FileEntryPointer fileAtIndex(unsigned i) const; + FileEntryPointer fileByName(const char *name) const; void *loadBlock(unsigned block); @@ -53,7 +51,7 @@ namespace Pascal { int unlink(const char *name); int rename(const char *oldName, const char *newName); int copy(const char *oldName, const char *newName); - FileEntry *create(const char *name, unsigned blocks); + FileEntryPointer create(const char *name, unsigned blocks); int krunch(); @@ -65,10 +63,21 @@ namespace Pascal { private: friend class FileEntry; + VolumeEntry(); - + VolumeEntry(Device::BlockDevicePointer, const char *name); + VolumeEntry(Device::BlockDevicePointer); + + VolumeEntryPointer thisPointer() + { + return std::tr1::static_pointer_cast(shared_from_this()); + } + void init(void *); + void setParents(); + + uint8_t *readDirectoryHeader(); @@ -90,7 +99,7 @@ namespace Pascal { unsigned _accessTime; Pascal::Date _lastBoot; - std::vector _files; + std::vector _files; unsigned _inodeGenerator; Device::BlockDevicePointer _device; diff --git a/bin/apfm.cpp b/bin/apfm.cpp index cd65dae..c81885f 100644 --- a/bin/apfm.cpp +++ b/bin/apfm.cpp @@ -263,7 +263,7 @@ void printUnusedEntry(unsigned block, unsigned size) std::printf("< UNUSED > %4u %4u\n", size, block); } -void printFileEntry(Pascal::FileEntry *e, bool extended) +void printFileEntry(Pascal::FileEntryPointer e, bool extended) { Pascal::Date dt = e->modification(); @@ -329,7 +329,7 @@ int action_ls(int argc, char **argv, Pascal::VolumeEntry *volume) for (unsigned i = 0; i < fileCount; ++i) { - Pascal::FileEntry *e = volume->fileAtIndex(i); + Pascal::FileEntryPointer e = volume->fileAtIndex(i); if (!e) continue; @@ -409,7 +409,7 @@ int action_cat(unsigned argc, char **argv, Pascal::VolumeEntry *volume) unsigned fileSize; unsigned offset; uint8_t buffer[512]; - Pascal::FileEntry *e = NULL; + Pascal::FileEntryPointer e; // find it... e = volume->fileByName(argv[i]); @@ -588,7 +588,7 @@ int action_rm(int argc, char **argv, Pascal::VolumeEntry *volume) // TODO -- catch errors ? for (int i = 0; i < argc; ++i) { - Pascal::FileEntry *e = volume->fileByName(argv[i]); + Pascal::FileEntryPointer e = volume->fileByName(argv[i]); if (!e) { @@ -691,7 +691,7 @@ int action_get(int argc, char **argv, Pascal::VolumeEntry *volume) argc -= optind; argv += optind; - Pascal::FileEntry *entry; + Pascal::FileEntryPointer entry; switch(argc) { @@ -910,7 +910,7 @@ int action_put(int argc, char **argv, Pascal::VolumeEntry *volume) blocks = text.blocks(); - Pascal::FileEntry *entry = volume->create(outfile, blocks); + Pascal::FileEntryPointer entry = volume->create(outfile, blocks); if (!entry) { perror(NULL); @@ -923,7 +923,7 @@ int action_put(int argc, char **argv, Pascal::VolumeEntry *volume) } else { - Pascal::FileEntry *entry = volume->create(outfile, blocks); + Pascal::FileEntryPointer entry = volume->create(outfile, blocks); if (!entry) { perror(NULL); @@ -962,7 +962,7 @@ int action_put(int argc, char **argv, Pascal::VolumeEntry *volume) int main(int argc, char **argv) { - std::auto_ptr volume; + Pascal::VolumeEntryPointer volume; Device::BlockDevicePointer device; unsigned fmt = 0; @@ -1027,7 +1027,7 @@ int main(int argc, char **argv) device = Device::BlockDevice::Open(file, commandFlags(actionCode), fmt); - volume.reset( new Pascal::VolumeEntry(device)); + volume = Pascal::VolumeEntry::Open(device); device.reset(); switch (actionCode) diff --git a/bin/fuse_pascal.cpp b/bin/fuse_pascal.cpp index 17f230c..e19edf8 100644 --- a/bin/fuse_pascal.cpp +++ b/bin/fuse_pascal.cpp @@ -169,7 +169,7 @@ int main(int argc, char **argv) int multithread = false; - std::auto_ptr volume; + Pascal::VolumeEntryPointer volume; init_ops(&pascal_ops); @@ -210,8 +210,7 @@ int main(int argc, char **argv) exit(1); } - volume.reset( new Pascal::VolumeEntry(device) ); - device.reset(); + volume = Pascal::VolumeEntry::Open(device); } catch (ProFUSE::POSIXException &e) { diff --git a/bin/fuse_pascal_ops.cpp b/bin/fuse_pascal_ops.cpp index a111191..fe966b0 100644 --- a/bin/fuse_pascal_ops.cpp +++ b/bin/fuse_pascal_ops.cpp @@ -56,18 +56,23 @@ using namespace Pascal; -static FileEntry *findChild(VolumeEntry *volume, unsigned inode) +// fd_table is files which have been open. +// fd_table_available is a list of indexes in fd_table which are not currently used. +static std::vector fd_table; +static std::vector fd_table_available; + +static FileEntryPointer findChild(VolumeEntry *volume, unsigned inode) { for (unsigned i = 0, l = volume->fileCount(); i < l; ++i) { - FileEntry *child = volume->fileAtIndex(i); + FileEntryPointer child = volume->fileAtIndex(i); if (!child) continue; if (inode == child->inode()) return child; } - return NULL; + return FileEntryPointer(); } static void pascal_init(void *userdata, struct fuse_conn_info *conn) @@ -82,7 +87,7 @@ static void pascal_init(void *userdata, struct fuse_conn_info *conn) for (unsigned i = 0, l = volume->fileCount(); i < l; ++i) { - FileEntry *child = volume->fileAtIndex(i); + FileEntryPointer child = volume->fileAtIndex(i); child->fileSize(); } @@ -105,7 +110,7 @@ static void pascal_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size) DEBUGNAME() VolumeEntry *volume = (VolumeEntry *)fuse_req_userdata(req); - FileEntry *file; + FileEntryPointer file; std::string attr; unsigned attrSize; @@ -149,7 +154,7 @@ static void pascal_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name, si VolumeEntry *volume = (VolumeEntry *)fuse_req_userdata(req); - FileEntry *file; + FileEntryPointer file; std::string attr(name); ERROR(ino == 1, ENOATTR) @@ -269,7 +274,7 @@ static void pascal_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t of { unsigned tmp; - FileEntry *file = volume->fileAtIndex(i); + FileEntryPointer file = volume->fileAtIndex(i); if (file == NULL) break; //? // only these fields are used. @@ -352,7 +357,7 @@ static void pascal_lookup(fuse_req_t req, fuse_ino_t parent, const char *name) for (unsigned i = 0, l = volume->fileCount(); i < l; ++i) { - FileEntry *file = volume->fileAtIndex(i); + FileEntryPointer file = volume->fileAtIndex(i); if (file == NULL) break; if (::strcasecmp(file->name(), name)) continue; @@ -363,7 +368,7 @@ static void pascal_lookup(fuse_req_t req, fuse_ino_t parent, const char *name) entry.entry_timeout = 0.0; entry.ino = file->inode(); - stat(file, &entry.attr); + stat(file.get(), &entry.attr); fuse_reply_entry(req, &entry); return; } @@ -378,7 +383,7 @@ static void pascal_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info struct stat st; VolumeEntry *volume = (VolumeEntry *)fuse_req_userdata(req); - FileEntry *file; + FileEntryPointer file; if (ino == 1) { @@ -392,7 +397,7 @@ static void pascal_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info ERROR(file == NULL, ENOENT) //printf("\t%s\n", file->name()); - stat(file, &st); + stat(file.get(), &st); fuse_reply_attr(req, &st, 0.0); } @@ -402,10 +407,11 @@ static void pascal_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info static void pascal_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { + unsigned index; DEBUGNAME() VolumeEntry *volume = (VolumeEntry *)fuse_req_userdata(req); - FileEntry *file; + FileEntryPointer file; ERROR(ino == 1, EISDIR) @@ -415,7 +421,20 @@ static void pascal_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *f ERROR((fi->flags & O_ACCMODE) != O_RDONLY, EACCES) - fi->fh = (uint64_t)file; + // insert the FileEntryPointer into fd_table. + if (fd_table_available.size()) + { + index = fd_table_available.back(); + fd_table_available.pop_back(); + fd_table[index] = file; + } + else + { + index = fd_table.size(); + fd_table.push_back(file); + } + + fi->fh = index; fuse_reply_open(req, fi); } @@ -423,19 +442,25 @@ static void pascal_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *f static void pascal_release(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { + unsigned index = fi->fh; DEBUGNAME() + fd_table[index].reset(); + fd_table_available.push_back(index); + fuse_reply_err(req, 0); } static void pascal_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi) { + unsigned index = fi->fh; + DEBUGNAME() //VolumeEntry *volume = (VolumeEntry *)fuse_req_userdata(req); - FileEntry *file = (FileEntry *)fi->fh; + FileEntryPointer file = fd_table[index]; diff --git a/bin/newfs_pascal.cpp b/bin/newfs_pascal.cpp index fe8b93a..7b1bbb0 100644 --- a/bin/newfs_pascal.cpp +++ b/bin/newfs_pascal.cpp @@ -215,7 +215,7 @@ int main(int argc, char **argv) bool rawDevice; BlockDevicePointer device; - std::auto_ptr volume; + VolumeEntryPointer volume; // Check for block device. if so, verify. // if file exists, verify before overwrite. @@ -298,9 +298,7 @@ int main(int argc, char **argv) } - volume.reset( - new VolumeEntry(volumeName.c_str(), device) - ); + volume = VolumeEntry::Create(device, volumeName.c_str()); }