2
0
mirror of https://github.com/dominicusin/zfs-win synced 2025-08-30 13:57:58 +00:00

More work on the ObjectSet class.

This commit is contained in:
gabest11
2010-07-22 20:59:31 +00:00
parent 03b74d9be8
commit 9d5fae9b1c
7 changed files with 130 additions and 120 deletions

View File

@@ -12,12 +12,90 @@ namespace ZFS
{
}
bool ObjectSet::Init(std::vector<uint8_t>& objset, std::vector<uint8_t>& dnode)
bool ObjectSet::Read(Pool& pool, blkptr_t* bp, size_t count)
{
m_objset.swap(objset);
m_dnode.swap(dnode);
ASSERT(bp->type == DMU_OT_OBJSET);
m_objset.clear();
m_dnode.clear();
m_dnode_count = 0;
if(!pool.Read(m_objset, bp, count))
{
return false;
}
objset_phys_t* os = (objset_phys_t*)m_objset.data();
if(os->meta_dnode.type != DMU_OT_DNODE)
{
return false;
}
if(!pool.Read(m_dnode, os->meta_dnode.blkptr, os->meta_dnode.nblkptr))
{
return false;
}
m_dnode_count = m_dnode.size() / sizeof(dnode_phys_t);
if(os->type == DMU_OST_META || os->type == DMU_OST_ZFS)
{
if(m_dnode_count < 2)
{
return false;
}
dnode_phys_t* dn = (*this)[1];
if(os->type == DMU_OST_META && dn->type != DMU_OT_OBJECT_DIRECTORY
|| os->type == DMU_OST_ZFS && dn->type != DMU_OT_MASTER_NODE)
{
return false;
}
if(!m_objdir.Read(pool, dn->blkptr, dn->nblkptr))
{
return false;
}
}
return true;
}
objset_phys_t* ObjectSet::operator -> ()
{
ASSERT(m_objset.size() >= sizeof(objset_phys_t));
return (objset_phys_t*)m_objset.data();
}
dnode_phys_t* ObjectSet::operator [] (size_t index)
{
ASSERT(index < m_dnode_count);
return (dnode_phys_t*)m_dnode.data() + index;
}
dnode_phys_t* ObjectSet::operator [] (const char* s)
{
uint64_t index;
if(m_objdir.Lookup(s, index))
{
size_t i = (size_t)index;
if(i < m_dnode_count)
{
return (*this)[i];
}
}
return NULL;
}
size_t ObjectSet::count()
{
return m_dnode_count;
}
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include "zfs.h"
#include "Pool.h"
#include "ZapObject.h"
namespace ZFS
{
@@ -9,15 +10,17 @@ namespace ZFS
std::vector<uint8_t> m_objset;
std::vector<uint8_t> m_dnode;
size_t m_dnode_count;
ZapObject m_objdir;
public:
ObjectSet();
virtual ~ObjectSet();
bool Init(std::vector<uint8_t>& objset, std::vector<uint8_t>& dnode);
bool Read(Pool& pool, blkptr_t* bp, size_t count);
objset_phys_t* operator -> () {ASSERT(m_objset.size() >= sizeof(objset_phys_t)); return (objset_phys_t*)m_objset.data();}
dnode_phys_t* operator [] (size_t index) {ASSERT(index < m_dnode_count); return (dnode_phys_t*)m_dnode.data() + index;}
size_t count() {return m_dnode_count;}
objset_phys_t* operator -> ();
dnode_phys_t* operator [] (size_t index);
dnode_phys_t* operator [] (const char* s);
size_t count();
};
}

View File

@@ -129,40 +129,4 @@ namespace ZFS
return r.ReadToEnd(buff);
}
bool Pool::Read(ObjectSet& objset, blkptr_t* bp, size_t count)
{
ASSERT(bp->type == DMU_OT_OBJSET);
std::vector<uint8_t> buff[2];
if(Read(buff[0], bp, count))
{
objset_phys_t* os = (objset_phys_t*)buff[0].data();
if(os->meta_dnode.type == DMU_OT_DNODE)
{
if(Read(buff[1], os->meta_dnode.blkptr, os->meta_dnode.nblkptr))
{
return objset.Init(buff[0], buff[1]);
}
}
}
return false;
}
bool Pool::Read(ZapObject& zap, blkptr_t* bp, size_t count)
{
std::vector<uint8_t> buff;
if(Read(buff, bp, count))
{
zap.Parse(buff);
return true;
}
return false;
}
}

View File

@@ -23,8 +23,6 @@
#include "zfs.h"
#include "Device.h"
#include "ZapObject.h"
#include "ObjectSet.h"
namespace ZFS
{
@@ -44,7 +42,5 @@ namespace ZFS
void Close();
bool Read(std::vector<uint8_t>& buff, blkptr_t* bp, size_t count);
bool Read(ObjectSet& objset, blkptr_t* bp, size_t count);
bool Read(ZapObject& zap, blkptr_t* bp, size_t count);
};
}

View File

@@ -30,30 +30,32 @@ namespace ZFS
ZapObject::~ZapObject()
{
Clear();
RemoveAll();
}
void ZapObject::Parse(std::vector<uint8_t>& buff)
bool ZapObject::Read(Pool& pool, blkptr_t* bp, size_t count)
{
Clear();
RemoveAll();
if(buff.size() >= sizeof(uint64_t))
std::vector<uint8_t> buff;
if(pool.Read(buff, bp, count))
{
uint64_t* ptr = (uint64_t*)buff.data();
if(*ptr == ZBT_MICRO) ParseMicro(buff);
else if(*ptr == ZBT_HEADER) ParseFat(buff);
}
}
void ZapObject::Clear()
{
for(auto i = begin(); i != end(); i++)
{
delete i->second;
if(buff.size() >= sizeof(uint64_t))
{
switch(*(uint64_t*)buff.data())
{
case ZBT_MICRO:
ParseMicro(buff);
return true;
case ZBT_HEADER:
ParseFat(buff);
return true;
}
}
}
clear();
return false;
}
bool ZapObject::Lookup(const char* name, uint64_t& value)
@@ -87,6 +89,16 @@ namespace ZFS
return false;
}
void ZapObject::RemoveAll()
{
for(auto i = begin(); i != end(); i++)
{
delete i->second;
}
clear();
}
void ZapObject::ParseMicro(std::vector<uint8_t>& buff)
{
mzap_phys_t* mzap = (mzap_phys_t*)buff.data();

View File

@@ -21,12 +21,13 @@
#pragma once
#include "zfs.h"
#include "Pool.h"
namespace ZFS
{
class ZapObject : protected std::map<std::string, std::vector<uint8_t>*>
{
void RemoveAll();
void ParseMicro(std::vector<uint8_t>& buff);
void ParseFat(std::vector<uint8_t>& buff);
bool ParseArray(std::vector<uint8_t>& buff, zap_leaf_entry_t* e, uint16_t index);
@@ -35,8 +36,7 @@ namespace ZFS
ZapObject();
virtual ~ZapObject();
void Parse(std::vector<uint8_t>& buff);
void Clear();
bool Read(Pool& pool, blkptr_t* bp, size_t count);
bool Lookup(const char* name, uint64_t& value);
bool Lookup(const char* name, std::string& value);

View File

@@ -22,6 +22,7 @@
#include "stdafx.h"
#include "Pool.h"
#include "Device.h"
#include "ObjectSet.h"
#include "ZapObject.h"
int _tmain(int argc, _TCHAR* argv[])
@@ -72,47 +73,27 @@ int _tmain(int argc, _TCHAR* argv[])
ZFS::ObjectSet os;
if(p.Read(os, &dev->m_active->rootbp, 1))
if(os.Read(p, &dev->m_active->rootbp, 1))
{
ASSERT(os.count() > 2);
dnode_phys_t* root_dataset = NULL;
ASSERT(os[1]->type == DMU_OT_OBJECT_DIRECTORY);
if(os[1]->type == DMU_OT_OBJECT_DIRECTORY)
{
ZFS::ZapObject zap;
if(p.Read(zap, os[1]->blkptr, os[1]->nblkptr))
{
uint64_t index;
if(zap.Lookup("root_dataset", index))
{
if(index < os.count() && os[index]->type == DMU_OT_DSL_DIR)
{
root_dataset = os[index];
}
}
}
}
dnode_phys_t* root_dataset = os["root_dataset"];
dnode_phys_t* head_dataset = NULL;
if(root_dataset != NULL)
if(root_dataset != NULL && root_dataset->type == DMU_OT_DSL_DIR)
{
dsl_dir_phys_t* dir = (dsl_dir_phys_t*)root_dataset->bonus;
size_t index = (size_t)dir->head_dataset_obj;
if(index < os.count() && os[index]->type == DMU_OT_DSL_DATASET)
if(index < os.count())
{
head_dataset = os[index];
}
}
if(head_dataset != NULL)
if(head_dataset != NULL && head_dataset->type == DMU_OT_DSL_DATASET)
{
dsl_dataset_phys_t* ds = (dsl_dataset_phys_t*)head_dataset->bonus;
@@ -120,35 +101,11 @@ int _tmain(int argc, _TCHAR* argv[])
{
ZFS::ObjectSet os;
if(p.Read(os, &ds->bp, 1))
if(os.Read(p, &ds->bp, 1))
{
dnode_phys_t* root = NULL;
dnode_phys_t* root = os["ROOT"];
ASSERT(os[1]->type == DMU_OT_MASTER_NODE);
if(os[1]->type == DMU_OT_MASTER_NODE)
{
ZFS::ZapObject zap;
if(p.Read(zap, os[1]->blkptr, os[1]->nblkptr))
{
uint64_t index;
if(zap.Lookup("ROOT", index)) // NOTE: the ROOT dataset may not contain too many files, don't be surprised
{
if(index < os.count() && os[index]->type == DMU_OT_DIRECTORY_CONTENTS)
{
root = os[index];
}
else
{
ASSERT(0);
}
}
}
}
if(root != NULL)
if(root != NULL && root->type == DMU_OT_DIRECTORY_CONTENTS)
{
znode_phys_t* node = (znode_phys_t*)root->bonus;