Loading src/client/hooks.cpp +26 −9 Original line number Diff line number Diff line Loading @@ -210,12 +210,9 @@ hook_openat(int dirfd, const char* cpath, int flags, mode_t mode) { return -ENOTDIR; case gkfs::preload::RelativizeStatus::internal: { auto md_ = gkfs::utils::get_metadata(resolved); if(md_ && S_ISDIR(md_->mode())) { // if its a directory, it is handled without fuse // TODO this could cause problems in the filemap if a dir fd and // a file fd are overwriting each other // return gkfs::syscall::gkfs_opendir(resolved); if(flags & O_DIRECTORY) { // Caller explicitly requests a directory: route via FUSE. // No metadata RPC needed — flag is authoritative. int fd = gsl::narrow_cast<int>(syscall_no_intercept_wrapper( SYS_openat, dirfd, cpath, flags, mode)); if(fd < 0) { Loading @@ -225,10 +222,30 @@ hook_openat(int dirfd, const char* cpath, int flags, mode_t mode) { fd, std::make_shared<gkfs::filemap::OpenFile>(resolved, flags)); return fd; } else { } if(flags & (O_WRONLY | O_RDWR | O_CREAT)) { // Write or create flags imply a regular file: intercept directly. return with_errno( gkfs::syscall::gkfs_open(resolved, mode, flags)); } // O_RDONLY without O_DIRECTORY: ambiguous (could be a regular file // or a dir/FUSE-only entry created by a non-intercepted process). // Try intercept first; on ENOENT fall back to FUSE — no upfront stat. { int ret = gkfs::syscall::gkfs_open(resolved, mode, flags); if(ret >= 0) { return ret; } int saved_errno = errno; if(saved_errno != ENOENT) { return -saved_errno; } // Not in intercept namespace: let FUSE handle it (dir or // entry created outside intercept). Do not register in // file_map so that subsequent ops (fstat, read) go to kernel. return gsl::narrow_cast<int>(syscall_no_intercept_wrapper( SYS_openat, dirfd, cpath, flags, mode)); } } default: Loading @@ -254,8 +271,8 @@ hook_close(int fd) { LOG(DEBUG, "{}() called with fd: {}", __func__, fd); auto f = CTX->file_map()->get(fd); if(f != nullptr && f->type() == filemap::FileType::directory) { auto f = CTX->file_map()->get_dir(fd); if(f != nullptr) { CTX->file_map()->remove(fd); return gsl::narrow_cast<int>( syscall_no_intercept_wrapper(SYS_close, fd)); Loading Loading
src/client/hooks.cpp +26 −9 Original line number Diff line number Diff line Loading @@ -210,12 +210,9 @@ hook_openat(int dirfd, const char* cpath, int flags, mode_t mode) { return -ENOTDIR; case gkfs::preload::RelativizeStatus::internal: { auto md_ = gkfs::utils::get_metadata(resolved); if(md_ && S_ISDIR(md_->mode())) { // if its a directory, it is handled without fuse // TODO this could cause problems in the filemap if a dir fd and // a file fd are overwriting each other // return gkfs::syscall::gkfs_opendir(resolved); if(flags & O_DIRECTORY) { // Caller explicitly requests a directory: route via FUSE. // No metadata RPC needed — flag is authoritative. int fd = gsl::narrow_cast<int>(syscall_no_intercept_wrapper( SYS_openat, dirfd, cpath, flags, mode)); if(fd < 0) { Loading @@ -225,10 +222,30 @@ hook_openat(int dirfd, const char* cpath, int flags, mode_t mode) { fd, std::make_shared<gkfs::filemap::OpenFile>(resolved, flags)); return fd; } else { } if(flags & (O_WRONLY | O_RDWR | O_CREAT)) { // Write or create flags imply a regular file: intercept directly. return with_errno( gkfs::syscall::gkfs_open(resolved, mode, flags)); } // O_RDONLY without O_DIRECTORY: ambiguous (could be a regular file // or a dir/FUSE-only entry created by a non-intercepted process). // Try intercept first; on ENOENT fall back to FUSE — no upfront stat. { int ret = gkfs::syscall::gkfs_open(resolved, mode, flags); if(ret >= 0) { return ret; } int saved_errno = errno; if(saved_errno != ENOENT) { return -saved_errno; } // Not in intercept namespace: let FUSE handle it (dir or // entry created outside intercept). Do not register in // file_map so that subsequent ops (fstat, read) go to kernel. return gsl::narrow_cast<int>(syscall_no_intercept_wrapper( SYS_openat, dirfd, cpath, flags, mode)); } } default: Loading @@ -254,8 +271,8 @@ hook_close(int fd) { LOG(DEBUG, "{}() called with fd: {}", __func__, fd); auto f = CTX->file_map()->get(fd); if(f != nullptr && f->type() == filemap::FileType::directory) { auto f = CTX->file_map()->get_dir(fd); if(f != nullptr) { CTX->file_map()->remove(fd); return gsl::narrow_cast<int>( syscall_no_intercept_wrapper(SYS_close, fd)); Loading