13bd94003SHeinz Mauelshagen // SPDX-License-Identifier: GPL-2.0-only 21da177e4SLinus Torvalds /* 3bf14299fSJana Saout * Copyright (C) 2003 Jana Saout <jana@saout.de> 41da177e4SLinus Torvalds * 51da177e4SLinus Torvalds * This file is released under the GPL. 61da177e4SLinus Torvalds */ 71da177e4SLinus Torvalds 8586e80e6SMikulas Patocka #include <linux/device-mapper.h> 91da177e4SLinus Torvalds 101da177e4SLinus Torvalds #include <linux/module.h> 111da177e4SLinus Torvalds #include <linux/init.h> 121da177e4SLinus Torvalds #include <linux/bio.h> 131da177e4SLinus Torvalds 1472d94861SAlasdair G Kergon #define DM_MSG_PREFIX "zero" 1572d94861SAlasdair G Kergon 161da177e4SLinus Torvalds /* 171da177e4SLinus Torvalds * Construct a dummy mapping that only returns zeros 181da177e4SLinus Torvalds */ 191da177e4SLinus Torvalds static int zero_ctr(struct dm_target *ti, unsigned int argc, char **argv) 201da177e4SLinus Torvalds { 211da177e4SLinus Torvalds if (argc != 0) { 2272d94861SAlasdair G Kergon ti->error = "No arguments required"; 231da177e4SLinus Torvalds return -EINVAL; 241da177e4SLinus Torvalds } 251da177e4SLinus Torvalds 26f8facb61SMike Snitzer /* 27f8facb61SMike Snitzer * Silently drop discards, avoiding -EOPNOTSUPP. 28f8facb61SMike Snitzer */ 2955a62eefSAlasdair G Kergon ti->num_discard_bios = 1; 3000065f92SMikulas Patocka ti->discards_supported = true; 31f8facb61SMike Snitzer 321da177e4SLinus Torvalds return 0; 331da177e4SLinus Torvalds } 341da177e4SLinus Torvalds 351da177e4SLinus Torvalds /* 361da177e4SLinus Torvalds * Return zeros only on reads 371da177e4SLinus Torvalds */ 387de3ee57SMikulas Patocka static int zero_map(struct dm_target *ti, struct bio *bio) 391da177e4SLinus Torvalds { 4070246286SChristoph Hellwig switch (bio_op(bio)) { 4170246286SChristoph Hellwig case REQ_OP_READ: 421eff9d32SJens Axboe if (bio->bi_opf & REQ_RAHEAD) { 431da177e4SLinus Torvalds /* readahead of null bytes only wastes buffer cache */ 44846785e6SChristoph Hellwig return DM_MAPIO_KILL; 4570246286SChristoph Hellwig } 4670246286SChristoph Hellwig zero_fill_bio(bio); 4770246286SChristoph Hellwig break; 4870246286SChristoph Hellwig case REQ_OP_WRITE: 4900065f92SMikulas Patocka case REQ_OP_DISCARD: 501da177e4SLinus Torvalds /* writes get silently dropped */ 511da177e4SLinus Torvalds break; 5270246286SChristoph Hellwig default: 53846785e6SChristoph Hellwig return DM_MAPIO_KILL; 541da177e4SLinus Torvalds } 551da177e4SLinus Torvalds 564246a0b6SChristoph Hellwig bio_endio(bio); 571da177e4SLinus Torvalds 581da177e4SLinus Torvalds /* accepted bio, don't make new request */ 59d2a7ad29SKiyoshi Ueda return DM_MAPIO_SUBMITTED; 601da177e4SLinus Torvalds } 611da177e4SLinus Torvalds 6200065f92SMikulas Patocka static void zero_io_hints(struct dm_target *ti, struct queue_limits *limits) 6300065f92SMikulas Patocka { 6400065f92SMikulas Patocka limits->max_discard_sectors = UINT_MAX; 6500065f92SMikulas Patocka limits->max_hw_discard_sectors = UINT_MAX; 6600065f92SMikulas Patocka limits->discard_granularity = 512; 6700065f92SMikulas Patocka } 6800065f92SMikulas Patocka 691da177e4SLinus Torvalds static struct target_type zero_target = { 701da177e4SLinus Torvalds .name = "zero", 7100065f92SMikulas Patocka .version = {1, 2, 0}, 72410fe220SJeffle Xu .features = DM_TARGET_NOWAIT, 731da177e4SLinus Torvalds .module = THIS_MODULE, 741da177e4SLinus Torvalds .ctr = zero_ctr, 751da177e4SLinus Torvalds .map = zero_map, 7600065f92SMikulas Patocka .io_hints = zero_io_hints, 771da177e4SLinus Torvalds }; 78*3664ff82SYangtao Li module_dm(zero); 791da177e4SLinus Torvalds 80bf14299fSJana Saout MODULE_AUTHOR("Jana Saout <jana@saout.de>"); 811da177e4SLinus Torvalds MODULE_DESCRIPTION(DM_NAME " dummy target returning zeros"); 821da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 83