1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
#pragma once
#include "constants.h"
#include "exceptions.h"
#include "files.h"
#include "myutils.h"
#include "platform.h"
#include "streams.h"
#include <memory>
#include <string.h>
#include <unordered_map>
#include <utility>
namespace securefs
{
class FileTableIO;
class AutoClosedFileBase;
class FileTable
{
DISABLE_COPY_MOVE(FileTable)
private:
typedef std::unordered_map<id_type, std::unique_ptr<FileBase>, id_hash> table_type;
private:
static const int MAX_NUM_CLOSED = 101, NUM_EJECT = 8;
private:
key_type m_master_key;
table_type m_files;
std::vector<id_type> m_closed_ids;
std::unique_ptr<FileTableIO> m_fio;
uint32_t m_flags;
unsigned m_block_size, m_iv_size;
std::shared_ptr<const OSService> m_root;
private:
void eject();
void finalize(std::unique_ptr<FileBase>&);
public:
explicit FileTable(int version,
std::shared_ptr<const OSService> root,
const key_type& master_key,
uint32_t flags,
unsigned block_size,
unsigned iv_size);
~FileTable();
FileBase* open_as(const id_type& id, int type);
FileBase* create_as(const id_type& id, int type);
void close(FileBase*);
bool is_readonly() const noexcept { return (m_flags & kOptionReadOnly) != 0; }
bool is_auth_enabled() const noexcept { return (m_flags & kOptionNoAuthentication) == 0; }
bool is_time_stored() const noexcept { return (m_flags & kOptionStoreTime) != 0; }
void gc();
void statfs(struct fuse_statvfs* fs_info) { m_root->statfs(fs_info); }
};
class AutoClosedFileBase
{
private:
FileTable* m_ft;
FileBase* m_fb;
public:
explicit AutoClosedFileBase(FileTable* ft, FileBase* fb) : m_ft(ft), m_fb(fb) {}
AutoClosedFileBase(const AutoClosedFileBase&) = delete;
AutoClosedFileBase& operator=(const AutoClosedFileBase&) = delete;
AutoClosedFileBase(AutoClosedFileBase&& other) noexcept : m_ft(other.m_ft), m_fb(other.m_fb)
{
other.m_ft = nullptr;
other.m_fb = nullptr;
}
AutoClosedFileBase& operator=(AutoClosedFileBase&& other) noexcept
{
if (this == &other)
return *this;
swap(other);
return *this;
}
~AutoClosedFileBase()
{
try
{
reset(nullptr);
}
catch (...)
{
}
}
FileBase* get() noexcept { return m_fb; }
template <class T>
T* get_as() noexcept
{
return m_fb->cast_as<T>();
}
FileBase& operator*() noexcept { return *m_fb; }
FileBase* operator->() noexcept { return m_fb; }
FileBase* release() noexcept
{
auto rt = m_fb;
m_fb = nullptr;
return rt;
}
void reset(FileBase* fb)
{
if (m_ft && m_fb)
{
m_ft->close(m_fb);
}
m_fb = fb;
}
void swap(AutoClosedFileBase& other) noexcept
{
std::swap(m_ft, other.m_ft);
std::swap(m_fb, other.m_fb);
}
};
inline AutoClosedFileBase open_as(FileTable& table, const id_type& id, int type)
{
return AutoClosedFileBase(&table, table.open_as(id, type));
}
inline AutoClosedFileBase create_as(FileTable& table, const id_type& id, int type)
{
return AutoClosedFileBase(&table, table.create_as(id, type));
}
} // namespace securefs
|