Writing a simple CBT (changed block tracking) driver for Linux

This might be useful if you want to implement a simple CBT (changed block tracking) driver for Linux.

The key here is to get block device queue, then replace the request function with your own

q = bdev_get_queue(bdev); 
orig = q->make_request_fn; 
q->make_request_fn = requestfunc;      
 

in your own request function you can print all struct bio information, using simple function like this:
static void printbio(struct bio *bio, char *pref) {

printk("%s bio=%p, dev=%x, sector=%lu, bi_flags=%lx" " bi_rw=%lx bi_size=%d bi_vcnt=%d bi_io_vec=%p" " bi_max_vecs=%d\n", pref, bio, bio->bi_bdev ? bio->bi_bdev->bd_dev : -1, bio->bi_iter.bi_sector, bio->bi_flags, bio->bi_rw, bio->bi_iter.bi_size, bio->bi_vcnt, bio->bi_io_vec, bio->bi_max_vecs);

}

Using this technique, you can also create simple copy on write snapshot feature for the block devices that are not part of the LVM.
You can intercept IO request, save that BIO in memory (postponing it), then you create and submit new BIO to read original data from disk and only then you allow the first BIO to go through - simple COW snapshots.