2
0
mirror of https://github.com/dominicusin/zfs-win synced 2025-08-31 06:15:21 +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); ASSERT(bp->type == DMU_OT_OBJSET);
m_dnode.swap(dnode);
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); 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; 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 #pragma once
#include "zfs.h" #include "Pool.h"
#include "ZapObject.h"
namespace ZFS namespace ZFS
{ {
@@ -9,15 +10,17 @@ namespace ZFS
std::vector<uint8_t> m_objset; std::vector<uint8_t> m_objset;
std::vector<uint8_t> m_dnode; std::vector<uint8_t> m_dnode;
size_t m_dnode_count; size_t m_dnode_count;
ZapObject m_objdir;
public: public:
ObjectSet(); ObjectSet();
virtual ~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();} objset_phys_t* operator -> ();
dnode_phys_t* operator [] (size_t index) {ASSERT(index < m_dnode_count); return (dnode_phys_t*)m_dnode.data() + index;} dnode_phys_t* operator [] (size_t index);
size_t count() {return m_dnode_count;} dnode_phys_t* operator [] (const char* s);
size_t count();
}; };
} }

View File

@@ -129,40 +129,4 @@ namespace ZFS
return r.ReadToEnd(buff); 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 "zfs.h"
#include "Device.h" #include "Device.h"
#include "ZapObject.h"
#include "ObjectSet.h"
namespace ZFS namespace ZFS
{ {
@@ -44,7 +42,5 @@ namespace ZFS
void Close(); void Close();
bool Read(std::vector<uint8_t>& buff, blkptr_t* bp, size_t count); 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() 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(buff.size() >= sizeof(uint64_t))
{
if(*ptr == ZBT_MICRO) ParseMicro(buff); switch(*(uint64_t*)buff.data())
else if(*ptr == ZBT_HEADER) ParseFat(buff); {
} case ZBT_MICRO:
} ParseMicro(buff);
return true;
void ZapObject::Clear() case ZBT_HEADER:
{ ParseFat(buff);
for(auto i = begin(); i != end(); i++) return true;
{ }
delete i->second; }
} }
clear(); return false;
} }
bool ZapObject::Lookup(const char* name, uint64_t& value) bool ZapObject::Lookup(const char* name, uint64_t& value)
@@ -87,6 +89,16 @@ namespace ZFS
return false; return false;
} }
void ZapObject::RemoveAll()
{
for(auto i = begin(); i != end(); i++)
{
delete i->second;
}
clear();
}
void ZapObject::ParseMicro(std::vector<uint8_t>& buff) void ZapObject::ParseMicro(std::vector<uint8_t>& buff)
{ {
mzap_phys_t* mzap = (mzap_phys_t*)buff.data(); mzap_phys_t* mzap = (mzap_phys_t*)buff.data();

View File

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

View File

@@ -22,6 +22,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "Pool.h" #include "Pool.h"
#include "Device.h" #include "Device.h"
#include "ObjectSet.h"
#include "ZapObject.h" #include "ZapObject.h"
int _tmain(int argc, _TCHAR* argv[]) int _tmain(int argc, _TCHAR* argv[])
@@ -72,47 +73,27 @@ int _tmain(int argc, _TCHAR* argv[])
ZFS::ObjectSet os; 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); ASSERT(os.count() > 2);
dnode_phys_t* root_dataset = NULL; dnode_phys_t* root_dataset = os["root_dataset"];
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* head_dataset = NULL; 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; dsl_dir_phys_t* dir = (dsl_dir_phys_t*)root_dataset->bonus;
size_t index = (size_t)dir->head_dataset_obj; 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]; 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; 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; 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(root != NULL && root->type == DMU_OT_DIRECTORY_CONTENTS)
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)
{ {
znode_phys_t* node = (znode_phys_t*)root->bonus; znode_phys_t* node = (znode_phys_t*)root->bonus;