1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2003 Jana Saout <jana@saout.de> 4 * 5 * This file is released under the GPL. 6 */ 7 8 #include <linux/device-mapper.h> 9 10 #include <linux/module.h> 11 #include <linux/init.h> 12 #include <linux/bio.h> 13 14 #define DM_MSG_PREFIX "zero" 15 16 /* 17 * Construct a dummy mapping that only returns zeros 18 */ 19 static int zero_ctr(struct dm_target *ti, unsigned int argc, char **argv) 20 { 21 if (argc != 0) { 22 ti->error = "No arguments required"; 23 return -EINVAL; 24 } 25 26 /* 27 * Silently drop discards, avoiding -EOPNOTSUPP. 28 */ 29 ti->num_discard_bios = 1; 30 31 return 0; 32 } 33 34 /* 35 * Return zeros only on reads 36 */ 37 static int zero_map(struct dm_target *ti, struct bio *bio) 38 { 39 switch (bio_op(bio)) { 40 case REQ_OP_READ: 41 if (bio->bi_opf & REQ_RAHEAD) { 42 /* readahead of null bytes only wastes buffer cache */ 43 return DM_MAPIO_KILL; 44 } 45 zero_fill_bio(bio); 46 break; 47 case REQ_OP_WRITE: 48 /* writes get silently dropped */ 49 break; 50 default: 51 return DM_MAPIO_KILL; 52 } 53 54 bio_endio(bio); 55 56 /* accepted bio, don't make new request */ 57 return DM_MAPIO_SUBMITTED; 58 } 59 60 static struct target_type zero_target = { 61 .name = "zero", 62 .version = {1, 1, 0}, 63 .features = DM_TARGET_NOWAIT, 64 .module = THIS_MODULE, 65 .ctr = zero_ctr, 66 .map = zero_map, 67 }; 68 69 static int __init dm_zero_init(void) 70 { 71 int r = dm_register_target(&zero_target); 72 73 if (r < 0) 74 DMERR("register failed %d", r); 75 76 return r; 77 } 78 79 static void __exit dm_zero_exit(void) 80 { 81 dm_unregister_target(&zero_target); 82 } 83 84 module_init(dm_zero_init) 85 module_exit(dm_zero_exit) 86 87 MODULE_AUTHOR("Jana Saout <jana@saout.de>"); 88 MODULE_DESCRIPTION(DM_NAME " dummy target returning zeros"); 89 MODULE_LICENSE("GPL"); 90