Loading fs/src/main.cpp +55 −17 Original line number Diff line number Diff line Loading @@ -7,14 +7,30 @@ static struct fuse_operations adafs_ops; using namespace std; //std::shared_ptr<Metadata> md; int adafs_getattr(const char *path, struct stat *attr, struct fuse_file_info *fi){ auto fpath = util::adafs_fullpath("meta/inodes"s); //FUSE_UNKNOWN_INO errorcode if attr->st_ino could not be resolved by VFS (This is unverified information // but Fuse initializes it with this value initially fuse.c:3303 // if (attr->st_ino == -1) { // ADAFS_DATA->logger->info("st_ino = -1: "s + to_string(attr->st_ino)); // } else { // ADAFS_DATA->logger->info("st_ino != -1: "s + to_string(attr->st_ino)); // } // ADAFS_DATA->logger->info("adafs_getattr_enter1"s); // ADAFS_DATA->logger->info("st_ino: "s + to_string(attr->st_ino)); // ADAFS_DATA->logger->info("adafs_getattr_enter2"s); // call lookup for *path, return int (use errorcodes), put pointer to Metadata object in parameter // if exist (i.e. == 0) use Metadata object, else return ENOENT // auto path_s = bfs::path(path); // ADAFS_DATA->logger->info(path_s); // ADAFS_DATA->logger->flush(); auto md = make_shared<Metadata>(); md->mode(S_IFDIR | 0755); md->inode_no(1); read_all_metadata(*md, 1, fpath); // md->mode(S_IFDIR | 0755); // md->inode_no(1); // get_metadata(*md, path_s); // read_all_metadata(*md, 1, fpath); if (strcmp(path, "/") == 0) { attr->st_ino = md->inode_no(); attr->st_mode = md->mode(); Loading @@ -31,6 +47,15 @@ int adafs_getattr(const char *path, struct stat *attr, struct fuse_file_info *fi } if (strcmp(path, "/file") == 0) { attr->st_mode = S_IFDIR | 0755; return 0; } if (strcmp(path, "/file/file2") == 0) { auto p_dir = make_shared<struct stat>(); lstat("/", p_dir.get()); ADAFS_DATA->logger->info(p_dir->st_ino); ADAFS_DATA->logger->flush(); attr->st_mode = S_IFREG | 0755; attr->st_nlink = 1; attr->st_size = strlen("blubb"); Loading @@ -46,26 +71,35 @@ void *adafs_init(struct fuse_conn_info *conn, struct fuse_config *cfg) { // ADAFS_DATA->logger->info("gid_: {}", fuse_get_context()->gid); // ADAFS_DATA->logger->info("pid: {0:d}", fuse_get_context()->pid); // ADAFS_DATA->logger->info("rootdir: {}", ((struct adafs_data*)fuse_get_context()->private_data)->rootdir); //Initialize directory structure for metadata. //Initialize directory structure for metadata. XXX We need this later for lowlevel when we split dentry from inodes boost::filesystem::create_directories(ADAFS_DATA->rootdir + "/meta/dentries"s); boost::filesystem::create_directories(ADAFS_DATA->rootdir + "/meta/inodes"s); boost::filesystem::create_directories(ADAFS_DATA->rootdir + "/data/chunks"s); // XXX Dunno if this is of any use cfg->use_ino = 1; //Init file system configuration ADAFS_DATA->blocksize = 4096; // Init unordered_map for caching metadata that was already looked up XXX use later ADAFS_DATA->hashmap = unordered_map<string, string>(); ADAFS_DATA->hashf = hash<string>(); //Init metadata // if (get_metadata("/") == -ENOENT) { // md = make_shared<Metadata>(S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO); // auto md = make_shared<Metadata>(S_IFDIR | 0755); // } // auto s = util::adafs_fullpath("meta/inodes"); // auto md = make_shared<Metadata>(); // write_all_metadata(*md, s); // Check that root metadata exists. If not intiialize it if (get_metadata(*md, "/"s) == -ENOENT) { ADAFS_DATA->logger->info("Root metadata not found. Initializing..."s); md->init_ACM_time(); md->mode(S_IFDIR | 0755); md->uid(fuse_get_context()->uid); md->gid(fuse_get_context()->gid); md->inode_no(ADAFS_ROOT_INODE); write_all_metadata(*md, ADAFS_DATA->hashf("/"s), ADAFS_DATA->inode_path); ADAFS_DATA->logger->info("Creating Metadata object"s); } ADAFS_DATA->logger->info("Survived creating Metadata object"s); ADAFS_DATA->logger->flush(); return ADAFS_DATA; Loading @@ -89,7 +123,7 @@ int main(int argc, char *argv[]) { //Initialize the mapping of Fuse functions init_adafs_ops(&adafs_ops); // create the adafs_data object (struct) // create the private data struct auto a_data = make_shared<adafs_data>(); //set the logger and initialize it with spdlog a_data->logger = spdlog::basic_logger_mt("basic_logger", "adafs.log"); Loading @@ -98,8 +132,12 @@ int main(int argc, char *argv[]) { argv[argc-2] = argv[argc-1]; argv[argc-1] = NULL; argc--; //init fuse and give the private data for further reference. //set all paths a_data->inode_path = a_data->rootdir + "meta/inodes"s; a_data->dentry_path = a_data->rootdir + "meta/dentries"s; a_data->chunk_path = a_data->rootdir + "data/chunks"s; //print version cout << "Fuse library version: "s + to_string(FUSE_MAJOR_VERSION) + to_string(FUSE_MINOR_VERSION) << endl; //init fuse and give the private data struct for further reference. return fuse_main(argc, argv, &adafs_ops, a_data.get()); } fs/src/main.h +20 −6 Original line number Diff line number Diff line Loading @@ -12,25 +12,39 @@ #include <string> #include <iostream> #include <cstdint> #include <unordered_map> //boost libraries #include <boost/filesystem.hpp> #include "spdlog/spdlog.h" namespace bfs = boost::filesystem; struct adafs_data { std::string rootdir; // Below paths are needed for future version when we'll get rid of path hashing. std::string inode_path; // used std::string dentry_path; // unused std::string chunk_path; // unused // Caching std::unordered_map<std::string, std::string> hashmap; std::hash<std::string> hashf; // Housekeeping std::shared_ptr<spdlog::logger> logger; std::int64_t inode_count; std::mutex inode_mutex; // Later the blocksize will likely be coupled to the chunks to allow individually big chunk sizes. int32_t blocksize; }; #define ADAFS_DATA ((struct adafs_data*) fuse_get_context()->private_data) #define ADAFS_ROOT_INODE 1 namespace util { std::string adafs_fullpath(const std::string &path); boost::filesystem::path adafs_fullpath(const std::string& path); int reset_inode_no(); Loading fs/src/metadata.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -94,9 +94,9 @@ Metadata::Metadata() : atime_(), gid_(), mode_(), inode_no_(), link_count_(), size_(), blocks_() {} link_count_(0), size_(0), blocks_(0) {} Metadata::Metadata(mode_t mode) : atime_(), Loading fs/src/metadata.h +2 −1 Original line number Diff line number Diff line Loading @@ -19,13 +19,14 @@ private: uint32_t size_; // size_ in bytes, might be computed instead of stored uint32_t blocks_; // allocated file system blocks_ void init_ACM_time(); public: Metadata(); Metadata(mode_t mode); void init_ACM_time(); //Getter and Setter time_t atime() const; Loading fs/src/metadata_ops.cpp +79 −35 Original line number Diff line number Diff line Loading @@ -7,48 +7,51 @@ #include <boost/archive/binary_iarchive.hpp> #include <boost/archive/binary_oarchive.hpp> namespace fs = boost::filesystem; // TODO error handling. Each read_metadata_field should check for boolean, i.e., if I/O failed. bool write_all_metadata(const Metadata &md, const std::string &path_str) { write_metadata_field(md.atime(), md.inode_no(), "/atime"s, path_str); write_metadata_field(md.mtime(), md.inode_no(), "/mtime"s, path_str); write_metadata_field(md.ctime(), md.inode_no(), "/ctime"s, path_str); write_metadata_field(md.uid(), md.inode_no(), "/uid"s, path_str); write_metadata_field(md.gid(), md.inode_no(), "/gid"s, path_str); write_metadata_field(md.mode(), md.inode_no(), "/mode"s, path_str); write_metadata_field(md.inode_no(), md.inode_no(), "/inode_no"s, path_str); write_metadata_field(md.link_count(), md.inode_no(), "/link_count"s, path_str); write_metadata_field(md.size(), md.inode_no(), "/size"s, path_str); write_metadata_field(md.blocks(), md.inode_no(), "/blocks"s, path_str); bool write_all_metadata(const Metadata& md, const unsigned long& hash, const bfs::path& i_path) { write_metadata_field(md.atime(), hash, "/atime"s, i_path); write_metadata_field(md.mtime(), hash, "/mtime"s, i_path); write_metadata_field(md.ctime(), hash, "/ctime"s, i_path); write_metadata_field(md.uid(), hash, "/uid"s, i_path); write_metadata_field(md.gid(), hash, "/gid"s, i_path); write_metadata_field(md.mode(), hash, "/mode"s, i_path); write_metadata_field(md.inode_no(), hash, "/inode_no"s, i_path); write_metadata_field(md.link_count(), hash, "/link_count"s, i_path); write_metadata_field(md.size(), hash, "/size"s, i_path); write_metadata_field(md.blocks(), hash, "/blocks"s, i_path); return true; } bool write_all_metadata(const Metadata& md, const unsigned long& hash, const string& i_path) { return write_all_metadata(md, hash, bfs::path(i_path)); } // TODO error handling. Each read_metadata_field should check for nullptr, i.e., if I/O failed. bool read_all_metadata(Metadata &md, const uint64_t &inode, const std::string &path_str) { md.atime(*read_metadata_field<time_t>(inode, "/atime"s, path_str)); md.mtime(*read_metadata_field<time_t>(inode, "/mtime"s, path_str)); md.ctime(*read_metadata_field<time_t>(inode, "/ctime"s, path_str)); md.uid(*read_metadata_field<uint32_t>(inode, "/uid"s, path_str)); md.gid(*read_metadata_field<uint32_t>(inode, "/gid"s, path_str)); md.mode(*read_metadata_field<uint32_t>(inode, "/mode"s, path_str)); md.inode_no(*read_metadata_field<uint64_t>(inode, "/inode_no"s, path_str)); md.link_count(*read_metadata_field<uint32_t>(inode, "/link_count"s, path_str)); md.size(*read_metadata_field<uint32_t>(inode, "/size"s, path_str)); md.blocks(*read_metadata_field<uint32_t>(inode, "/blocks"s, path_str)); bool read_all_metadata(Metadata& md, const uint64_t& inode, const bfs::path& i_path) { md.atime(*read_metadata_field<time_t>(inode, "/atime"s, i_path)); md.mtime(*read_metadata_field<time_t>(inode, "/mtime"s, i_path)); md.ctime(*read_metadata_field<time_t>(inode, "/ctime"s, i_path)); md.uid(*read_metadata_field<uint32_t>(inode, "/uid"s, i_path)); md.gid(*read_metadata_field<uint32_t>(inode, "/gid"s, i_path)); md.mode(*read_metadata_field<uint32_t>(inode, "/mode"s, i_path)); md.inode_no(*read_metadata_field<uint64_t>(inode, "/inode_no"s, i_path)); md.link_count(*read_metadata_field<uint32_t>(inode, "/link_count"s, i_path)); md.size(*read_metadata_field<uint32_t>(inode, "/size"s, i_path)); md.blocks(*read_metadata_field<uint32_t>(inode, "/blocks"s, i_path)); return true; } // TODO error handling. template<typename T> bool write_metadata_field(const T &field, const uint64_t &inode, const string &fname, const string &p) { auto i_path = p + "/" + to_string(inode); fs::create_directories(i_path); auto file = fs::path{i_path + fname}; // for some reason auto ofs = fs::ofstream(file); does not work. That is why I use the old style. bool write_metadata_field(const T& field, const unsigned long& hash, const string& fname, bfs::path path) { path.append(to_string(hash)); bfs::create_directories(path); path.append(fname); // for some reason auto ofs = bfs::ofstream(file); does not work. That is why I use the old style. // std::basic_ofstream does not encounter this problem fs::ofstream ofs{file}; bfs::ofstream ofs{path}; // write to disk in binary form boost::archive::binary_oarchive ba(ofs); ba << field; Loading @@ -57,11 +60,12 @@ bool write_metadata_field(const T &field, const uint64_t &inode, const string &f } template<typename T> unique_ptr<T> read_metadata_field(const uint64_t &inode, const string &fname, const string &p) { auto i_path = p + "/" + to_string(inode); if (!fs::exists(i_path)) return nullptr; auto file = fs::path(i_path + fname); fs::ifstream ifs{file}; unique_ptr<T> read_metadata_field(const uint64_t& inode, const string& fname, bfs::path path) { path.append(to_string(inode)); if (!bfs::exists(path)) return nullptr; path.append(fname); bfs::ifstream ifs{path}; //fast error checking //ifs.good() boost::archive::binary_iarchive ba(ifs); Loading @@ -70,4 +74,44 @@ unique_ptr<T> read_metadata_field(const uint64_t &inode, const string &fname, co return field; } // Returns the inode for given path. ENOENT if not found int read_dentry_inode(const std::string path) { return 0; } int get_metadata(Metadata& md, const std::string& path) { return get_metadata(md, bfs::path(path)); } int get_metadata(Metadata& md, const bfs::path& path) { // // TODO HOW TO DO THE LOOKUP PROPERLY? SO NO INODE TYPE CLASH // auto inode = lookup(path); // ADAFS_DATA->logger->info("get_metadata() inode: {} for path: {}", inode, path); // if (inode == -ENOENT) { // // If no inode is found lookup father path // // <lookup father here> // // If still on return inode is not found, return ENOENT // return -ENOENT; // } // auto i_path = util::adafs_fullpath(ADAFS_DATA->inode_path + "/"s + to_string(inode)); // read_all_metadata(md, inode, i_path); return -ENOENT; } //int lookup(const string& path) { // return lookup(bfs::path(path)); //} // int lookup(const bfs::path& path) { // if ("/"s.compare(path)) { // return ADAFS_ROOT_INODE; // } else { // return -ENOENT; // } return 0; } Loading
fs/src/main.cpp +55 −17 Original line number Diff line number Diff line Loading @@ -7,14 +7,30 @@ static struct fuse_operations adafs_ops; using namespace std; //std::shared_ptr<Metadata> md; int adafs_getattr(const char *path, struct stat *attr, struct fuse_file_info *fi){ auto fpath = util::adafs_fullpath("meta/inodes"s); //FUSE_UNKNOWN_INO errorcode if attr->st_ino could not be resolved by VFS (This is unverified information // but Fuse initializes it with this value initially fuse.c:3303 // if (attr->st_ino == -1) { // ADAFS_DATA->logger->info("st_ino = -1: "s + to_string(attr->st_ino)); // } else { // ADAFS_DATA->logger->info("st_ino != -1: "s + to_string(attr->st_ino)); // } // ADAFS_DATA->logger->info("adafs_getattr_enter1"s); // ADAFS_DATA->logger->info("st_ino: "s + to_string(attr->st_ino)); // ADAFS_DATA->logger->info("adafs_getattr_enter2"s); // call lookup for *path, return int (use errorcodes), put pointer to Metadata object in parameter // if exist (i.e. == 0) use Metadata object, else return ENOENT // auto path_s = bfs::path(path); // ADAFS_DATA->logger->info(path_s); // ADAFS_DATA->logger->flush(); auto md = make_shared<Metadata>(); md->mode(S_IFDIR | 0755); md->inode_no(1); read_all_metadata(*md, 1, fpath); // md->mode(S_IFDIR | 0755); // md->inode_no(1); // get_metadata(*md, path_s); // read_all_metadata(*md, 1, fpath); if (strcmp(path, "/") == 0) { attr->st_ino = md->inode_no(); attr->st_mode = md->mode(); Loading @@ -31,6 +47,15 @@ int adafs_getattr(const char *path, struct stat *attr, struct fuse_file_info *fi } if (strcmp(path, "/file") == 0) { attr->st_mode = S_IFDIR | 0755; return 0; } if (strcmp(path, "/file/file2") == 0) { auto p_dir = make_shared<struct stat>(); lstat("/", p_dir.get()); ADAFS_DATA->logger->info(p_dir->st_ino); ADAFS_DATA->logger->flush(); attr->st_mode = S_IFREG | 0755; attr->st_nlink = 1; attr->st_size = strlen("blubb"); Loading @@ -46,26 +71,35 @@ void *adafs_init(struct fuse_conn_info *conn, struct fuse_config *cfg) { // ADAFS_DATA->logger->info("gid_: {}", fuse_get_context()->gid); // ADAFS_DATA->logger->info("pid: {0:d}", fuse_get_context()->pid); // ADAFS_DATA->logger->info("rootdir: {}", ((struct adafs_data*)fuse_get_context()->private_data)->rootdir); //Initialize directory structure for metadata. //Initialize directory structure for metadata. XXX We need this later for lowlevel when we split dentry from inodes boost::filesystem::create_directories(ADAFS_DATA->rootdir + "/meta/dentries"s); boost::filesystem::create_directories(ADAFS_DATA->rootdir + "/meta/inodes"s); boost::filesystem::create_directories(ADAFS_DATA->rootdir + "/data/chunks"s); // XXX Dunno if this is of any use cfg->use_ino = 1; //Init file system configuration ADAFS_DATA->blocksize = 4096; // Init unordered_map for caching metadata that was already looked up XXX use later ADAFS_DATA->hashmap = unordered_map<string, string>(); ADAFS_DATA->hashf = hash<string>(); //Init metadata // if (get_metadata("/") == -ENOENT) { // md = make_shared<Metadata>(S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO); // auto md = make_shared<Metadata>(S_IFDIR | 0755); // } // auto s = util::adafs_fullpath("meta/inodes"); // auto md = make_shared<Metadata>(); // write_all_metadata(*md, s); // Check that root metadata exists. If not intiialize it if (get_metadata(*md, "/"s) == -ENOENT) { ADAFS_DATA->logger->info("Root metadata not found. Initializing..."s); md->init_ACM_time(); md->mode(S_IFDIR | 0755); md->uid(fuse_get_context()->uid); md->gid(fuse_get_context()->gid); md->inode_no(ADAFS_ROOT_INODE); write_all_metadata(*md, ADAFS_DATA->hashf("/"s), ADAFS_DATA->inode_path); ADAFS_DATA->logger->info("Creating Metadata object"s); } ADAFS_DATA->logger->info("Survived creating Metadata object"s); ADAFS_DATA->logger->flush(); return ADAFS_DATA; Loading @@ -89,7 +123,7 @@ int main(int argc, char *argv[]) { //Initialize the mapping of Fuse functions init_adafs_ops(&adafs_ops); // create the adafs_data object (struct) // create the private data struct auto a_data = make_shared<adafs_data>(); //set the logger and initialize it with spdlog a_data->logger = spdlog::basic_logger_mt("basic_logger", "adafs.log"); Loading @@ -98,8 +132,12 @@ int main(int argc, char *argv[]) { argv[argc-2] = argv[argc-1]; argv[argc-1] = NULL; argc--; //init fuse and give the private data for further reference. //set all paths a_data->inode_path = a_data->rootdir + "meta/inodes"s; a_data->dentry_path = a_data->rootdir + "meta/dentries"s; a_data->chunk_path = a_data->rootdir + "data/chunks"s; //print version cout << "Fuse library version: "s + to_string(FUSE_MAJOR_VERSION) + to_string(FUSE_MINOR_VERSION) << endl; //init fuse and give the private data struct for further reference. return fuse_main(argc, argv, &adafs_ops, a_data.get()); }
fs/src/main.h +20 −6 Original line number Diff line number Diff line Loading @@ -12,25 +12,39 @@ #include <string> #include <iostream> #include <cstdint> #include <unordered_map> //boost libraries #include <boost/filesystem.hpp> #include "spdlog/spdlog.h" namespace bfs = boost::filesystem; struct adafs_data { std::string rootdir; // Below paths are needed for future version when we'll get rid of path hashing. std::string inode_path; // used std::string dentry_path; // unused std::string chunk_path; // unused // Caching std::unordered_map<std::string, std::string> hashmap; std::hash<std::string> hashf; // Housekeeping std::shared_ptr<spdlog::logger> logger; std::int64_t inode_count; std::mutex inode_mutex; // Later the blocksize will likely be coupled to the chunks to allow individually big chunk sizes. int32_t blocksize; }; #define ADAFS_DATA ((struct adafs_data*) fuse_get_context()->private_data) #define ADAFS_ROOT_INODE 1 namespace util { std::string adafs_fullpath(const std::string &path); boost::filesystem::path adafs_fullpath(const std::string& path); int reset_inode_no(); Loading
fs/src/metadata.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -94,9 +94,9 @@ Metadata::Metadata() : atime_(), gid_(), mode_(), inode_no_(), link_count_(), size_(), blocks_() {} link_count_(0), size_(0), blocks_(0) {} Metadata::Metadata(mode_t mode) : atime_(), Loading
fs/src/metadata.h +2 −1 Original line number Diff line number Diff line Loading @@ -19,13 +19,14 @@ private: uint32_t size_; // size_ in bytes, might be computed instead of stored uint32_t blocks_; // allocated file system blocks_ void init_ACM_time(); public: Metadata(); Metadata(mode_t mode); void init_ACM_time(); //Getter and Setter time_t atime() const; Loading
fs/src/metadata_ops.cpp +79 −35 Original line number Diff line number Diff line Loading @@ -7,48 +7,51 @@ #include <boost/archive/binary_iarchive.hpp> #include <boost/archive/binary_oarchive.hpp> namespace fs = boost::filesystem; // TODO error handling. Each read_metadata_field should check for boolean, i.e., if I/O failed. bool write_all_metadata(const Metadata &md, const std::string &path_str) { write_metadata_field(md.atime(), md.inode_no(), "/atime"s, path_str); write_metadata_field(md.mtime(), md.inode_no(), "/mtime"s, path_str); write_metadata_field(md.ctime(), md.inode_no(), "/ctime"s, path_str); write_metadata_field(md.uid(), md.inode_no(), "/uid"s, path_str); write_metadata_field(md.gid(), md.inode_no(), "/gid"s, path_str); write_metadata_field(md.mode(), md.inode_no(), "/mode"s, path_str); write_metadata_field(md.inode_no(), md.inode_no(), "/inode_no"s, path_str); write_metadata_field(md.link_count(), md.inode_no(), "/link_count"s, path_str); write_metadata_field(md.size(), md.inode_no(), "/size"s, path_str); write_metadata_field(md.blocks(), md.inode_no(), "/blocks"s, path_str); bool write_all_metadata(const Metadata& md, const unsigned long& hash, const bfs::path& i_path) { write_metadata_field(md.atime(), hash, "/atime"s, i_path); write_metadata_field(md.mtime(), hash, "/mtime"s, i_path); write_metadata_field(md.ctime(), hash, "/ctime"s, i_path); write_metadata_field(md.uid(), hash, "/uid"s, i_path); write_metadata_field(md.gid(), hash, "/gid"s, i_path); write_metadata_field(md.mode(), hash, "/mode"s, i_path); write_metadata_field(md.inode_no(), hash, "/inode_no"s, i_path); write_metadata_field(md.link_count(), hash, "/link_count"s, i_path); write_metadata_field(md.size(), hash, "/size"s, i_path); write_metadata_field(md.blocks(), hash, "/blocks"s, i_path); return true; } bool write_all_metadata(const Metadata& md, const unsigned long& hash, const string& i_path) { return write_all_metadata(md, hash, bfs::path(i_path)); } // TODO error handling. Each read_metadata_field should check for nullptr, i.e., if I/O failed. bool read_all_metadata(Metadata &md, const uint64_t &inode, const std::string &path_str) { md.atime(*read_metadata_field<time_t>(inode, "/atime"s, path_str)); md.mtime(*read_metadata_field<time_t>(inode, "/mtime"s, path_str)); md.ctime(*read_metadata_field<time_t>(inode, "/ctime"s, path_str)); md.uid(*read_metadata_field<uint32_t>(inode, "/uid"s, path_str)); md.gid(*read_metadata_field<uint32_t>(inode, "/gid"s, path_str)); md.mode(*read_metadata_field<uint32_t>(inode, "/mode"s, path_str)); md.inode_no(*read_metadata_field<uint64_t>(inode, "/inode_no"s, path_str)); md.link_count(*read_metadata_field<uint32_t>(inode, "/link_count"s, path_str)); md.size(*read_metadata_field<uint32_t>(inode, "/size"s, path_str)); md.blocks(*read_metadata_field<uint32_t>(inode, "/blocks"s, path_str)); bool read_all_metadata(Metadata& md, const uint64_t& inode, const bfs::path& i_path) { md.atime(*read_metadata_field<time_t>(inode, "/atime"s, i_path)); md.mtime(*read_metadata_field<time_t>(inode, "/mtime"s, i_path)); md.ctime(*read_metadata_field<time_t>(inode, "/ctime"s, i_path)); md.uid(*read_metadata_field<uint32_t>(inode, "/uid"s, i_path)); md.gid(*read_metadata_field<uint32_t>(inode, "/gid"s, i_path)); md.mode(*read_metadata_field<uint32_t>(inode, "/mode"s, i_path)); md.inode_no(*read_metadata_field<uint64_t>(inode, "/inode_no"s, i_path)); md.link_count(*read_metadata_field<uint32_t>(inode, "/link_count"s, i_path)); md.size(*read_metadata_field<uint32_t>(inode, "/size"s, i_path)); md.blocks(*read_metadata_field<uint32_t>(inode, "/blocks"s, i_path)); return true; } // TODO error handling. template<typename T> bool write_metadata_field(const T &field, const uint64_t &inode, const string &fname, const string &p) { auto i_path = p + "/" + to_string(inode); fs::create_directories(i_path); auto file = fs::path{i_path + fname}; // for some reason auto ofs = fs::ofstream(file); does not work. That is why I use the old style. bool write_metadata_field(const T& field, const unsigned long& hash, const string& fname, bfs::path path) { path.append(to_string(hash)); bfs::create_directories(path); path.append(fname); // for some reason auto ofs = bfs::ofstream(file); does not work. That is why I use the old style. // std::basic_ofstream does not encounter this problem fs::ofstream ofs{file}; bfs::ofstream ofs{path}; // write to disk in binary form boost::archive::binary_oarchive ba(ofs); ba << field; Loading @@ -57,11 +60,12 @@ bool write_metadata_field(const T &field, const uint64_t &inode, const string &f } template<typename T> unique_ptr<T> read_metadata_field(const uint64_t &inode, const string &fname, const string &p) { auto i_path = p + "/" + to_string(inode); if (!fs::exists(i_path)) return nullptr; auto file = fs::path(i_path + fname); fs::ifstream ifs{file}; unique_ptr<T> read_metadata_field(const uint64_t& inode, const string& fname, bfs::path path) { path.append(to_string(inode)); if (!bfs::exists(path)) return nullptr; path.append(fname); bfs::ifstream ifs{path}; //fast error checking //ifs.good() boost::archive::binary_iarchive ba(ifs); Loading @@ -70,4 +74,44 @@ unique_ptr<T> read_metadata_field(const uint64_t &inode, const string &fname, co return field; } // Returns the inode for given path. ENOENT if not found int read_dentry_inode(const std::string path) { return 0; } int get_metadata(Metadata& md, const std::string& path) { return get_metadata(md, bfs::path(path)); } int get_metadata(Metadata& md, const bfs::path& path) { // // TODO HOW TO DO THE LOOKUP PROPERLY? SO NO INODE TYPE CLASH // auto inode = lookup(path); // ADAFS_DATA->logger->info("get_metadata() inode: {} for path: {}", inode, path); // if (inode == -ENOENT) { // // If no inode is found lookup father path // // <lookup father here> // // If still on return inode is not found, return ENOENT // return -ENOENT; // } // auto i_path = util::adafs_fullpath(ADAFS_DATA->inode_path + "/"s + to_string(inode)); // read_all_metadata(md, inode, i_path); return -ENOENT; } //int lookup(const string& path) { // return lookup(bfs::path(path)); //} // int lookup(const bfs::path& path) { // if ("/"s.compare(path)) { // return ADAFS_ROOT_INODE; // } else { // return -ENOENT; // } return 0; }