Commit 286d938b authored by Alasdair G. Kergon's avatar Alasdair G. Kergon Committed by Linus Torvalds

[PATCH] Device-mapper: dm-zero

Add dm-zero target
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 4da29aba
...@@ -193,5 +193,12 @@ config DM_MIRROR ...@@ -193,5 +193,12 @@ config DM_MIRROR
Allow volume managers to mirror logical volumes, also Allow volume managers to mirror logical volumes, also
needed for live data migration tools such as 'pvmove'. needed for live data migration tools such as 'pvmove'.
config DM_ZERO
tristate "Zero target (EXPERIMENTAL)"
depends on BLK_DEV_DM && EXPERIMENTAL
---help---
A target that discards writes, and returns all zeroes for
reads. Useful in some recovery situations.
endmenu endmenu
...@@ -28,6 +28,7 @@ obj-$(CONFIG_BLK_DEV_DM) += dm-mod.o ...@@ -28,6 +28,7 @@ obj-$(CONFIG_BLK_DEV_DM) += dm-mod.o
obj-$(CONFIG_DM_CRYPT) += dm-crypt.o obj-$(CONFIG_DM_CRYPT) += dm-crypt.o
obj-$(CONFIG_DM_SNAPSHOT) += dm-snapshot.o obj-$(CONFIG_DM_SNAPSHOT) += dm-snapshot.o
obj-$(CONFIG_DM_MIRROR) += dm-mirror.o obj-$(CONFIG_DM_MIRROR) += dm-mirror.o
obj-$(CONFIG_DM_ZERO) += dm-zero.o
quiet_cmd_unroll = UNROLL $@ quiet_cmd_unroll = UNROLL $@
cmd_unroll = $(PERL) $(srctree)/$(src)/unroll.pl $(UNROLL) \ cmd_unroll = $(PERL) $(srctree)/$(src)/unroll.pl $(UNROLL) \
......
/*
* Copyright (C) 2003 Christophe Saout <christophe@saout.de>
*
* 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 __init dm_zero_init(void)
{
int r = dm_register_target(&zero_target);
if (r < 0)
DMERR("zero: register failed %d", r);
return r;
}
void __exit dm_zero_exit(void)
{
int r = dm_unregister_target(&zero_target);
if (r < 0)
DMERR("zero: unregister failed %d", r);
}
module_init(dm_zero_init)
module_exit(dm_zero_exit)
MODULE_AUTHOR("Christophe Saout <christophe@saout.de>");
MODULE_DESCRIPTION(DM_NAME " dummy target returning zeros");
MODULE_LICENSE("GPL");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment