Loading include/client/gkfs_functions.hpp +8 −0 Original line number Original line Diff line number Diff line Loading @@ -31,10 +31,18 @@ int gkfs_create(const std::string& path, mode_t mode); int gkfs_remove(const std::string& path); int gkfs_remove(const std::string& path); // Implementation of access, // Follow links is true by default int gkfs_access(const std::string& path, int mask, bool follow_links = true); int gkfs_access(const std::string& path, int mask, bool follow_links = true); // Implementation of stat, // Follow links is true by default int gkfs_stat(const std::string& path, struct stat* buf, bool follow_links = true); int gkfs_stat(const std::string& path, struct stat* buf, bool follow_links = true); // Implementation of statx, it uses the normal stat and maps the information to the statx structure // Follow links is true by default int gkfs_statx(int dirfd, const std::string& path, int flags, unsigned int mask,struct statx* buf, bool follow_links = true ); int gkfs_statfs(struct statfs* buf); int gkfs_statfs(struct statfs* buf); int gkfs_statvfs(struct statvfs* buf); int gkfs_statvfs(struct statvfs* buf); Loading include/client/hooks.hpp +2 −0 Original line number Original line Diff line number Diff line Loading @@ -30,6 +30,8 @@ int hook_close(int fd); int hook_stat(const char* path, struct stat* buf); int hook_stat(const char* path, struct stat* buf); int hook_statx(int dirfd, const char* path, int flags, unsigned int mask,struct statx* buf); int hook_lstat(const char* path, struct stat* buf); int hook_lstat(const char* path, struct stat* buf); int hook_fstat(unsigned int fd, struct stat* buf); int hook_fstat(unsigned int fd, struct stat* buf); Loading src/client/gkfs_functions.cpp +37 −1 Original line number Original line Diff line number Diff line Loading @@ -59,7 +59,6 @@ struct linux_dirent64 { char d_name[1]; // originally `char d_name[0]` in kernel, but ISO C++ forbids zero-size array 'd_name' char d_name[1]; // originally `char d_name[0]` in kernel, but ISO C++ forbids zero-size array 'd_name' }; }; namespace { namespace { int check_parent_dir(const std::string& path) { int check_parent_dir(const std::string& path) { Loading Loading @@ -233,6 +232,43 @@ int gkfs_stat(const string& path, struct stat* buf, bool follow_links) { return 0; return 0; } } int gkfs_statx(int dirfs, const std::string& path, int flags, unsigned int mask, struct statx* buf, bool follow_links) { auto md = gkfs::util::get_metadata(path, follow_links); if (!md) { return -1; } struct stat tmp{}; gkfs::util::metadata_to_stat(path, *md, tmp); buf->stx_mask = 0; buf->stx_blksize = tmp.st_blksize; buf->stx_attributes = 0; buf->stx_nlink = tmp.st_nlink; buf->stx_uid = tmp.st_uid; buf->stx_gid = tmp.st_gid; buf->stx_mode = tmp.st_mode; buf->stx_ino = tmp.st_ino; buf->stx_size = tmp.st_size; buf->stx_blocks = tmp.st_blocks; buf->stx_attributes_mask = 0; buf->stx_atime.tv_sec = tmp.st_atim.tv_sec; buf->stx_atime.tv_nsec = tmp.st_atim.tv_nsec; buf->stx_mtime.tv_sec = tmp.st_mtim.tv_sec; buf->stx_mtime.tv_nsec = tmp.st_mtim.tv_nsec; buf->stx_ctime.tv_sec = tmp.st_ctim.tv_sec; buf->stx_ctime.tv_nsec = tmp.st_ctim.tv_nsec; buf->stx_btime = buf->stx_atime; return 0; } int gkfs_statfs(struct statfs* buf) { int gkfs_statfs(struct statfs* buf) { auto blk_stat = gkfs::rpc::forward_get_chunk_stat(); auto blk_stat = gkfs::rpc::forward_get_chunk_stat(); buf->f_type = 0; buf->f_type = 0; Loading src/client/hooks.cpp +33 −0 Original line number Original line Diff line number Diff line Loading @@ -98,6 +98,39 @@ int hook_stat(const char* path, struct stat* buf) { return syscall_no_intercept(SYS_stat, rel_path.c_str(), buf); return syscall_no_intercept(SYS_stat, rel_path.c_str(), buf); } } int hook_statx(int dirfd, const char* path, int flags, unsigned int mask, struct ::statx* buf) { LOG(DEBUG, "{}() called with dirfd: '{}', path: \"{}\", flags: '{}', mask: '{}', buf: '{}'", __func__, dirfd, path, flags, mask, fmt::ptr(buf)); std::string resolved; auto rstatus = CTX->relativize_fd_path(dirfd, path, resolved); switch (rstatus) { case gkfs::preload::RelativizeStatus::fd_unknown: return syscall_no_intercept(SYS_statx, dirfd, path, flags, mask, buf); case gkfs::preload::RelativizeStatus::external: return syscall_no_intercept(SYS_statx, dirfd, resolved.c_str(), flags, mask, buf); case gkfs::preload::RelativizeStatus::fd_not_a_dir: return -ENOTDIR; case gkfs::preload::RelativizeStatus::internal: return with_errno(gkfs::syscall::gkfs_statx(dirfd, resolved.c_str() , flags, mask, buf)); default: LOG(ERROR, "{}() relativize status unknown: {}", __func__); return -EINVAL; } return syscall_no_intercept(SYS_statx, dirfd, path, flags, mask, buf); } int hook_lstat(const char* path, struct stat* buf) { int hook_lstat(const char* path, struct stat* buf) { LOG(DEBUG, "{}() called with path: \"{}\", buf: {}", LOG(DEBUG, "{}() called with path: \"{}\", buf: {}", Loading src/client/intercept.cpp +11 −1 Original line number Original line Diff line number Diff line Loading @@ -466,6 +466,16 @@ int hook(long syscall_number, reinterpret_cast<struct stat*>(arg1)); reinterpret_cast<struct stat*>(arg1)); break; break; #ifdef SYS_statx case SYS_statx: *result = gkfs::hook::hook_statx(static_cast<int>(arg0), reinterpret_cast<char*>(arg1), static_cast<int>(arg2), static_cast<unsigned int>(arg3), reinterpret_cast<struct statx*>(arg4)); break; #endif case SYS_lstat: case SYS_lstat: *result = gkfs::hook::hook_lstat(reinterpret_cast<char*>(arg0), *result = gkfs::hook::hook_lstat(reinterpret_cast<char*>(arg0), reinterpret_cast<struct stat*>(arg1)); reinterpret_cast<struct stat*>(arg1)); Loading Loading
include/client/gkfs_functions.hpp +8 −0 Original line number Original line Diff line number Diff line Loading @@ -31,10 +31,18 @@ int gkfs_create(const std::string& path, mode_t mode); int gkfs_remove(const std::string& path); int gkfs_remove(const std::string& path); // Implementation of access, // Follow links is true by default int gkfs_access(const std::string& path, int mask, bool follow_links = true); int gkfs_access(const std::string& path, int mask, bool follow_links = true); // Implementation of stat, // Follow links is true by default int gkfs_stat(const std::string& path, struct stat* buf, bool follow_links = true); int gkfs_stat(const std::string& path, struct stat* buf, bool follow_links = true); // Implementation of statx, it uses the normal stat and maps the information to the statx structure // Follow links is true by default int gkfs_statx(int dirfd, const std::string& path, int flags, unsigned int mask,struct statx* buf, bool follow_links = true ); int gkfs_statfs(struct statfs* buf); int gkfs_statfs(struct statfs* buf); int gkfs_statvfs(struct statvfs* buf); int gkfs_statvfs(struct statvfs* buf); Loading
include/client/hooks.hpp +2 −0 Original line number Original line Diff line number Diff line Loading @@ -30,6 +30,8 @@ int hook_close(int fd); int hook_stat(const char* path, struct stat* buf); int hook_stat(const char* path, struct stat* buf); int hook_statx(int dirfd, const char* path, int flags, unsigned int mask,struct statx* buf); int hook_lstat(const char* path, struct stat* buf); int hook_lstat(const char* path, struct stat* buf); int hook_fstat(unsigned int fd, struct stat* buf); int hook_fstat(unsigned int fd, struct stat* buf); Loading
src/client/gkfs_functions.cpp +37 −1 Original line number Original line Diff line number Diff line Loading @@ -59,7 +59,6 @@ struct linux_dirent64 { char d_name[1]; // originally `char d_name[0]` in kernel, but ISO C++ forbids zero-size array 'd_name' char d_name[1]; // originally `char d_name[0]` in kernel, but ISO C++ forbids zero-size array 'd_name' }; }; namespace { namespace { int check_parent_dir(const std::string& path) { int check_parent_dir(const std::string& path) { Loading Loading @@ -233,6 +232,43 @@ int gkfs_stat(const string& path, struct stat* buf, bool follow_links) { return 0; return 0; } } int gkfs_statx(int dirfs, const std::string& path, int flags, unsigned int mask, struct statx* buf, bool follow_links) { auto md = gkfs::util::get_metadata(path, follow_links); if (!md) { return -1; } struct stat tmp{}; gkfs::util::metadata_to_stat(path, *md, tmp); buf->stx_mask = 0; buf->stx_blksize = tmp.st_blksize; buf->stx_attributes = 0; buf->stx_nlink = tmp.st_nlink; buf->stx_uid = tmp.st_uid; buf->stx_gid = tmp.st_gid; buf->stx_mode = tmp.st_mode; buf->stx_ino = tmp.st_ino; buf->stx_size = tmp.st_size; buf->stx_blocks = tmp.st_blocks; buf->stx_attributes_mask = 0; buf->stx_atime.tv_sec = tmp.st_atim.tv_sec; buf->stx_atime.tv_nsec = tmp.st_atim.tv_nsec; buf->stx_mtime.tv_sec = tmp.st_mtim.tv_sec; buf->stx_mtime.tv_nsec = tmp.st_mtim.tv_nsec; buf->stx_ctime.tv_sec = tmp.st_ctim.tv_sec; buf->stx_ctime.tv_nsec = tmp.st_ctim.tv_nsec; buf->stx_btime = buf->stx_atime; return 0; } int gkfs_statfs(struct statfs* buf) { int gkfs_statfs(struct statfs* buf) { auto blk_stat = gkfs::rpc::forward_get_chunk_stat(); auto blk_stat = gkfs::rpc::forward_get_chunk_stat(); buf->f_type = 0; buf->f_type = 0; Loading
src/client/hooks.cpp +33 −0 Original line number Original line Diff line number Diff line Loading @@ -98,6 +98,39 @@ int hook_stat(const char* path, struct stat* buf) { return syscall_no_intercept(SYS_stat, rel_path.c_str(), buf); return syscall_no_intercept(SYS_stat, rel_path.c_str(), buf); } } int hook_statx(int dirfd, const char* path, int flags, unsigned int mask, struct ::statx* buf) { LOG(DEBUG, "{}() called with dirfd: '{}', path: \"{}\", flags: '{}', mask: '{}', buf: '{}'", __func__, dirfd, path, flags, mask, fmt::ptr(buf)); std::string resolved; auto rstatus = CTX->relativize_fd_path(dirfd, path, resolved); switch (rstatus) { case gkfs::preload::RelativizeStatus::fd_unknown: return syscall_no_intercept(SYS_statx, dirfd, path, flags, mask, buf); case gkfs::preload::RelativizeStatus::external: return syscall_no_intercept(SYS_statx, dirfd, resolved.c_str(), flags, mask, buf); case gkfs::preload::RelativizeStatus::fd_not_a_dir: return -ENOTDIR; case gkfs::preload::RelativizeStatus::internal: return with_errno(gkfs::syscall::gkfs_statx(dirfd, resolved.c_str() , flags, mask, buf)); default: LOG(ERROR, "{}() relativize status unknown: {}", __func__); return -EINVAL; } return syscall_no_intercept(SYS_statx, dirfd, path, flags, mask, buf); } int hook_lstat(const char* path, struct stat* buf) { int hook_lstat(const char* path, struct stat* buf) { LOG(DEBUG, "{}() called with path: \"{}\", buf: {}", LOG(DEBUG, "{}() called with path: \"{}\", buf: {}", Loading
src/client/intercept.cpp +11 −1 Original line number Original line Diff line number Diff line Loading @@ -466,6 +466,16 @@ int hook(long syscall_number, reinterpret_cast<struct stat*>(arg1)); reinterpret_cast<struct stat*>(arg1)); break; break; #ifdef SYS_statx case SYS_statx: *result = gkfs::hook::hook_statx(static_cast<int>(arg0), reinterpret_cast<char*>(arg1), static_cast<int>(arg2), static_cast<unsigned int>(arg3), reinterpret_cast<struct statx*>(arg4)); break; #endif case SYS_lstat: case SYS_lstat: *result = gkfs::hook::hook_lstat(reinterpret_cast<char*>(arg0), *result = gkfs::hook::hook_lstat(reinterpret_cast<char*>(arg0), reinterpret_cast<struct stat*>(arg1)); reinterpret_cast<struct stat*>(arg1)); Loading