Loading src/client/gkfs_python.cpp +237 −4 Original line number Diff line number Diff line Loading @@ -8,12 +8,141 @@ PYBIND11_MODULE(gkfs_python, m) { m.doc() = "Python bindings for GekkoFS POSIX interface"; m.def("gkfs_open", &gkfs::syscall::gkfs_open); m.def("gkfs_create", &gkfs::syscall::gkfs_create); m.def("gkfs_libcremove", &gkfs::syscall::gkfs_libcremove); m.def("gkfs_remove", &gkfs::syscall::gkfs_remove); m.def("gkfs_access", &gkfs::syscall::gkfs_access, py::arg("path"), py::arg("mask"), py::arg("follow_links") = true); // Wrap gkfs_stat manually (complex signature) m.def("gkfs_rmdir", &gkfs::syscall::gkfs_rmdir); m.def("gkfs_write", [](int fd, py::bytes data) -> ssize_t { py::buffer_info info(py::buffer(data).request()); ssize_t ret = gkfs::syscall::gkfs_write(fd, info.ptr, info.size); if(ret < 0) throw std::runtime_error("gkfs_write failed"); return ret; }); m.def("gkfs_read", [](int fd, size_t count) -> py::bytes { std::vector<char> buf(count); ssize_t ret = gkfs::syscall::gkfs_read(fd, buf.data(), count); if(ret < 0) throw std::runtime_error("gkfs_read failed"); return py::bytes(buf.data(), ret); }); m.def("gkfs_close", &gkfs::syscall::gkfs_close); m.def( "gkfs_lseek", [](unsigned int fd, int64_t offset, unsigned int whence) { return gkfs::syscall::gkfs_lseek(fd, offset, whence); }, py::arg("fd"), py::arg("offset"), py::arg("whence")); m.def( "gkfs_pwrite", [](int fd, py::bytes data, int64_t offset) { std::string buf = data; return gkfs::syscall::gkfs_pwrite(fd, buf.data(), buf.size(), offset); }, py::arg("fd"), py::arg("data"), py::arg("offset")); m.def( "gkfs_pread", [](int fd, size_t count, int64_t offset) { std::string buf(count, '\0'); ssize_t nread = gkfs::syscall::gkfs_pread(fd, buf.data(), count, offset); if(nread < 0) { throw std::runtime_error("gkfs_pread failed"); } return py::bytes(buf.data(), nread); }, py::arg("fd"), py::arg("count"), py::arg("offset")); m.def( "gkfs_readv", [](int fd, size_t iovcnt) { // TODO better allocation or provide size to calc std::vector<char> buffer(4096 * iovcnt); std::vector<struct iovec> iov(iovcnt); size_t chunk = buffer.size() / iovcnt; for(size_t i = 0; i < iovcnt; ++i) { iov[i].iov_base = buffer.data() + i * chunk; iov[i].iov_len = chunk; } ssize_t nread = gkfs::syscall::gkfs_readv(fd, iov.data(), iovcnt); if(nread < 0) throw std::runtime_error("gkfs_readv failed"); return py::bytes(buffer.data(), nread); }, py::arg("fd"), py::arg("iovcnt")); m.def( "gkfs_writev", [](int fd, const std::vector<py::bytes>& bufs) { std::vector<std::string> buf_data; std::vector<struct iovec> iov; for(const auto& b : bufs) { buf_data.emplace_back(b); // keep data alive struct iovec io{}; io.iov_base = (void*) buf_data.back().data(); io.iov_len = buf_data.back().size(); iov.push_back(io); } return gkfs::syscall::gkfs_writev(fd, iov.data(), iov.size()); }, py::arg("fd"), py::arg("buffers")); m.def( "gkfs_preadv", [](int fd, size_t iovcnt, int64_t offset) { std::vector<char> buffer(4096 * iovcnt); // adjust as needed std::vector<struct iovec> iov(iovcnt); size_t chunk = buffer.size() / iovcnt; for(size_t i = 0; i < iovcnt; ++i) { iov[i].iov_base = buffer.data() + i * chunk; iov[i].iov_len = chunk; } ssize_t nread = gkfs::syscall::gkfs_preadv(fd, iov.data(), iovcnt, offset); if(nread < 0) throw std::runtime_error("gkfs_preadv failed"); return py::bytes(buffer.data(), nread); }, py::arg("fd"), py::arg("iovcnt"), py::arg("offset")); m.def( "gkfs_pwritev", [](int fd, const std::vector<py::bytes>& bufs, int64_t offset) { std::vector<std::string> buf_data; std::vector<struct iovec> iov; for(const auto& b : bufs) { buf_data.emplace_back(b); struct iovec io{}; io.iov_base = (void*) buf_data.back().data(); io.iov_len = buf_data.back().size(); iov.push_back(io); } return gkfs::syscall::gkfs_pwritev(fd, iov.data(), iov.size(), offset); }, py::arg("fd"), py::arg("buffers"), py::arg("offset")); m.def("gkfs_stat", [](const std::string& path, bool follow_links, bool bypass_rename) { struct stat buf; Loading @@ -38,10 +167,102 @@ PYBIND11_MODULE(gkfs_python, m) { return std::make_tuple(res, stat_result); }); m.def("gkfs_statx", [](int dirfd, const std::string& path, int flags, unsigned int mask, bool follow_links) { struct statx stx; memset(&stx, 0, sizeof(stx)); int ret = gkfs::syscall::gkfs_statx(dirfd, path, flags, mask, &stx, follow_links); py::dict meta; if(ret == 0) { meta["size"] = stx.stx_size; meta["mode"] = stx.stx_mode; meta["uid"] = stx.stx_uid; meta["gid"] = stx.stx_gid; meta["mtime"] = stx.stx_mtime.tv_sec; meta["atime"] = stx.stx_atime.tv_sec; meta["ctime"] = stx.stx_ctime.tv_sec; meta["ino"] = stx.stx_ino; meta["nlink"] = stx.stx_nlink; meta["dev_major"] = stx.stx_dev_major; meta["dev_minor"] = stx.stx_dev_minor; } return py::make_tuple(ret, meta); }); m.def("gkfs_dup", &gkfs::syscall::gkfs_dup); m.def("gkfs_dup2", &gkfs::syscall::gkfs_dup2); m.def("gkfs_access", &gkfs::syscall::gkfs_access, py::arg("path"), py::arg("mask"), py::arg("follow_links") = true); m.def("gkfs_get_file_list", &gkfs::syscall::gkfs_get_file_list); m.def("gkfs_close", &gkfs::syscall::gkfs_close); m.def("gkfs_opendir", &gkfs::syscall::gkfs_opendir); m.def("gkfs_getdents", [](unsigned int fd, unsigned int count) { std::vector<char> buf(count); int ret = gkfs::syscall::gkfs_getdents( fd, reinterpret_cast<struct linux_dirent*>(buf.data()), count); if(ret < 0) throw std::runtime_error("gkfs_getdents failed"); return py::bytes(buf.data(), ret); }); m.def("gkfs_getdents64", [](unsigned int fd, unsigned int count) { std::vector<char> buf(count); int ret = gkfs::syscall::gkfs_getdents64( fd, reinterpret_cast<struct linux_dirent64*>(buf.data()), count); if(ret < 0) throw std::runtime_error("gkfs_getdents64 failed"); return py::bytes(buf.data(), ret); }); m.def("gkfs_truncate", &gkfs::syscall::gkfs_truncate); #ifdef HAS_SYMLINKS m.def("gkfs_mk_symlink", &gkfs::syscall::gkfs_mk_symlink); m.def("gkfs_readlink", [](const std::string& path, int bufsize) { std::vector<char> buf(bufsize); int ret = gkfs::syscall::gkfs_readlink(path, buf.data(), bufsize); if(ret < 0) throw std::runtime_error("gkfs_readlink failed"); return std::string(buf.data(), ret); }); #endif #ifdef HAS_RENAME m.def("gkfs_rename", &gkfs::syscall::gkfs_rename); #endif m.def("gkfs_fsync", &gkfs::syscall::gkfs_fsync); m.def("gkfs_mmap", [](uintptr_t addr, size_t length, int prot, int flags, int fd, off_t offset) { void* result = gkfs::syscall::gkfs_mmap( reinterpret_cast<void*>(addr), length, prot, flags, fd, offset); // if(result == MAP_FAILED) // TODO // throw std::runtime_error("gkfs_mmap failed"); return reinterpret_cast<uintptr_t>(result); }); m.def("gkfs_munmap", [](uintptr_t addr, size_t length) { return gkfs::syscall::gkfs_munmap(reinterpret_cast<void*>(addr), length); }); m.def("gkfs_msync", [](uintptr_t addr, size_t length, int flags) { return gkfs::syscall::gkfs_msync(reinterpret_cast<void*>(addr), length, flags); }); // TODO missing // expand_start, expand_status, expand_finalize m.def( "init", Loading @@ -54,4 +275,16 @@ PYBIND11_MODULE(gkfs_python, m) { return result; }, "Initialize GekkoFS"); m.def( "end", []() { int result = gkfs_end(); if(result != 0) { throw std::runtime_error("gkfs_end() failed with code " + std::to_string(result)); } return result; }, "End GekkoFS"); } Loading
src/client/gkfs_python.cpp +237 −4 Original line number Diff line number Diff line Loading @@ -8,12 +8,141 @@ PYBIND11_MODULE(gkfs_python, m) { m.doc() = "Python bindings for GekkoFS POSIX interface"; m.def("gkfs_open", &gkfs::syscall::gkfs_open); m.def("gkfs_create", &gkfs::syscall::gkfs_create); m.def("gkfs_libcremove", &gkfs::syscall::gkfs_libcremove); m.def("gkfs_remove", &gkfs::syscall::gkfs_remove); m.def("gkfs_access", &gkfs::syscall::gkfs_access, py::arg("path"), py::arg("mask"), py::arg("follow_links") = true); // Wrap gkfs_stat manually (complex signature) m.def("gkfs_rmdir", &gkfs::syscall::gkfs_rmdir); m.def("gkfs_write", [](int fd, py::bytes data) -> ssize_t { py::buffer_info info(py::buffer(data).request()); ssize_t ret = gkfs::syscall::gkfs_write(fd, info.ptr, info.size); if(ret < 0) throw std::runtime_error("gkfs_write failed"); return ret; }); m.def("gkfs_read", [](int fd, size_t count) -> py::bytes { std::vector<char> buf(count); ssize_t ret = gkfs::syscall::gkfs_read(fd, buf.data(), count); if(ret < 0) throw std::runtime_error("gkfs_read failed"); return py::bytes(buf.data(), ret); }); m.def("gkfs_close", &gkfs::syscall::gkfs_close); m.def( "gkfs_lseek", [](unsigned int fd, int64_t offset, unsigned int whence) { return gkfs::syscall::gkfs_lseek(fd, offset, whence); }, py::arg("fd"), py::arg("offset"), py::arg("whence")); m.def( "gkfs_pwrite", [](int fd, py::bytes data, int64_t offset) { std::string buf = data; return gkfs::syscall::gkfs_pwrite(fd, buf.data(), buf.size(), offset); }, py::arg("fd"), py::arg("data"), py::arg("offset")); m.def( "gkfs_pread", [](int fd, size_t count, int64_t offset) { std::string buf(count, '\0'); ssize_t nread = gkfs::syscall::gkfs_pread(fd, buf.data(), count, offset); if(nread < 0) { throw std::runtime_error("gkfs_pread failed"); } return py::bytes(buf.data(), nread); }, py::arg("fd"), py::arg("count"), py::arg("offset")); m.def( "gkfs_readv", [](int fd, size_t iovcnt) { // TODO better allocation or provide size to calc std::vector<char> buffer(4096 * iovcnt); std::vector<struct iovec> iov(iovcnt); size_t chunk = buffer.size() / iovcnt; for(size_t i = 0; i < iovcnt; ++i) { iov[i].iov_base = buffer.data() + i * chunk; iov[i].iov_len = chunk; } ssize_t nread = gkfs::syscall::gkfs_readv(fd, iov.data(), iovcnt); if(nread < 0) throw std::runtime_error("gkfs_readv failed"); return py::bytes(buffer.data(), nread); }, py::arg("fd"), py::arg("iovcnt")); m.def( "gkfs_writev", [](int fd, const std::vector<py::bytes>& bufs) { std::vector<std::string> buf_data; std::vector<struct iovec> iov; for(const auto& b : bufs) { buf_data.emplace_back(b); // keep data alive struct iovec io{}; io.iov_base = (void*) buf_data.back().data(); io.iov_len = buf_data.back().size(); iov.push_back(io); } return gkfs::syscall::gkfs_writev(fd, iov.data(), iov.size()); }, py::arg("fd"), py::arg("buffers")); m.def( "gkfs_preadv", [](int fd, size_t iovcnt, int64_t offset) { std::vector<char> buffer(4096 * iovcnt); // adjust as needed std::vector<struct iovec> iov(iovcnt); size_t chunk = buffer.size() / iovcnt; for(size_t i = 0; i < iovcnt; ++i) { iov[i].iov_base = buffer.data() + i * chunk; iov[i].iov_len = chunk; } ssize_t nread = gkfs::syscall::gkfs_preadv(fd, iov.data(), iovcnt, offset); if(nread < 0) throw std::runtime_error("gkfs_preadv failed"); return py::bytes(buffer.data(), nread); }, py::arg("fd"), py::arg("iovcnt"), py::arg("offset")); m.def( "gkfs_pwritev", [](int fd, const std::vector<py::bytes>& bufs, int64_t offset) { std::vector<std::string> buf_data; std::vector<struct iovec> iov; for(const auto& b : bufs) { buf_data.emplace_back(b); struct iovec io{}; io.iov_base = (void*) buf_data.back().data(); io.iov_len = buf_data.back().size(); iov.push_back(io); } return gkfs::syscall::gkfs_pwritev(fd, iov.data(), iov.size(), offset); }, py::arg("fd"), py::arg("buffers"), py::arg("offset")); m.def("gkfs_stat", [](const std::string& path, bool follow_links, bool bypass_rename) { struct stat buf; Loading @@ -38,10 +167,102 @@ PYBIND11_MODULE(gkfs_python, m) { return std::make_tuple(res, stat_result); }); m.def("gkfs_statx", [](int dirfd, const std::string& path, int flags, unsigned int mask, bool follow_links) { struct statx stx; memset(&stx, 0, sizeof(stx)); int ret = gkfs::syscall::gkfs_statx(dirfd, path, flags, mask, &stx, follow_links); py::dict meta; if(ret == 0) { meta["size"] = stx.stx_size; meta["mode"] = stx.stx_mode; meta["uid"] = stx.stx_uid; meta["gid"] = stx.stx_gid; meta["mtime"] = stx.stx_mtime.tv_sec; meta["atime"] = stx.stx_atime.tv_sec; meta["ctime"] = stx.stx_ctime.tv_sec; meta["ino"] = stx.stx_ino; meta["nlink"] = stx.stx_nlink; meta["dev_major"] = stx.stx_dev_major; meta["dev_minor"] = stx.stx_dev_minor; } return py::make_tuple(ret, meta); }); m.def("gkfs_dup", &gkfs::syscall::gkfs_dup); m.def("gkfs_dup2", &gkfs::syscall::gkfs_dup2); m.def("gkfs_access", &gkfs::syscall::gkfs_access, py::arg("path"), py::arg("mask"), py::arg("follow_links") = true); m.def("gkfs_get_file_list", &gkfs::syscall::gkfs_get_file_list); m.def("gkfs_close", &gkfs::syscall::gkfs_close); m.def("gkfs_opendir", &gkfs::syscall::gkfs_opendir); m.def("gkfs_getdents", [](unsigned int fd, unsigned int count) { std::vector<char> buf(count); int ret = gkfs::syscall::gkfs_getdents( fd, reinterpret_cast<struct linux_dirent*>(buf.data()), count); if(ret < 0) throw std::runtime_error("gkfs_getdents failed"); return py::bytes(buf.data(), ret); }); m.def("gkfs_getdents64", [](unsigned int fd, unsigned int count) { std::vector<char> buf(count); int ret = gkfs::syscall::gkfs_getdents64( fd, reinterpret_cast<struct linux_dirent64*>(buf.data()), count); if(ret < 0) throw std::runtime_error("gkfs_getdents64 failed"); return py::bytes(buf.data(), ret); }); m.def("gkfs_truncate", &gkfs::syscall::gkfs_truncate); #ifdef HAS_SYMLINKS m.def("gkfs_mk_symlink", &gkfs::syscall::gkfs_mk_symlink); m.def("gkfs_readlink", [](const std::string& path, int bufsize) { std::vector<char> buf(bufsize); int ret = gkfs::syscall::gkfs_readlink(path, buf.data(), bufsize); if(ret < 0) throw std::runtime_error("gkfs_readlink failed"); return std::string(buf.data(), ret); }); #endif #ifdef HAS_RENAME m.def("gkfs_rename", &gkfs::syscall::gkfs_rename); #endif m.def("gkfs_fsync", &gkfs::syscall::gkfs_fsync); m.def("gkfs_mmap", [](uintptr_t addr, size_t length, int prot, int flags, int fd, off_t offset) { void* result = gkfs::syscall::gkfs_mmap( reinterpret_cast<void*>(addr), length, prot, flags, fd, offset); // if(result == MAP_FAILED) // TODO // throw std::runtime_error("gkfs_mmap failed"); return reinterpret_cast<uintptr_t>(result); }); m.def("gkfs_munmap", [](uintptr_t addr, size_t length) { return gkfs::syscall::gkfs_munmap(reinterpret_cast<void*>(addr), length); }); m.def("gkfs_msync", [](uintptr_t addr, size_t length, int flags) { return gkfs::syscall::gkfs_msync(reinterpret_cast<void*>(addr), length, flags); }); // TODO missing // expand_start, expand_status, expand_finalize m.def( "init", Loading @@ -54,4 +275,16 @@ PYBIND11_MODULE(gkfs_python, m) { return result; }, "Initialize GekkoFS"); m.def( "end", []() { int result = gkfs_end(); if(result != 0) { throw std::runtime_error("gkfs_end() failed with code " + std::to_string(result)); } return result; }, "End GekkoFS"); }