mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-09 12:28:13 -04:00
metadata_v2: implement readdir
This commit is contained in:
parent
fdb8b07b08
commit
bd33fbd0eb
@ -66,10 +66,20 @@ class entry_view
|
|||||||
class directory_view
|
class directory_view
|
||||||
: public ::apache::thrift::frozen::View<thrift::metadata::directory> {
|
: public ::apache::thrift::frozen::View<thrift::metadata::directory> {
|
||||||
public:
|
public:
|
||||||
directory_view(::apache::thrift::frozen::View<thrift::metadata::directory> dv)
|
directory_view(
|
||||||
: ::apache::thrift::frozen::View<thrift::metadata::directory>(dv) {}
|
::apache::thrift::frozen::View<thrift::metadata::directory> dv,
|
||||||
|
::apache::thrift::frozen::MappedFrozen<thrift::metadata::metadata> const*
|
||||||
|
meta)
|
||||||
|
: ::apache::thrift::frozen::View<thrift::metadata::directory>(dv)
|
||||||
|
, meta_(meta) {}
|
||||||
|
|
||||||
boost::integer_range<uint32_t> entry_range() const;
|
boost::integer_range<uint32_t> entry_range() const;
|
||||||
|
|
||||||
|
uint32_t self_inode();
|
||||||
|
|
||||||
|
private:
|
||||||
|
::apache::thrift::frozen::MappedFrozen<thrift::metadata::metadata> const*
|
||||||
|
meta_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class metadata_v2 {
|
class metadata_v2 {
|
||||||
@ -115,6 +125,11 @@ class metadata_v2 {
|
|||||||
return impl_->opendir(de);
|
return impl_->opendir(de);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<std::pair<entry_view, std::string_view>>
|
||||||
|
readdir(directory_view d, size_t offset) const {
|
||||||
|
return impl_->readdir(d, offset);
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
size_t block_size() const { return impl_->block_size(); }
|
size_t block_size() const { return impl_->block_size(); }
|
||||||
|
|
||||||
@ -124,11 +139,6 @@ class metadata_v2 {
|
|||||||
return impl_->access(de, mode, uid, gid);
|
return impl_->access(de, mode, uid, gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
entry_view
|
|
||||||
readdir(directory_view d, size_t offset, std::string* name) const {
|
|
||||||
return impl_->readdir(d, offset, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t dirsize(directory_view d) const { return impl_->dirsize(d); }
|
size_t dirsize(directory_view d) const { return impl_->dirsize(d); }
|
||||||
|
|
||||||
int readlink(entry_view de, char* buf, size_t size) const {
|
int readlink(entry_view de, char* buf, size_t size) const {
|
||||||
@ -170,13 +180,14 @@ class metadata_v2 {
|
|||||||
|
|
||||||
virtual std::optional<directory_view> opendir(entry_view de) const = 0;
|
virtual std::optional<directory_view> opendir(entry_view de) const = 0;
|
||||||
|
|
||||||
|
virtual std::optional<std::pair<entry_view, std::string_view>>
|
||||||
|
readdir(directory_view d, size_t offset) const = 0;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
virtual size_t block_size() const = 0;
|
virtual size_t block_size() const = 0;
|
||||||
virtual unsigned block_size_bits() const = 0;
|
virtual unsigned block_size_bits() const = 0;
|
||||||
virtual int
|
virtual int
|
||||||
access(entry_view de, int mode, uid_t uid, gid_t gid) const = 0;
|
access(entry_view de, int mode, uid_t uid, gid_t gid) const = 0;
|
||||||
virtual entry_view
|
|
||||||
readdir(directory_view d, size_t offset, std::string* name) const = 0;
|
|
||||||
virtual size_t dirsize(directory_view d) const = 0;
|
virtual size_t dirsize(directory_view d) const = 0;
|
||||||
virtual int readlink(entry_view de, char* buf, size_t size) const = 0;
|
virtual int readlink(entry_view de, char* buf, size_t size) const = 0;
|
||||||
virtual int readlink(entry_view de, std::string* buf) const = 0;
|
virtual int readlink(entry_view de, std::string* buf) const = 0;
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cassert>
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -54,6 +54,17 @@ boost::integer_range<uint32_t> directory_view::entry_range() const {
|
|||||||
return boost::irange(first, first + entry_count());
|
return boost::irange(first, first + entry_count());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t directory_view::self_inode() {
|
||||||
|
auto pos = getPosition().bitOffset;
|
||||||
|
if (pos > 0) {
|
||||||
|
// XXX: this is evil trickery...
|
||||||
|
auto one = meta_->directories()[1].getPosition().bitOffset;
|
||||||
|
assert(pos % one == 0);
|
||||||
|
pos /= one;
|
||||||
|
}
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename LoggerPolicy>
|
template <typename LoggerPolicy>
|
||||||
class metadata_v2_ : public metadata_v2::impl {
|
class metadata_v2_ : public metadata_v2::impl {
|
||||||
public:
|
public:
|
||||||
@ -96,6 +107,9 @@ class metadata_v2_ : public metadata_v2::impl {
|
|||||||
|
|
||||||
std::optional<directory_view> opendir(entry_view entry) const override;
|
std::optional<directory_view> opendir(entry_view entry) const override;
|
||||||
|
|
||||||
|
std::optional<std::pair<entry_view, std::string_view>>
|
||||||
|
readdir(directory_view dir, size_t offset) const override;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
size_t block_size() const override {
|
size_t block_size() const override {
|
||||||
return static_cast<size_t>(1) << cfg_->block_size_bits;
|
return static_cast<size_t>(1) << cfg_->block_size_bits;
|
||||||
@ -105,8 +119,6 @@ class metadata_v2_ : public metadata_v2::impl {
|
|||||||
|
|
||||||
int access(entry_view entry, int mode, uid_t uid,
|
int access(entry_view entry, int mode, uid_t uid,
|
||||||
gid_t gid) const override;
|
gid_t gid) const override;
|
||||||
entry_view
|
|
||||||
readdir(directory_view d, size_t offset, std::string* name) const override;
|
|
||||||
size_t dirsize(directory_view d) const override {
|
size_t dirsize(directory_view d) const override {
|
||||||
return d->count + 2; // adds '.' and '..', which we fake in ;-)
|
return d->count + 2; // adds '.' and '..', which we fake in ;-)
|
||||||
}
|
}
|
||||||
@ -123,8 +135,12 @@ class metadata_v2_ : public metadata_v2::impl {
|
|||||||
return entry_view(meta_.entries()[index], &meta_);
|
return entry_view(meta_.entries()[index], &meta_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry_view make_entry_view_from_inode(uint32_t inode) const {
|
||||||
|
return make_entry_view(meta_.entry_index()[inode]);
|
||||||
|
}
|
||||||
|
|
||||||
directory_view make_directory_view(size_t index) const {
|
directory_view make_directory_view(size_t index) const {
|
||||||
return directory_view(meta_.directories()[index]);
|
return directory_view(meta_.directories()[index], &meta_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump(std::ostream& os, const std::string& indent, entry_view entry,
|
void dump(std::ostream& os, const std::string& indent, entry_view entry,
|
||||||
@ -170,7 +186,7 @@ class metadata_v2_ : public metadata_v2::impl {
|
|||||||
inode -= inode_offset_;
|
inode -= inode_offset_;
|
||||||
std::optional<entry_view> rv;
|
std::optional<entry_view> rv;
|
||||||
if (inode >= 0 && inode < int(meta_.entry_index().size())) {
|
if (inode >= 0 && inode < int(meta_.entry_index().size())) {
|
||||||
rv = make_entry_view(meta_.entry_index()[inode]);
|
rv = make_entry_view_from_inode(inode);
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -228,7 +244,9 @@ void metadata_v2_<LoggerPolicy>::dump(
|
|||||||
std::function<void(const std::string&, uint32_t)> const& icb) const {
|
std::function<void(const std::string&, uint32_t)> const& icb) const {
|
||||||
auto count = dir.entry_count();
|
auto count = dir.entry_count();
|
||||||
auto first = dir.first_entry();
|
auto first = dir.first_entry();
|
||||||
os << indent << "(" << count << ") entries\n";
|
|
||||||
|
os << indent << "(" << count << ") entries [" << dir.self_inode() << ":"
|
||||||
|
<< dir.parent_inode() << "]\n";
|
||||||
|
|
||||||
for (size_t i = 0; i < count; ++i) {
|
for (size_t i = 0; i < count; ++i) {
|
||||||
dump(os, indent, make_entry_view(first + i), icb);
|
dump(os, indent, make_entry_view(first + i), icb);
|
||||||
@ -380,6 +398,31 @@ metadata_v2_<LoggerPolicy>::opendir(entry_view entry) const {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename LoggerPolicy>
|
||||||
|
std::optional<std::pair<entry_view, std::string_view>>
|
||||||
|
metadata_v2_<LoggerPolicy>::readdir(directory_view dir, size_t offset) const {
|
||||||
|
switch (offset) {
|
||||||
|
case 0:
|
||||||
|
return std::pair(make_entry_view_from_inode(dir.self_inode()), ".");
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
return std::pair(make_entry_view_from_inode(dir.parent_inode()), "..");
|
||||||
|
|
||||||
|
default:
|
||||||
|
offset -= 2;
|
||||||
|
|
||||||
|
if (offset >= dir.entry_count()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto entry = make_entry_view(dir.first_entry() + offset);
|
||||||
|
|
||||||
|
return std::pair(entry, entry.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
template <typename LoggerPolicy>
|
template <typename LoggerPolicy>
|
||||||
int metadata_v2_<LoggerPolicy>::access(entry_view entry, int mode, uid_t uid,
|
int metadata_v2_<LoggerPolicy>::access(entry_view entry, int mode, uid_t uid,
|
||||||
@ -396,44 +439,6 @@ int metadata_v2_<LoggerPolicy>::open(entry_view entry) const {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename LoggerPolicy>
|
|
||||||
entry_view
|
|
||||||
metadata_v2_<LoggerPolicy>::readdir(directory_view d, size_t offset,
|
|
||||||
std::string* name) const {
|
|
||||||
entry_view entry;
|
|
||||||
|
|
||||||
switch (offset) {
|
|
||||||
case 0:
|
|
||||||
entry = as<dir_entry>(d->self);
|
|
||||||
|
|
||||||
if (name) {
|
|
||||||
name->assign(".");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
entry = as<dir_entry>(d->parent);
|
|
||||||
|
|
||||||
if (name) {
|
|
||||||
name->assign("..");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
offset -= 2;
|
|
||||||
|
|
||||||
if (offset < d->count) {
|
|
||||||
entry = dir_reader_->readdir(d, offset, name);
|
|
||||||
} else {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename LoggerPolicy>
|
template <typename LoggerPolicy>
|
||||||
int metadata_v2_<LoggerPolicy>::readlink(entry_view entry, char* buf,
|
int metadata_v2_<LoggerPolicy>::readlink(entry_view entry, char* buf,
|
||||||
size_t size) const {
|
size_t size) const {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user