krunch support

git-svn-id: https://profuse.googlecode.com/svn/branches/v2@253 aa027e90-d47c-11dd-86d7-074df07e0730
This commit is contained in:
ksherlock 2010-05-21 23:01:32 +00:00
parent 949ed1e16c
commit deec48b728
2 changed files with 141 additions and 12 deletions

View File

@ -112,7 +112,11 @@ public:
void writeBlock(unsigned block, void *);
void sync();
unsigned unlink(const char *name);
unsigned rename(const char *oldName, const char *newName);
unsigned krunch();
protected:
@ -140,6 +144,13 @@ private:
class FileEntry : public Entry {
public:
static unsigned ValidName(const char *);
static bool Compress(std::string& text);
static bool Uncompress(std::string& text);
FileEntry(const char *name, unsigned fileKind);
FileEntry(void *vp);
@ -154,18 +165,14 @@ class FileEntry : public Entry {
const char *name() const { return _fileName; }
Date modification() const { return _modification; }
static unsigned ValidName(const char *);
static bool Compress(std::string& text);
static bool Uncompress(std::string& text);
protected:
virtual void writeDirectoryEntry(LittleEndian::IOBuffer *);
private:
friend class VolumeEntry;
unsigned _status;

View File

@ -209,10 +209,13 @@ FileEntry *VolumeEntry::fileByName(const char *name) const
return NULL;
}
void VolumeEntry::unlink(const char *name)
unsigned VolumeEntry::unlink(const char *name)
{
unsigned index;
if (_device->readOnly()) return 0x2b; // WRITE-PROTECTED DISK
for(index = 0; index < _fileCount; ++index)
{
FileEntry *e = _files[index];
@ -223,14 +226,14 @@ void VolumeEntry::unlink(const char *name)
break;
}
}
if (index == _fileCount) return; // not found.
if (index == _fileCount) return 0x46; // FILE NOT FOUND
_files.erase(files.begin() + index);
_files.erase(_files.begin() + index);
_fileCount--;
// need to update the header blocks.
unsigned blockCount = blocks();
auto_array<uint8_t> buffer(new uint8_t[512 * blocks]);
ProFUSE::auto_array<uint8_t> buffer(new uint8_t[512 * blockCount]);
// load up blocks.
// since entries span blocks, we can't do this via pointer.
@ -239,8 +242,8 @@ void VolumeEntry::unlink(const char *name)
_cache->read(2 + i, buffer.get() + 512 * i);
}
// update the filecount.
IOBuffer b(buffer.get());
writeDirectoryEntry(b);
IOBuffer b(buffer.get(), 512 * blockCount);
writeDirectoryEntry(&b);
// move up all the entries.
uint8_t *address = buffer.get() + 0x1a + 0x1a * index;
@ -253,8 +256,127 @@ void VolumeEntry::unlink(const char *name)
{
_cache->write(2 + i, buffer.get() + 512 * i);
}
_cache->sync();
return 0;
}
unsigned VolumeEntry::krunch()
{
unsigned prevBlock;
std::vector<FileEntry *>::const_iterator iter;
bool gap = false;
// sanity check to make sure no weird overlap issues.
prevBlock = lastBlock();
for (iter = _files.begin(); iter != _files.end(); ++iter)
{
FileEntry *e = *iter;
unsigned first = e->firstBlock();
unsigned last = e->lastBlock();
if (first != prevBlock) gap = true;
if (first < prevBlock)
return ProFUSE::damagedBitMap;
if (last < first)
return ProFUSE::damagedBitMap;
if (first < volumeBlocks())
return ProFUSE::damagedBitMap;
prevBlock = last;
}
if (!gap) return 0;
// need to update the header blocks.
unsigned blockCount = blocks();
ProFUSE::auto_array<uint8_t> buffer(new uint8_t[512 * blockCount]);
IOBuffer b(buffer.get(), 512 * blockCount);
// load up the directory blocks.
for (unsigned i = 0; i < blocks(); ++i)
{
_cache->read(2 + i, buffer.get() + 512 * i);
}
prevBlock = lastBlock();
unsigned offset = 0;
for (iter = _files.begin(); iter != _files.end(); ++iter, ++offset)
{
FileEntry *e = *iter;
b.setOffset(0x1a + 0x1a * offset);
unsigned first = e->firstBlock();
unsigned last = e->lastBlock();
unsigned blocks = last - first;
unsigned offset = first - prevBlock;
if (offset == 0)
{
prevBlock = last;
continue;
}
e->_firstBlock = first - offset;
e->_lastBlock = last - offset;
e->writeDirectoryEntry(&b);
for (unsigned i = 0; i < blocks; ++i)
{
uint8_t buffer[512];
_cache->read(first + i, buffer);
_cache->write(prevBlock +i, buffer);
_cache->zeroBlock(first + i);
}
}
// now save the directory entries.
// load up the directory blocks.
for (unsigned i = 0; i < blocks(); ++i)
{
_cache->write(2 + i, buffer.get() + 512 * i);
}
_cache->sync();
return 0;
}
void *VolumeEntry::loadBlock(unsigned block)
{
return _cache->acquire(block);