Commit 3379bf44 authored by Ramon Nou's avatar Ramon Nou
Browse files

Merge branch '104-statx-syscall-missing' into 'master'

Resolve "statx syscall missing"

Closes #104

See merge request !42
parents 1c4528b4 69949c08
Loading
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -31,10 +31,18 @@ int gkfs_create(const std::string& path, mode_t mode);

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);

// Implementation of stat, 
// Follow links is true by default 
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_statvfs(struct statvfs* buf);
+2 −0
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@ int hook_close(int fd);

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_fstat(unsigned int fd, struct stat* buf);
+37 −1
Original line number Diff line number Diff line
@@ -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'
};


namespace {

int check_parent_dir(const std::string& path) {
@@ -233,6 +232,43 @@ int gkfs_stat(const string& path, struct stat* buf, bool follow_links) {
    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) {
    auto blk_stat = gkfs::rpc::forward_get_chunk_stat();
    buf->f_type = 0;
+33 −0
Original line number Diff line number Diff line
@@ -98,6 +98,39 @@ int hook_stat(const char* path, struct stat* 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) {

    LOG(DEBUG, "{}() called with path: \"{}\", buf: {}",
+11 −1
Original line number Diff line number Diff line
@@ -466,6 +466,16 @@ int hook(long syscall_number,
                                            reinterpret_cast<struct stat*>(arg1));
            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:
            *result = gkfs::hook::hook_lstat(reinterpret_cast<char*>(arg0),
                                             reinterpret_cast<struct stat*>(arg1));
Loading