This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / drivers / md / dm-zero.c
1 /*
2  * Copyright (C) 2003 Christophe Saout <christophe@saout.de>
3  *
4  * This file is released under the GPL.
5  */
6
7 #include "dm.h"
8
9 #include <linux/module.h>
10 #include <linux/init.h>
11 #include <linux/bio.h>
12
13 /*
14  * Construct a dummy mapping that only returns zeros
15  */
16 static int zero_ctr(struct dm_target *ti, unsigned int argc, char **argv)
17 {
18         if (argc != 0) {
19                 ti->error = "dm-zero: No arguments required";
20                 return -EINVAL;
21         }
22
23         return 0;
24 }
25
26 /*
27  * Fills the bio pages with zeros
28  */
29 static void zero_fill_bio(struct bio *bio)
30 {
31         unsigned long flags;
32         struct bio_vec *bv;
33         int i;
34
35         bio_for_each_segment(bv, bio, i) {
36                 char *data = bvec_kmap_irq(bv, &flags);
37                 memset(data, 0, bv->bv_len);
38                 flush_dcache_page(bv->bv_page);
39                 bvec_kunmap_irq(data, &flags);
40         }
41 }
42
43 /*
44  * Return zeros only on reads
45  */
46 static int zero_map(struct dm_target *ti, struct bio *bio,
47                       union map_info *map_context)
48 {
49         switch(bio_rw(bio)) {
50         case READ:
51                 zero_fill_bio(bio);
52                 break;
53         case READA:
54                 /* readahead of null bytes only wastes buffer cache */
55                 return -EIO;
56         case WRITE:
57                 /* writes get silently dropped */
58                 break;
59         }
60
61         bio_endio(bio, bio->bi_size, 0);
62
63         /* accepted bio, don't make new request */
64         return 0;
65 }
66
67 static struct target_type zero_target = {
68         .name   = "zero",
69         .version = {1, 0, 0},
70         .module = THIS_MODULE,
71         .ctr    = zero_ctr,
72         .map    = zero_map,
73 };
74
75 int __init dm_zero_init(void)
76 {
77         int r = dm_register_target(&zero_target);
78
79         if (r < 0)
80                 DMERR("zero: register failed %d", r);
81
82         return r;
83 }
84
85 void __exit dm_zero_exit(void)
86 {
87         int r = dm_unregister_target(&zero_target);
88
89         if (r < 0)
90                 DMERR("zero: unregister failed %d", r);
91 }
92
93 module_init(dm_zero_init)
94 module_exit(dm_zero_exit)
95
96 MODULE_AUTHOR("Christophe Saout <christophe@saout.de>");
97 MODULE_DESCRIPTION(DM_NAME " dummy target returning zeros");
98 MODULE_LICENSE("GPL");