Loading include/client/adafs_functions.hpp +4 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,10 @@ int getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count); int getdents64(unsigned int fd, struct linux_dirent64 *dirp, unsigned int count); int adafs_rmdir(const std::string& path); #endif //IFS_ADAFS_FUNCTIONS_HPP include/client/hooks.hpp +1 −1 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ #include <fcntl.h> #include <sys/types.h> int hook_openat(int dirfd, const char *cpath, int flags, mode_t mode); int hook_close(int fd); int hook_stat(const char* path, struct stat* buf); Loading @@ -42,6 +41,7 @@ int hook_dup(unsigned int fd); int hook_dup2(unsigned int oldfd, unsigned int newfd); int hook_dup3(unsigned int oldfd, unsigned int newfd, int flags); int hook_getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count); int hook_getdents64(unsigned int fd, struct linux_dirent64 *dirp, unsigned int count); int hook_mkdirat(int dirfd, const char * cpath, mode_t mode); int hook_fchmodat(int dirfd, const char* path, mode_t mode); int hook_fchmod(unsigned int dirfd, mode_t mode); Loading src/client/adafs_functions.cpp +61 −2 Original line number Diff line number Diff line Loading @@ -23,8 +23,6 @@ #include <client/rpc/ld_rpc_data_ws.hpp> #include <client/open_dir.hpp> #include <dirent.h> #define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) #define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1) Loading @@ -37,6 +35,14 @@ struct linux_dirent { char d_name[1]; }; struct linux_dirent64 { unsigned long long d_ino; unsigned long long d_off; unsigned short d_reclen; unsigned char d_type; char d_name[1]; }; using namespace std; int adafs_open(const std::string& path, mode_t mode, int flags) { Loading Loading @@ -572,6 +578,59 @@ int getdents(unsigned int fd, return written; } int getdents64(unsigned int fd, struct linux_dirent64 *dirp, unsigned int count) { CTX->log()->trace("{}() called on fd: {}, count {}", __func__, fd, count); auto open_dir = CTX->file_map()->get_dir(fd); if(open_dir == nullptr){ //Cast did not succeeded: open_file is a regular file errno = EBADF; return -1; } auto pos = open_dir->pos(); if (pos >= open_dir->size()) { return 0; } unsigned int written = 0; struct linux_dirent64 * current_dirp = nullptr; while(pos < open_dir->size()) { DirEntry de = open_dir->getdent(pos); auto total_size = ALIGN(offsetof(struct linux_dirent64, d_name) + de.name().size() + 3, sizeof(long)); if (total_size > (count - written)) { //no enough space left on user buffer to insert next dirent break; } current_dirp = reinterpret_cast<struct linux_dirent64 *>( reinterpret_cast<char*>(dirp) + written); current_dirp->d_ino = std::hash<std::string>()( open_dir->path() + "/" + de.name()); current_dirp->d_reclen = total_size; current_dirp->d_type = ((de.type() == FileType::regular)? DT_REG : DT_DIR); CTX->log()->trace("{}() name {}: {}", __func__, pos, de.name()); std::strcpy(&(current_dirp->d_name[0]), de.name().c_str()); ++pos; current_dirp->d_off = pos; written += total_size; } if (written == 0) { errno = EINVAL; return -1; } open_dir->pos(pos); return written; } #ifdef HAS_SYMLINKS int adafs_mk_symlink(const std::string& path, const std::string& target_path) { Loading src/client/hooks.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -347,6 +347,16 @@ int hook_getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count return syscall_no_intercept(SYS_getdents, fd, dirp, count); } int hook_getdents64(unsigned int fd, struct linux_dirent64 *dirp, unsigned int count) { CTX->log()->trace("{}() called with fd {}, count {}", __func__, fd, count); if (CTX->file_map()->exist(fd)) { return with_errno(getdents64(fd, dirp, count)); } return syscall_no_intercept(SYS_getdents64, fd, dirp, count); } int hook_mkdirat(int dirfd, const char * cpath, mode_t mode) { CTX->log()->trace("{}() called with fd: {}, path: {}, mode: {}", __func__, dirfd, cpath, mode); Loading src/client/intercept.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -201,6 +201,13 @@ static inline int hook(long syscall_number, static_cast<unsigned int>(arg2)); break; case SYS_getdents64: *result = hook_getdents64(static_cast<unsigned int>(arg0), reinterpret_cast<struct linux_dirent64 *>(arg1), static_cast<unsigned int>(arg2)); break; case SYS_mkdirat: *result = hook_mkdirat(static_cast<unsigned int>(arg0), reinterpret_cast<const char *>(arg1), Loading Loading
include/client/adafs_functions.hpp +4 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,10 @@ int getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count); int getdents64(unsigned int fd, struct linux_dirent64 *dirp, unsigned int count); int adafs_rmdir(const std::string& path); #endif //IFS_ADAFS_FUNCTIONS_HPP
include/client/hooks.hpp +1 −1 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ #include <fcntl.h> #include <sys/types.h> int hook_openat(int dirfd, const char *cpath, int flags, mode_t mode); int hook_close(int fd); int hook_stat(const char* path, struct stat* buf); Loading @@ -42,6 +41,7 @@ int hook_dup(unsigned int fd); int hook_dup2(unsigned int oldfd, unsigned int newfd); int hook_dup3(unsigned int oldfd, unsigned int newfd, int flags); int hook_getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count); int hook_getdents64(unsigned int fd, struct linux_dirent64 *dirp, unsigned int count); int hook_mkdirat(int dirfd, const char * cpath, mode_t mode); int hook_fchmodat(int dirfd, const char* path, mode_t mode); int hook_fchmod(unsigned int dirfd, mode_t mode); Loading
src/client/adafs_functions.cpp +61 −2 Original line number Diff line number Diff line Loading @@ -23,8 +23,6 @@ #include <client/rpc/ld_rpc_data_ws.hpp> #include <client/open_dir.hpp> #include <dirent.h> #define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) #define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1) Loading @@ -37,6 +35,14 @@ struct linux_dirent { char d_name[1]; }; struct linux_dirent64 { unsigned long long d_ino; unsigned long long d_off; unsigned short d_reclen; unsigned char d_type; char d_name[1]; }; using namespace std; int adafs_open(const std::string& path, mode_t mode, int flags) { Loading Loading @@ -572,6 +578,59 @@ int getdents(unsigned int fd, return written; } int getdents64(unsigned int fd, struct linux_dirent64 *dirp, unsigned int count) { CTX->log()->trace("{}() called on fd: {}, count {}", __func__, fd, count); auto open_dir = CTX->file_map()->get_dir(fd); if(open_dir == nullptr){ //Cast did not succeeded: open_file is a regular file errno = EBADF; return -1; } auto pos = open_dir->pos(); if (pos >= open_dir->size()) { return 0; } unsigned int written = 0; struct linux_dirent64 * current_dirp = nullptr; while(pos < open_dir->size()) { DirEntry de = open_dir->getdent(pos); auto total_size = ALIGN(offsetof(struct linux_dirent64, d_name) + de.name().size() + 3, sizeof(long)); if (total_size > (count - written)) { //no enough space left on user buffer to insert next dirent break; } current_dirp = reinterpret_cast<struct linux_dirent64 *>( reinterpret_cast<char*>(dirp) + written); current_dirp->d_ino = std::hash<std::string>()( open_dir->path() + "/" + de.name()); current_dirp->d_reclen = total_size; current_dirp->d_type = ((de.type() == FileType::regular)? DT_REG : DT_DIR); CTX->log()->trace("{}() name {}: {}", __func__, pos, de.name()); std::strcpy(&(current_dirp->d_name[0]), de.name().c_str()); ++pos; current_dirp->d_off = pos; written += total_size; } if (written == 0) { errno = EINVAL; return -1; } open_dir->pos(pos); return written; } #ifdef HAS_SYMLINKS int adafs_mk_symlink(const std::string& path, const std::string& target_path) { Loading
src/client/hooks.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -347,6 +347,16 @@ int hook_getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count return syscall_no_intercept(SYS_getdents, fd, dirp, count); } int hook_getdents64(unsigned int fd, struct linux_dirent64 *dirp, unsigned int count) { CTX->log()->trace("{}() called with fd {}, count {}", __func__, fd, count); if (CTX->file_map()->exist(fd)) { return with_errno(getdents64(fd, dirp, count)); } return syscall_no_intercept(SYS_getdents64, fd, dirp, count); } int hook_mkdirat(int dirfd, const char * cpath, mode_t mode) { CTX->log()->trace("{}() called with fd: {}, path: {}, mode: {}", __func__, dirfd, cpath, mode); Loading
src/client/intercept.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -201,6 +201,13 @@ static inline int hook(long syscall_number, static_cast<unsigned int>(arg2)); break; case SYS_getdents64: *result = hook_getdents64(static_cast<unsigned int>(arg0), reinterpret_cast<struct linux_dirent64 *>(arg1), static_cast<unsigned int>(arg2)); break; case SYS_mkdirat: *result = hook_mkdirat(static_cast<unsigned int>(arg0), reinterpret_cast<const char *>(arg1), Loading