| 
 | 1 | + | 
 | 2 | + | 
 | 3 | +ffind  | 
 | 4 | +-----  | 
 | 5 | + | 
 | 6 | +An Asynchronous File Finder for Linux  | 
 | 7 | + | 
 | 8 | +ffind is a high-performance, command-line utility for recursively finding files on a Linux filesystem. It is built from the ground up using io_uring, the modern asynchronous I/O interface in the Linux kernel, to achieve maximum throughput and efficiency.  | 
 | 9 | + | 
 | 10 | +ffind is designed to do one thing exceptionally well: find files that contain a specific substring in their name, as fast as possible.   | 
 | 11 | + | 
 | 12 | + | 
 | 13 | + | 
 | 14 | +Usage  | 
 | 15 | +_____  | 
 | 16 | + | 
 | 17 | +CHECK :: USAGE.md  | 
 | 18 | + | 
 | 19 | + | 
 | 20 | + | 
 | 21 | +Working  | 
 | 22 | +_______  | 
 | 23 | + | 
 | 24 | +The Asynchronous io_uring Engine :  | 
 | 25 | + | 
 | 26 | +ffind achieves its performance by fundamentally changing the conversation with the Linux kernel. Instead of the traditional "ask and wait" (blocking) model, ffind uses an event-driven, asynchronous architecture.  | 
 | 27 | + | 
 | 28 | + | 
 | 29 | +The Core Components :  | 
 | 30 | + | 
 | 31 | +io_uring : The foundation of the application. ffind initializes an io_uring instance, creating two ring buffers in memory that are shared directly with the kernel: the Submission Queue (SQ) and the Completion Queue (CQ). This shared memory allows for extremely low-overhead communication.  | 
 | 32 | + | 
 | 33 | + | 
 | 34 | +The Event Loop :   | 
 | 35 | + | 
 | 36 | +The application is built around a single-threaded event loop in main(). This loop's only job is to manage the flow of I/O operations:  | 
 | 37 | +- Submit pending requests from the SQ to the kernel.  | 
 | 38 | +- Wait for completion events (CQEs) to appear on the CQ.  | 
 | 39 | +- Dispatch completed events to a handler function.  | 
 | 40 | +- Repeat.  | 
 | 41 | + | 
 | 42 | +The State Machine (handle_completion) :   | 
 | 43 | + | 
 | 44 | +The heart of the logic resides in the handle_completion function. Since operations are asynchronous and can complete in any order, a state machine is used to track the progress of each directory scan.   | 
 | 45 | + | 
 | 46 | +A single Request struct holds the state for scanning one directory, transitioning through different phases:  | 
 | 47 | + | 
 | 48 | +- Open Phase:   | 
 | 49 | +An openat operation is submitted. When it completes, the function receives a file descriptor (fd).  | 
 | 50 | + | 
 | 51 | +- Read Phase:   | 
 | 52 | +The function stores the fd in the Request struct and submits a getdents64 operation (using the IORING_OP_READ opcode on the directory fd) to read the directory's contents.  | 
 | 53 | + | 
 | 54 | +- Process and Recurse:   | 
 | 55 | +When the read completes, the buffer of directory entries is processed. For each subdirectory found, a new openat request is submitted, creating a new task. For each file, the name is checked against the search term.  | 
 | 56 | + | 
 | 57 | +- Terminal State:  | 
 | 58 | +When a directory read returns 0 bytes, the directory scan is complete. The file descriptor is closed, and all associated memory is freed.  | 
 | 59 | + | 
 | 60 | + | 
 | 61 | +Targeting Efficiency :  | 
 | 62 | + | 
 | 63 | +- Reduced System Call Overhead : The most expensive part of traditional I/O is the context switch between user space and kernel space for each system call. With io_uring, ffind can submit a large batch of I/O requests with a single syscall, and reap many completions with another. This drastically reduces the number of context switches.  | 
 | 64 | + | 
 | 65 | +- True Asynchronicity : ffind can have hundreds or thousands of filesystem operations "in-flight" simultaneously. While the kernel is working on opening one directory or reading another, the application's CPU is free to process the results of already-completed operations. This keeps the CPU and the storage device constantly busy, maximizing parallelism.  | 
 | 66 | + | 
 | 67 | +- Kernel-Side Polling (Optional) : For ultimate low-latency, io_uring can be configured to use kernel-side polling (IORING_SETUP_SQPOLL), which can eliminate system calls from the submission path almost entirely under heavy load.  | 
 | 68 | + | 
 | 69 | + | 
 | 70 | +License  | 
 | 71 | +-------  | 
 | 72 | + | 
 | 73 | +All software contained within this repo is dual licensed LGPL and MIT.   | 
 | 74 | + | 
 | 75 | + | 
 | 76 | +Archit Anant 2025-09-23  | 
 | 77 | + | 
0 commit comments