Commit 0977f04f authored by sevenuz's avatar sevenuz
Browse files

dup and remove fix

parent 71e33592
Loading
Loading
Loading
Loading
Loading
+31 −2
Changes for src/client/hooks.cpp: 31 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -276,9 +276,10 @@ hook_close(int fd) {

    auto f = CTX->file_map()->get_dir(fd);
    if(f != nullptr) {
        // OpenFileMap::remove() already closes the kernel fd (it assumes a
        // /dev/null placeholder); closing again would hit a reused fd.
        CTX->file_map()->remove(fd);
        return gsl::narrow_cast<int>(
                syscall_no_intercept_wrapper(SYS_close, fd));
        return 0;
    }
    auto ret = gkfs::syscall::gkfs_close(fd);

@@ -849,11 +850,26 @@ hook_ftruncate(unsigned int fd, unsigned long length) {
            syscall_no_intercept_wrapper(SYS_ftruncate, fd, length));
}

// Hybrid dirs live in the kernel (FUSE): dup them in the kernel and register
// the new fd as OpenDir so later relative lookups (openat/fstatat) resolve.
static int
dup_kernel_dir(int oldfd, long newfd) {
    if(newfd >= 0) {
        auto dir = CTX->file_map()->get_dir(oldfd);
        CTX->file_map()->add(
                newfd, std::make_shared<gkfs::filemap::OpenDir>(dir->path()));
    }
    return gsl::narrow_cast<int>(newfd);
}

int
hook_dup(unsigned int fd) {

    LOG(DEBUG, "{}() called with oldfd: {}", __func__, fd);

    if(CTX->file_map()->get_dir(fd)) {
        return dup_kernel_dir(fd, syscall_no_intercept_wrapper(SYS_dup, fd));
    }
    if(CTX->file_map()->exist(fd)) {
        return with_errno(gkfs::syscall::gkfs_dup(fd));
    }
@@ -865,6 +881,10 @@ hook_dup2(unsigned int oldfd, unsigned int newfd) {

    LOG(DEBUG, "{}() called with oldfd: {}, newfd: {}", __func__, oldfd, newfd);

    if(CTX->file_map()->get_dir(oldfd)) {
        return dup_kernel_dir(
                oldfd, syscall_no_intercept_wrapper(SYS_dup2, oldfd, newfd));
    }
    if(CTX->file_map()->exist(oldfd)) {
        return with_errno(gkfs::syscall::gkfs_dup2(oldfd, newfd));
    }
@@ -878,6 +898,10 @@ hook_dup3(unsigned int oldfd, unsigned int newfd, int flags) {
    LOG(DEBUG, "{}() called with oldfd: {}, newfd: {}, flags: {}", __func__,
        oldfd, newfd, flags);

    if(CTX->file_map()->get_dir(oldfd)) {
        return dup_kernel_dir(oldfd, syscall_no_intercept_wrapper(
                                             SYS_dup3, oldfd, newfd, flags));
    }
    if(CTX->file_map()->exist(oldfd)) {
        if(flags & O_CLOEXEC) {
            LOG(WARNING, "{}() Not supported", __func__);
@@ -1273,6 +1297,11 @@ hook_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) {
        return gsl::narrow_cast<int>(
                syscall_no_intercept_wrapper(SYS_fcntl, fd, cmd, arg));
    }
    if((cmd == F_DUPFD || cmd == F_DUPFD_CLOEXEC) &&
       CTX->file_map()->get_dir(fd)) {
        return dup_kernel_dir(
                fd, syscall_no_intercept_wrapper(SYS_fcntl, fd, cmd, arg));
    }
    int ret;
    switch(cmd) {