X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=io_uring_engine.h;h=470bacf9f4c450cb49d9a25185e8100eb4b073b3;hb=498466c6434e479cd973fe7655b4feb51dd2c378;hp=93e7a0dc22c21b79fc21a9cdb63c608e9c3d1348;hpb=009ba1838c9185844acd34458ef863828b8ab143;p=plocate diff --git a/io_uring_engine.h b/io_uring_engine.h index 93e7a0d..470bacf 100644 --- a/io_uring_engine.h +++ b/io_uring_engine.h @@ -3,49 +3,84 @@ #include #include -#include -#include +#include +#include +#include +#include + +struct io_uring_sqe; +#ifndef WITHOUT_URING #include +#endif class IOUringEngine { public: - IOUringEngine(); - void submit_read(int fd, size_t len, off_t offset, std::function cb); + IOUringEngine(size_t slop_bytes); + void submit_read(int fd, size_t len, off_t offset, std::function cb); + + // NOTE: We just do the stat() to get the data into the dentry cache for fast access; + // we don't care about the return value. Thus, the callback has no parameter lists. + // If we have no io_uring, the callback will be made immediately, with no stat() call + // being done. + void submit_stat(const char *path, std::function cb); + bool get_supports_stat() { return supports_stat; } + void finish(); size_t get_waiting_reads() const { return pending_reads + queued_reads.size(); } private: - void submit_read_internal(io_uring_sqe *sqe, int fd, size_t len, off_t offset, std::function cb); +#ifndef WITHOUT_URING + void submit_read_internal(io_uring_sqe *sqe, int fd, size_t len, off_t offset, std::function cb); + void submit_stat_internal(io_uring_sqe *sqe, char *path, std::function cb); io_uring ring; +#endif size_t pending_reads = 0; // Number of requests we have going in the ring. - bool using_uring; + bool using_uring, supports_stat = false; + const size_t slop_bytes; struct QueuedRead { int fd; size_t len; off_t offset; - std::function cb; + std::function cb; }; std::queue queued_reads; + struct QueuedStat { + char *pathname; // Owned by us. + std::function cb; + }; + std::queue queued_stats; + + enum Op { OP_READ, + OP_STAT }; + struct PendingRead { - void *buf; - size_t len; - std::function cb; + Op op; - // For re-submission. - int fd; - off_t offset; - iovec iov; + std::function read_cb; + std::function stat_cb; + + union { + struct { + void *buf; + size_t len; + + // For re-submission. + int fd; + off_t offset; + iovec iov; + } read; + struct { + char *pathname; + struct statx *buf; + } stat; + }; }; // 256 simultaneous requests should be ample, for slow and fast media alike. static constexpr size_t queue_depth = 256; }; -// A wrapper around pread() that returns an incomplete read. -// Always synchronous (no io_uring). -void complete_pread(int fd, void *ptr, size_t len, off_t offset); - #endif // !defined(IO_URING_ENGINE_H)