dm-zero target. Provides a block-device version of /dev/zero. This target was originally written by Christophe Saout (http://www.saout.de/misc/). I have made some adjustments for the latest Device-Mapper code in 2.6. This patch is against Joe's 2.6.0-test10-udm1 patchset. diff -Naur linux-2.6.0-test10-udm1/drivers/md/Makefile linux/drivers/md/Makefile --- linux-2.6.0-test10-udm1/drivers/md/Makefile 2003-12-03 11:16:05.000000000 -0600 +++ linux/drivers/md/Makefile 2003-12-03 11:13:30.000000000 -0600 @@ -3,7 +3,7 @@ # dm-mod-objs := dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \ - dm-ioctl.o dm-io.o kcopyd.o dm-daemon.o + dm-ioctl.o dm-io.o kcopyd.o dm-daemon.o dm-zero.o dm-snapshot-objs := dm-snap.o dm-exception-store.o diff -Naur linux-2.6.0-test10-udm1/drivers/md/dm-zero.c linux/drivers/md/dm-zero.c --- linux-2.6.0-test10-udm1/drivers/md/dm-zero.c 1969-12-31 18:00:00.000000000 -0600 +++ linux/drivers/md/dm-zero.c 2003-12-03 11:14:58.000000000 -0600 @@ -0,0 +1,90 @@ +/* + * Copyright (c) Christophe Saout <christophe@xxxxxxxx>, 2003 + * + * This file is released under the GPL. + */ + +#include "dm.h" + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/bio.h> + +/* + * Construct a dummy mapping that only returns zeros + */ +static int zero_ctr(struct dm_target *ti, unsigned int argc, char **argv) +{ + if (argc != 0) { + ti->error = "dm-zero: No arguments required"; + return -EINVAL; + } + + return 0; +} + +/* + * Fills the bio pages with zeros + */ +static void zero_fill_bio(struct bio *bio) +{ + unsigned long flags; + struct bio_vec *bv; + int i; + + bio_for_each_segment(bv, bio, i) { + char *data = bvec_kmap_irq(bv, &flags); + memset(data, 0, bv->bv_len); + bvec_kunmap_irq(bv, &flags); + } +} + +/* + * Return zeros only on reads + */ +static int zero_map(struct dm_target *ti, struct bio *bio, + union map_info *map_context) +{ + switch(bio_rw(bio)) { + case READ: + zero_fill_bio(bio); + break; + case READA: + /* readahead of null bytes only wastes buffer cache */ + return -EIO; + case WRITE: + /* writes get silently dropped */ + break; + } + + bio_endio(bio, bio->bi_size, 0); + + /* accepted bio, don't make new request */ + return 0; +} + +static struct target_type zero_target = { + .name = "zero", + .module = THIS_MODULE, + .ctr = zero_ctr, + .map = zero_map, +}; + +int dm_zero_init(void) +{ + int r = dm_register_target(&zero_target); + + if (r < 0) + DMERR("zero: register failed %d", r); + + return r; +} + +void dm_zero_exit(void) +{ + int r = dm_unregister_target(&zero_target); + + if (r < 0) + DMERR("zero: unregister failed %d", r); +} + diff -Naur linux-2.6.0-test10-udm1/drivers/md/dm.c linux/drivers/md/dm.c --- linux-2.6.0-test10-udm1/drivers/md/dm.c 2003-12-03 11:16:05.000000000 -0600 +++ linux/drivers/md/dm.c 2003-12-03 11:13:39.000000000 -0600 @@ -154,6 +154,7 @@ xx(dm_stripe) xx(kcopyd) xx(dm_interface) + xx(dm_zero) #undef xx }; diff -Naur linux-2.6.0-test10-udm1/drivers/md/dm.h linux/drivers/md/dm.h --- linux-2.6.0-test10-udm1/drivers/md/dm.h 2003-12-03 11:16:05.000000000 -0600 +++ linux/drivers/md/dm.h 2003-12-03 11:14:07.000000000 -0600 @@ -186,6 +186,9 @@ int kcopyd_init(void); void kcopyd_exit(void); +int dm_zero_init(void); +void dm_zero_exit(void); + void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size); #endif