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:
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
@@ -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();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@@ -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();
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user