Loading lfs/src/adafs_ops/mdata_ops.cpp +53 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,59 @@ using namespace std; /** * Reads a specific metadata field from the database and puts it into the corresponding metadata object * @tparam T * @param inode * @param field * @return type, 0 might mean failure */ void read_metadata_field_md(const fuse_ino_t inode, const Md_fields field, Metadata& md) { // XXX I am sure this can be implemented in a better way switch (field) { case Md_fields::atime: md.atime(db_get_mdata<time_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::atime)>(md_field_map)))); break; case Md_fields::mtime: md.mtime(db_get_mdata<time_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::mtime)>(md_field_map)))); break; case Md_fields::ctime: md.ctime(db_get_mdata<time_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::ctime)>(md_field_map)))); break; case Md_fields::uid: md.uid(db_get_mdata<uid_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::uid)>(md_field_map)))); break; case Md_fields::gid: md.gid(db_get_mdata<gid_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::gid)>(md_field_map)))); break; case Md_fields::mode: md.mode(db_get_mdata<mode_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::mode)>(md_field_map)))); break; case Md_fields::inode_no: md.inode_no(db_get_mdata<fuse_ino_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::inode_no)>(md_field_map)))); break; case Md_fields::link_count: md.link_count(db_get_mdata<nlink_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::link_count)>(md_field_map)))); break; case Md_fields::size: md.size(db_get_mdata<off_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::size)>(md_field_map)))); break; case Md_fields::blocks: md.blocks(db_get_mdata<blkcnt_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::blocks)>(md_field_map)))); break; } } int write_all_metadata(const Metadata& md) { auto inode_key = fmt::FormatInt(md.inode_no()).str(); // TODO this should be somewhat a batch operation or similar. this errorhandling is bs Loading lfs/src/adafs_ops/mdata_ops.hpp +16 −13 Original line number Diff line number Diff line Loading @@ -14,14 +14,14 @@ using namespace std; /** * Reads a specific metadata field to the database * Reads a specific metadata field from the database and returns it * @tparam T * @param inode * @param field * @return type, 0 might mean failure */ template<typename T> decltype(auto) read_metadata_field(const fuse_ino_t inode, Md_fields field) { decltype(auto) read_metadata_field(const fuse_ino_t inode, const Md_fields field) { // XXX I am sure this can be implemented in a better way switch (field) { case Md_fields::atime: Loading Loading @@ -50,6 +50,8 @@ decltype(auto) read_metadata_field(const fuse_ino_t inode, Md_fields field) { } void read_metadata_field_md(const fuse_ino_t inode, const Md_fields field, Metadata& md); /** * writes a specific metadata field to the database * @tparam T Loading @@ -59,40 +61,41 @@ decltype(auto) read_metadata_field(const fuse_ino_t inode, Md_fields field) { * @return bool - success */ template<typename T> bool write_metadata_field(const fuse_ino_t inode, const Md_fields field, Metadata& md) { bool write_metadata_field(const fuse_ino_t inode, const Md_fields field, const T val) { // XXX I am sure this can be implemented in a better way switch (field) { case Md_fields::atime: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::atime)>(md_field_map)), md.atime()); val); case Md_fields::mtime: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::mtime)>(md_field_map)), md.mtime()); val); case Md_fields::ctime: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::ctime)>(md_field_map)), md.ctime()); val); case Md_fields::uid: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::uid)>(md_field_map)), md.uid()); val); case Md_fields::gid: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::gid)>(md_field_map)), md.gid()); val); case Md_fields::mode: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::mode)>(md_field_map)), md.mode()); val); case Md_fields::inode_no: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::inode_no)>(md_field_map)), md.inode_no()); val); case Md_fields::link_count: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::link_count)>(md_field_map)), md.link_count()); val); case Md_fields::size: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::size)>(md_field_map)), md.size()); val); case Md_fields::blocks: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::blocks)>(md_field_map)), md.blocks()); val); } return false; // never reached... compiler complains if left out } Loading lfs/src/fuse_ops/io.cpp +20 −16 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ #include "../main.hpp" #include "../fuse_ops.hpp" #include "../db/db_ops.hpp" #include "../adafs_ops/mdata_ops.hpp" using namespace std; Loading Loading @@ -50,8 +51,7 @@ void adafs_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struc char* buf = new char[size](); auto read_size = static_cast<size_t>(pread(fd, buf, size, off)); // snprintf(buf, size + 1, buf); ADAFS_DATA->spdlogger()->debug("Read the following buf {} wtf", buf); ADAFS_DATA->spdlogger()->trace("Read the following buf: {}", buf); fuse_reply_buf(req, buf, read_size); Loading Loading @@ -88,7 +88,8 @@ void adafs_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struc */ void adafs_ll_write(fuse_req_t req, fuse_ino_t ino, const char* buf, size_t size, off_t off, struct fuse_file_info* fi) { ADAFS_DATA->spdlogger()->info("adafs_ll_write() enter: inode {} size {} offset {} buf {} O_APPEND", ino, size, off, ADAFS_DATA->spdlogger()->debug("adafs_ll_write() enter: inode {} size {} offset {} buf {} O_APPEND {}", ino, size, off, buf, fi->flags & O_APPEND); // TODO Check out how splicing works. This uses the function write_buf then. auto chnk_path = bfs::path(ADAFS_DATA->chunk_path()); Loading @@ -101,20 +102,23 @@ adafs_ll_write(fuse_req_t req, fuse_ino_t ino, const char* buf, size_t size, off fuse_reply_err(req, EIO); return; } // write to disk pwrite(fd, buf, size, off); // XXX the metadata size needs to be correct in the metadata. otherwise it won't read the data... db_put_mdata(db_build_mdata_key(ino, std::get<to_underlying(Md_fields::size)>(md_field_map)), size); // Set new size of the file // if (fi->flags & O_APPEND) { // truncate(chnk_path.c_str(), md->size() + size); // md->size(md->size() + static_cast<uint32_t>(size)); // } else { // truncate(chnk_path.c_str(), size); // md->size(static_cast<uint32_t>(size)); // } close(fd); // Set new size of the file if (fi->flags & O_APPEND) { // appending requires to read the old size first so that the new size can be added to it Metadata md{}; read_metadata_field_md(ino, Md_fields::size, md); // truncating file truncate(chnk_path.c_str(), md.size() + size); // refresh metadata size field write_metadata_field(ino, Md_fields::size, md.size() + static_cast<off_t>(size)); } else { truncate(chnk_path.c_str(), size); write_metadata_field(ino, Md_fields::size, static_cast<off_t>(size)); } fuse_reply_write(req, size); close(fd); } Loading
lfs/src/adafs_ops/mdata_ops.cpp +53 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,59 @@ using namespace std; /** * Reads a specific metadata field from the database and puts it into the corresponding metadata object * @tparam T * @param inode * @param field * @return type, 0 might mean failure */ void read_metadata_field_md(const fuse_ino_t inode, const Md_fields field, Metadata& md) { // XXX I am sure this can be implemented in a better way switch (field) { case Md_fields::atime: md.atime(db_get_mdata<time_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::atime)>(md_field_map)))); break; case Md_fields::mtime: md.mtime(db_get_mdata<time_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::mtime)>(md_field_map)))); break; case Md_fields::ctime: md.ctime(db_get_mdata<time_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::ctime)>(md_field_map)))); break; case Md_fields::uid: md.uid(db_get_mdata<uid_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::uid)>(md_field_map)))); break; case Md_fields::gid: md.gid(db_get_mdata<gid_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::gid)>(md_field_map)))); break; case Md_fields::mode: md.mode(db_get_mdata<mode_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::mode)>(md_field_map)))); break; case Md_fields::inode_no: md.inode_no(db_get_mdata<fuse_ino_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::inode_no)>(md_field_map)))); break; case Md_fields::link_count: md.link_count(db_get_mdata<nlink_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::link_count)>(md_field_map)))); break; case Md_fields::size: md.size(db_get_mdata<off_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::size)>(md_field_map)))); break; case Md_fields::blocks: md.blocks(db_get_mdata<blkcnt_t>( db_build_mdata_key(inode, std::get<to_underlying(Md_fields::blocks)>(md_field_map)))); break; } } int write_all_metadata(const Metadata& md) { auto inode_key = fmt::FormatInt(md.inode_no()).str(); // TODO this should be somewhat a batch operation or similar. this errorhandling is bs Loading
lfs/src/adafs_ops/mdata_ops.hpp +16 −13 Original line number Diff line number Diff line Loading @@ -14,14 +14,14 @@ using namespace std; /** * Reads a specific metadata field to the database * Reads a specific metadata field from the database and returns it * @tparam T * @param inode * @param field * @return type, 0 might mean failure */ template<typename T> decltype(auto) read_metadata_field(const fuse_ino_t inode, Md_fields field) { decltype(auto) read_metadata_field(const fuse_ino_t inode, const Md_fields field) { // XXX I am sure this can be implemented in a better way switch (field) { case Md_fields::atime: Loading Loading @@ -50,6 +50,8 @@ decltype(auto) read_metadata_field(const fuse_ino_t inode, Md_fields field) { } void read_metadata_field_md(const fuse_ino_t inode, const Md_fields field, Metadata& md); /** * writes a specific metadata field to the database * @tparam T Loading @@ -59,40 +61,41 @@ decltype(auto) read_metadata_field(const fuse_ino_t inode, Md_fields field) { * @return bool - success */ template<typename T> bool write_metadata_field(const fuse_ino_t inode, const Md_fields field, Metadata& md) { bool write_metadata_field(const fuse_ino_t inode, const Md_fields field, const T val) { // XXX I am sure this can be implemented in a better way switch (field) { case Md_fields::atime: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::atime)>(md_field_map)), md.atime()); val); case Md_fields::mtime: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::mtime)>(md_field_map)), md.mtime()); val); case Md_fields::ctime: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::ctime)>(md_field_map)), md.ctime()); val); case Md_fields::uid: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::uid)>(md_field_map)), md.uid()); val); case Md_fields::gid: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::gid)>(md_field_map)), md.gid()); val); case Md_fields::mode: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::mode)>(md_field_map)), md.mode()); val); case Md_fields::inode_no: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::inode_no)>(md_field_map)), md.inode_no()); val); case Md_fields::link_count: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::link_count)>(md_field_map)), md.link_count()); val); case Md_fields::size: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::size)>(md_field_map)), md.size()); val); case Md_fields::blocks: return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::blocks)>(md_field_map)), md.blocks()); val); } return false; // never reached... compiler complains if left out } Loading
lfs/src/fuse_ops/io.cpp +20 −16 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ #include "../main.hpp" #include "../fuse_ops.hpp" #include "../db/db_ops.hpp" #include "../adafs_ops/mdata_ops.hpp" using namespace std; Loading Loading @@ -50,8 +51,7 @@ void adafs_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struc char* buf = new char[size](); auto read_size = static_cast<size_t>(pread(fd, buf, size, off)); // snprintf(buf, size + 1, buf); ADAFS_DATA->spdlogger()->debug("Read the following buf {} wtf", buf); ADAFS_DATA->spdlogger()->trace("Read the following buf: {}", buf); fuse_reply_buf(req, buf, read_size); Loading Loading @@ -88,7 +88,8 @@ void adafs_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struc */ void adafs_ll_write(fuse_req_t req, fuse_ino_t ino, const char* buf, size_t size, off_t off, struct fuse_file_info* fi) { ADAFS_DATA->spdlogger()->info("adafs_ll_write() enter: inode {} size {} offset {} buf {} O_APPEND", ino, size, off, ADAFS_DATA->spdlogger()->debug("adafs_ll_write() enter: inode {} size {} offset {} buf {} O_APPEND {}", ino, size, off, buf, fi->flags & O_APPEND); // TODO Check out how splicing works. This uses the function write_buf then. auto chnk_path = bfs::path(ADAFS_DATA->chunk_path()); Loading @@ -101,20 +102,23 @@ adafs_ll_write(fuse_req_t req, fuse_ino_t ino, const char* buf, size_t size, off fuse_reply_err(req, EIO); return; } // write to disk pwrite(fd, buf, size, off); // XXX the metadata size needs to be correct in the metadata. otherwise it won't read the data... db_put_mdata(db_build_mdata_key(ino, std::get<to_underlying(Md_fields::size)>(md_field_map)), size); // Set new size of the file // if (fi->flags & O_APPEND) { // truncate(chnk_path.c_str(), md->size() + size); // md->size(md->size() + static_cast<uint32_t>(size)); // } else { // truncate(chnk_path.c_str(), size); // md->size(static_cast<uint32_t>(size)); // } close(fd); // Set new size of the file if (fi->flags & O_APPEND) { // appending requires to read the old size first so that the new size can be added to it Metadata md{}; read_metadata_field_md(ino, Md_fields::size, md); // truncating file truncate(chnk_path.c_str(), md.size() + size); // refresh metadata size field write_metadata_field(ino, Md_fields::size, md.size() + static_cast<off_t>(size)); } else { truncate(chnk_path.c_str(), size); write_metadata_field(ino, Md_fields::size, static_cast<off_t>(size)); } fuse_reply_write(req, size); close(fd); }