mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-09 04:19:10 -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
|
||||
: public ::apache::thrift::frozen::View<thrift::metadata::directory> {
|
||||
public:
|
||||
directory_view(::apache::thrift::frozen::View<thrift::metadata::directory> dv)
|
||||
: ::apache::thrift::frozen::View<thrift::metadata::directory>(dv) {}
|
||||
directory_view(
|
||||
::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;
|
||||
|
||||
uint32_t self_inode();
|
||||
|
||||
private:
|
||||
::apache::thrift::frozen::MappedFrozen<thrift::metadata::metadata> const*
|
||||
meta_;
|
||||
};
|
||||
|
||||
class metadata_v2 {
|
||||
@ -115,6 +125,11 @@ class metadata_v2 {
|
||||
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
|
||||
size_t block_size() const { return impl_->block_size(); }
|
||||
|
||||
@ -124,11 +139,6 @@ class metadata_v2 {
|
||||
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); }
|
||||
|
||||
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<std::pair<entry_view, std::string_view>>
|
||||
readdir(directory_view d, size_t offset) const = 0;
|
||||
|
||||
#if 0
|
||||
virtual size_t block_size() const = 0;
|
||||
virtual unsigned block_size_bits() const = 0;
|
||||
virtual int
|
||||
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 int readlink(entry_view de, char* buf, size_t size) const = 0;
|
||||
virtual int readlink(entry_view de, std::string* buf) const = 0;
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
@ -54,6 +54,17 @@ boost::integer_range<uint32_t> directory_view::entry_range() const {
|
||||
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>
|
||||
class metadata_v2_ : public metadata_v2::impl {
|
||||
public:
|
||||
@ -96,6 +107,9 @@ class metadata_v2_ : public metadata_v2::impl {
|
||||
|
||||
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
|
||||
size_t block_size() const override {
|
||||
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,
|
||||
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 {
|
||||
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_);
|
||||
}
|
||||
|
||||
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 {
|
||||
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,
|
||||
@ -170,7 +186,7 @@ class metadata_v2_ : public metadata_v2::impl {
|
||||
inode -= inode_offset_;
|
||||
std::optional<entry_view> rv;
|
||||
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;
|
||||
}
|
||||
@ -228,7 +244,9 @@ void metadata_v2_<LoggerPolicy>::dump(
|
||||
std::function<void(const std::string&, uint32_t)> const& icb) const {
|
||||
auto count = dir.entry_count();
|
||||
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) {
|
||||
dump(os, indent, make_entry_view(first + i), icb);
|
||||
@ -380,6 +398,31 @@ metadata_v2_<LoggerPolicy>::opendir(entry_view entry) const {
|
||||
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
|
||||
template <typename LoggerPolicy>
|
||||
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;
|
||||
}
|
||||
|
||||
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>
|
||||
int metadata_v2_<LoggerPolicy>::readlink(entry_view entry, char* buf,
|
||||
size_t size) const {
|
||||
|
Loading…
x
Reference in New Issue
Block a user