A simple block I/O filter driver for modern Linux kernels (5.0+). This driver creates a virtual block device that intercepts and forwards I/O requests to an underlying block device, allowing monitoring, logging, and potential modification of block I/O operations.
Updated for Linux Kernel 5.0+ - This version has been modernized to use the blk-mq (multi-queue block layer) API instead of the deprecated request_fn interface.
- Modern Kernel Support: Compatible with Linux kernels 5.0 and above
- Bio-based Filtering: Intercepts block I/O at the bio submission level
- Configurable Target Device: Use module parameters to specify which device to filter
- Statistics Tracking: Counts processed I/O operations
- Proper Resource Management: Safe device reference counting and error handling
- Control Interface: Misc device for querying statistics via ioctl
- Linux kernel 5.0 or newer
- Kernel headers for your running kernel
- GCC and make
- Root privileges for loading/unloading the module
The driver operates by:
- Creating a Virtual Block Device: Allocates a new block device (
/dev/blockfilter) using the modernblk_alloc_disk()API - Opening the Target Device: Safely opens the target block device (e.g.,
/dev/sda1) with proper reference counting usingblkdev_get_by_path() - Intercepting I/O: Implements a
submit_biocallback that intercepts all bio submissions to the filter device - Forwarding Requests: Clones each bio and forwards it to the underlying target device using
submit_bio_noacct() - Logging & Statistics: Logs I/O operations and maintains counters for monitoring
This approach allows transparent interception of block I/O without modifying the target device or filesystem.
cd misc
makeThis will compile the misc.ko kernel module.
Basic usage with default settings (targets /dev/sda1):
sudo insmod misc.koSpecify a custom target device:
sudo insmod misc.ko target_device=/dev/sdb1WARNING: Be very careful when specifying target devices. Incorrect usage could interfere with disk I/O.
View kernel messages:
dmesg | tail -20List loaded modules:
lsmod | grep miscCheck module information:
modinfo misc.kosudo rmmod miscTo install the module system-wide:
sudo make installTo uninstall:
sudo make uninstall- target_device (string): Path to the block device to filter
- Default:
/dev/sda1 - Example:
target_device=/dev/nvme0n1p1
- Default:
The driver creates a misc device at /dev/blockfilter that supports ioctl commands:
Get I/O Statistics:
#include <sys/ioctl.h>
#include <fcntl.h>
#define MISC_GET _IOR('B', 0x01, unsigned long)
int fd = open("/dev/blockfilter", O_RDONLY);
unsigned long bio_count;
ioctl(fd, MISC_GET, &bio_count);
printf("Total BIOs processed: %lu\n", bio_count);
close(fd);Enable debug messages:
echo 8 > /proc/sys/kernel/printkView real-time kernel logs:
sudo dmesg -wmisc/
├── misc.c - Main driver implementation
├── misc.h - Header with ioctl definitions
└── Makefile - Build configuration
filter_submit_bio(): Bio submission callback that intercepts I/Oregister_block_device(): Opens target device and creates filter deviceunregister_block_device(): Cleanup and resource releasemischelp_ioctl(): Control interface for statistics and management
This modernized version includes:
- Modern Block Layer API: Uses
blk_alloc_disk()andsubmit_bioinstead of deprecatedrequest_fn - Proper Reference Counting: Uses
blkdev_get_by_path()/blkdev_put()for safe device access - Comprehensive Error Handling: All error paths properly cleanup resources
- NULL Pointer Protection: Validates all pointers before use
- Module Parameters: Configurable target device without recompilation
- Better Logging: Uses
pr_*macros with appropriate log levels - Thread Safety: Uses mutex for synchronization
- Atomic Statistics: Lock-free statistics using atomic64_t
- Proper IOCTL Definitions: Uses standard
_IOR/_IOWmacros - Clean Code: Removed unused headers and improved documentation
- Educational Purpose: This is a demonstration driver, not production-ready
- Performance Impact: Bio cloning adds overhead to I/O path
- No Hot-Plug Support: Target device must exist when module loads
- Single Target: Only supports one target device per module instance
- Root Required: Must run as root to load kernel modules
- This module operates at the kernel level and can cause system instability if misused
- Always test on non-production systems first
- Specifying the wrong target device could cause data loss
- The default target (
/dev/sda1) may be your system drive - change it if needed - Kernel panics are possible if the target device is removed while the module is loaded
Module fails to load:
- Check kernel version:
uname -r(must be 5.0+) - Verify kernel headers are installed:
ls /lib/modules/$(uname -r)/build - Check dmesg for specific error messages
Target device errors:
- Ensure the device path exists:
ls -l /dev/sda1 - Verify you have permission to access the device
- Check that the device is not exclusively locked by another process
Compilation errors:
- Ensure kernel headers match your running kernel
- Update to latest kernel headers:
sudo apt update && sudo apt install linux-headers-$(uname -r)
Enable additional debugging by modifying the code:
- Change
pr_debug()topr_info()inmisc.c:107to see all I/O operations - Add custom logic in
filter_submit_bio()to inspect/modify I/O requests
The original driver was written in 2013 for Linux 3.x kernels. This updated version (2025) modernizes the code for current Linux kernels (5.0+), which underwent major block layer rewrites. The kernel's transition from request_fn to blk-mq required a complete rewrite of the I/O interception mechanism.
MIT License - See source files for full license text.
Linux kernel, block filter driver, blk-mq, bio interception, block I/O monitoring, device mapper, kernel module
Original: Asim Kadav (asimkadav@gmail.com) Modernized: 2025 update for Linux 5.0+ kernels
NO WARRANTIES. Use at your own risk. This software is provided "as is" without warranty of any kind. Test thoroughly in safe environments before any production use.