11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2003 Christophe Saout <christophe@saout.de>
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file is released under the GPL.
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7586e80e6ee0d137c7d79fbae183bb37bc60ee97eMikulas Patocka#include <linux/device-mapper.h>
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/bio.h>
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1372d9486169a2a8353e022813185ba2f32d7dde69Alasdair G Kergon#define DM_MSG_PREFIX "zero"
1472d9486169a2a8353e022813185ba2f32d7dde69Alasdair G Kergon
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Construct a dummy mapping that only returns zeros
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int zero_ctr(struct dm_target *ti, unsigned int argc, char **argv)
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (argc != 0) {
2172d9486169a2a8353e022813185ba2f32d7dde69Alasdair G Kergon		ti->error = "No arguments required";
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EINVAL;
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
25f8facb61b5095488a4d78fa78116ef4f4b82bc4dMike Snitzer	/*
26f8facb61b5095488a4d78fa78116ef4f4b82bc4dMike Snitzer	 * Silently drop discards, avoiding -EOPNOTSUPP.
27f8facb61b5095488a4d78fa78116ef4f4b82bc4dMike Snitzer	 */
28f8facb61b5095488a4d78fa78116ef4f4b82bc4dMike Snitzer	ti->num_discard_requests = 1;
29f8facb61b5095488a4d78fa78116ef4f4b82bc4dMike Snitzer
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Return zeros only on reads
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int zero_map(struct dm_target *ti, struct bio *bio,
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		      union map_info *map_context)
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch(bio_rw(bio)) {
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case READ:
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		zero_fill_bio(bio);
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case READA:
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* readahead of null bytes only wastes buffer cache */
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EIO;
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case WRITE:
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* writes get silently dropped */
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
516712ecf8f648118c3363c142196418f89a510b90NeilBrown	bio_endio(bio, 0);
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* accepted bio, don't make new request */
54d2a7ad29a810441e9dacbaddcc2f0c6045390008Kiyoshi Ueda	return DM_MAPIO_SUBMITTED;
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct target_type zero_target = {
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.name   = "zero",
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.version = {1, 0, 0},
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.module = THIS_MODULE,
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.ctr    = zero_ctr,
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.map    = zero_map,
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
655e198d94dd0c3ec7f6138229e2e412c2c6268c38Alasdair G Kergonstatic int __init dm_zero_init(void)
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int r = dm_register_target(&zero_target);
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (r < 0)
7072d9486169a2a8353e022813185ba2f32d7dde69Alasdair G Kergon		DMERR("register failed %d", r);
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return r;
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
755e198d94dd0c3ec7f6138229e2e412c2c6268c38Alasdair G Kergonstatic void __exit dm_zero_exit(void)
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7710d3bd09a3c25df114f74f7f86e1b58d070bef32Mikulas Patocka	dm_unregister_target(&zero_target);
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(dm_zero_init)
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(dm_zero_exit)
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Christophe Saout <christophe@saout.de>");
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION(DM_NAME " dummy target returning zeros");
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL");
86