Loading fs/src/fuse_ops/directory.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,9 @@ int adafs_opendir(const char* p, struct fuse_file_info* fi) { int adafs_readdir(const char* p, void* buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info* fi, enum fuse_readdir_flags flags) { ADAFS_DATA->logger->debug("FUSE: adafs_readdir() enter"s); // XXX ls also reports the number of allocated blocks IN the directory. Non recursive. Currently not considered auto path = bfs::path(p); auto md = make_shared<Metadata>(); // first check that dir exists that is trying to be read. I don't know if this is actually needed, Loading @@ -72,6 +75,9 @@ int adafs_readdir(const char* p, void* buf, fuse_fill_dir_t filler, off_t offset if (read_dentries(*dentries, ADAFS_DATA->hashf(path.string())) != 0) return 1; // XXX problemo dedected deal with it later (I mean me) // visualizing current and parent dir filler(buf, ".", NULL, 0, FUSE_FILL_DIR_PLUS); filler(buf, "..", NULL, 0, FUSE_FILL_DIR_PLUS); for (auto& dentry : *dentries) { // XXX I have no idea what the last parameter really does... filler(buf, dentry.c_str(), NULL, 0, FUSE_FILL_DIR_PLUS); Loading fs/src/fuse_ops/file.cpp +24 −1 Original line number Diff line number Diff line Loading @@ -4,11 +4,19 @@ #include "../main.h" #include "../fuse_ops.h" #include "../metadata.h" #include "../metadata_ops.h" using namespace std; /** Get file attributes. * * Similar to stat(). The 'st_dev' and 'st_blksize' fields are * ignored. The 'st_ino' field is ignored except if the 'use_ino' * mount option is given. * * `fi` will always be NULL if the file is not currenly open, but * may also be NULL if the file is open. */ int adafs_getattr(const char* p, struct stat* attr, struct fuse_file_info* fi) { auto path = bfs::path(p); Loading Loading @@ -56,7 +64,20 @@ int adafs_getattr(const char* p, struct stat* attr, struct fuse_file_info* fi) { */ int adafs_mknod(const char* p, mode_t mode, dev_t dev) { ADAFS_DATA->logger->debug("FUSE: adafs_readdir() enter"s); // XXX Errorhandling and beware of transactions. saving dentry and metadata have to be atomic auto path = bfs::path(p); // XXX check if file exists (how can we omit this? Let's just try to create it and see if it fails) // XXX check permissions (omittable) // XXX create directory entry (can fail) create_dentry(ADAFS_DATA->hashf(path.parent_path().string()), path.filename().string()); // XXX create metadata of new file // mode is used here to init metadata auto md = make_unique<Metadata>(mode); write_all_metadata(*md, ADAFS_DATA->hashf(path.string())); return 0; } Loading @@ -77,6 +98,7 @@ int adafs_mknod(const char* p, mode_t mode, dev_t dev) { * passed to all file operations. */ int adafs_open(const char* p, struct fuse_file_info* ffi) { // XXX ignored for now. Will be similar to opendir. Implement when implementing I/O return 0; } Loading @@ -93,5 +115,6 @@ int adafs_open(const char* p, struct fuse_file_info* ffi) { * See the utimensat(2) man page for details. */ int adafs_utimens(const char* p, const struct timespec tv[2], struct fuse_file_info* fi) { // XXX ignored for now. Later: Make it configurable return 0; } fs/src/fuse_ops/sync.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,27 @@ #include "../main.h" #include "../fuse_ops.h" /** Possibly flush cached data * * BIG NOTE: This is not equivalent to fsync(). It's not a * request to sync dirty data. * * Flush is called on each close() of a file descriptor. So if a * filesystem wants to return write errors in close() and the file * has cached dirty data, this is a good place to write back data * and return any errors. Since many applications ignore close() * errors this is not always useful. * * NOTE: The flush() method may be called more than once for each * open(). This happens if more than one file descriptor refers * to an opened file due to dup(), dup2() or fork() calls. It is * not possible to determine if a flush is final, so each flush * should be treated equally. Multiple write-flush sequences are * relatively rare, so this shouldn't be a problem. * * Filesystems shouldn't assume that flush will always be called * after some writes, or that if will be called at all. */ int adafs_flush(const char*, struct fuse_file_info*) { return 0; } fs/src/main.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -39,8 +39,10 @@ void *adafs_init(struct fuse_conn_info *conn, struct fuse_config *cfg) { ADAFS_DATA->logger->debug("Root metadata not found. Initializing..."s); md->init_ACM_time(); md->mode(S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO); // chmod 777 md->size(4096); // XXX just visual. size computation of directory should be done properly at some point // md->mode(S_IFDIR | 0755); // XXX The gid and uid is the root user for some reason. Should be the user that mounted fuse. // This is because fuse is mounted through root although it was triggered by the user md->uid(fuse_get_context()->uid); md->gid(fuse_get_context()->gid); md->inode_no(ADAFS_ROOT_INODE); Loading fs/src/metadata_ops.cpp +21 −2 Original line number Diff line number Diff line Loading @@ -94,7 +94,7 @@ int get_metadata(Metadata& md, const bfs::path& path) { * Reads all directory entries in a directory with a given @hash. Returns 0 if successful. * @dir is assumed to be empty */ int read_dentries(vector<string> dir, const unsigned long hash) { int read_dentries(vector<string>& dir, const unsigned long hash) { auto path = bfs::path(ADAFS_DATA->dentry_path); path /= to_string(hash); if (!bfs::exists(path)) return 1; Loading @@ -105,11 +105,30 @@ int read_dentries(vector<string> dir, const unsigned long hash) { bfs::directory_iterator end_dir_it; for (bfs::directory_iterator dir_it(path); dir_it != end_dir_it; ++dir_it) { const bfs::path cp = (*dir_it); dir.push_back(cp.string()); dir.push_back(cp.filename().string()); } return 0; } /** * Creates an empty file in the dentry folder of the parent directory, acting as a dentry for lookup * @param parent_dir * @param fname * @return */ int create_dentry(const unsigned long parent_dir_hash, const string& fname) { // XXX Errorhandling auto f_path = bfs::path(ADAFS_DATA->dentry_path); f_path /= to_string(parent_dir_hash); if (!bfs::exists(f_path)) return 1; f_path /= fname; bfs::ofstream ofs{f_path}; // XXX make sure the file has been created return 0; } Loading Loading
fs/src/fuse_ops/directory.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,9 @@ int adafs_opendir(const char* p, struct fuse_file_info* fi) { int adafs_readdir(const char* p, void* buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info* fi, enum fuse_readdir_flags flags) { ADAFS_DATA->logger->debug("FUSE: adafs_readdir() enter"s); // XXX ls also reports the number of allocated blocks IN the directory. Non recursive. Currently not considered auto path = bfs::path(p); auto md = make_shared<Metadata>(); // first check that dir exists that is trying to be read. I don't know if this is actually needed, Loading @@ -72,6 +75,9 @@ int adafs_readdir(const char* p, void* buf, fuse_fill_dir_t filler, off_t offset if (read_dentries(*dentries, ADAFS_DATA->hashf(path.string())) != 0) return 1; // XXX problemo dedected deal with it later (I mean me) // visualizing current and parent dir filler(buf, ".", NULL, 0, FUSE_FILL_DIR_PLUS); filler(buf, "..", NULL, 0, FUSE_FILL_DIR_PLUS); for (auto& dentry : *dentries) { // XXX I have no idea what the last parameter really does... filler(buf, dentry.c_str(), NULL, 0, FUSE_FILL_DIR_PLUS); Loading
fs/src/fuse_ops/file.cpp +24 −1 Original line number Diff line number Diff line Loading @@ -4,11 +4,19 @@ #include "../main.h" #include "../fuse_ops.h" #include "../metadata.h" #include "../metadata_ops.h" using namespace std; /** Get file attributes. * * Similar to stat(). The 'st_dev' and 'st_blksize' fields are * ignored. The 'st_ino' field is ignored except if the 'use_ino' * mount option is given. * * `fi` will always be NULL if the file is not currenly open, but * may also be NULL if the file is open. */ int adafs_getattr(const char* p, struct stat* attr, struct fuse_file_info* fi) { auto path = bfs::path(p); Loading Loading @@ -56,7 +64,20 @@ int adafs_getattr(const char* p, struct stat* attr, struct fuse_file_info* fi) { */ int adafs_mknod(const char* p, mode_t mode, dev_t dev) { ADAFS_DATA->logger->debug("FUSE: adafs_readdir() enter"s); // XXX Errorhandling and beware of transactions. saving dentry and metadata have to be atomic auto path = bfs::path(p); // XXX check if file exists (how can we omit this? Let's just try to create it and see if it fails) // XXX check permissions (omittable) // XXX create directory entry (can fail) create_dentry(ADAFS_DATA->hashf(path.parent_path().string()), path.filename().string()); // XXX create metadata of new file // mode is used here to init metadata auto md = make_unique<Metadata>(mode); write_all_metadata(*md, ADAFS_DATA->hashf(path.string())); return 0; } Loading @@ -77,6 +98,7 @@ int adafs_mknod(const char* p, mode_t mode, dev_t dev) { * passed to all file operations. */ int adafs_open(const char* p, struct fuse_file_info* ffi) { // XXX ignored for now. Will be similar to opendir. Implement when implementing I/O return 0; } Loading @@ -93,5 +115,6 @@ int adafs_open(const char* p, struct fuse_file_info* ffi) { * See the utimensat(2) man page for details. */ int adafs_utimens(const char* p, const struct timespec tv[2], struct fuse_file_info* fi) { // XXX ignored for now. Later: Make it configurable return 0; }
fs/src/fuse_ops/sync.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,27 @@ #include "../main.h" #include "../fuse_ops.h" /** Possibly flush cached data * * BIG NOTE: This is not equivalent to fsync(). It's not a * request to sync dirty data. * * Flush is called on each close() of a file descriptor. So if a * filesystem wants to return write errors in close() and the file * has cached dirty data, this is a good place to write back data * and return any errors. Since many applications ignore close() * errors this is not always useful. * * NOTE: The flush() method may be called more than once for each * open(). This happens if more than one file descriptor refers * to an opened file due to dup(), dup2() or fork() calls. It is * not possible to determine if a flush is final, so each flush * should be treated equally. Multiple write-flush sequences are * relatively rare, so this shouldn't be a problem. * * Filesystems shouldn't assume that flush will always be called * after some writes, or that if will be called at all. */ int adafs_flush(const char*, struct fuse_file_info*) { return 0; }
fs/src/main.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -39,8 +39,10 @@ void *adafs_init(struct fuse_conn_info *conn, struct fuse_config *cfg) { ADAFS_DATA->logger->debug("Root metadata not found. Initializing..."s); md->init_ACM_time(); md->mode(S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO); // chmod 777 md->size(4096); // XXX just visual. size computation of directory should be done properly at some point // md->mode(S_IFDIR | 0755); // XXX The gid and uid is the root user for some reason. Should be the user that mounted fuse. // This is because fuse is mounted through root although it was triggered by the user md->uid(fuse_get_context()->uid); md->gid(fuse_get_context()->gid); md->inode_no(ADAFS_ROOT_INODE); Loading
fs/src/metadata_ops.cpp +21 −2 Original line number Diff line number Diff line Loading @@ -94,7 +94,7 @@ int get_metadata(Metadata& md, const bfs::path& path) { * Reads all directory entries in a directory with a given @hash. Returns 0 if successful. * @dir is assumed to be empty */ int read_dentries(vector<string> dir, const unsigned long hash) { int read_dentries(vector<string>& dir, const unsigned long hash) { auto path = bfs::path(ADAFS_DATA->dentry_path); path /= to_string(hash); if (!bfs::exists(path)) return 1; Loading @@ -105,11 +105,30 @@ int read_dentries(vector<string> dir, const unsigned long hash) { bfs::directory_iterator end_dir_it; for (bfs::directory_iterator dir_it(path); dir_it != end_dir_it; ++dir_it) { const bfs::path cp = (*dir_it); dir.push_back(cp.string()); dir.push_back(cp.filename().string()); } return 0; } /** * Creates an empty file in the dentry folder of the parent directory, acting as a dentry for lookup * @param parent_dir * @param fname * @return */ int create_dentry(const unsigned long parent_dir_hash, const string& fname) { // XXX Errorhandling auto f_path = bfs::path(ADAFS_DATA->dentry_path); f_path /= to_string(parent_dir_hash); if (!bfs::exists(f_path)) return 1; f_path /= fname; bfs::ofstream ofs{f_path}; // XXX make sure the file has been created return 0; } Loading