2004-06-02 15:50:23

by Alasdair G Kergon

[permalink] [raw]
Subject: [PATCH] 5/5: Device-mapper: dm-zero

dm-zero

--- diff/drivers/md/Kconfig 2004-06-01 19:56:27.000000000 -0500
+++ source/drivers/md/Kconfig 2004-06-01 19:56:47.000000000 -0500
@@ -193,5 +193,12 @@
Allow volume managers to mirror logical volumes, also
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

--- diff/drivers/md/Makefile 2004-06-01 19:56:27.000000000 -0500
+++ source/drivers/md/Makefile 2004-06-01 19:56:47.000000000 -0500
@@ -28,6 +28,7 @@
obj-$(CONFIG_DM_CRYPT) += dm-crypt.o
obj-$(CONFIG_DM_SNAPSHOT) += dm-snapshot.o
obj-$(CONFIG_DM_MIRROR) += dm-mirror.o
+obj-$(CONFIG_DM_ZERO) += dm-zero.o

quiet_cmd_unroll = UNROLL $@
cmd_unroll = $(PERL) $(srctree)/$(src)/unroll.pl $(UNROLL) \
--- diff/drivers/md/dm-zero.c 1969-12-31 18:00:00.000000000 -0600
+++ source/drivers/md/dm-zero.c 2004-06-01 19:56:47.000000000 -0500
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2003 Christophe Saout <[email protected]>
+ *
+ * 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 <[email protected]>");
+MODULE_DESCRIPTION(DM_NAME " dummy target returning zeros");
+MODULE_LICENSE("GPL");


2004-06-02 16:04:11

by Christophe Saout

[permalink] [raw]
Subject: Re: [PATCH] 5/5: Device-mapper: dm-zero

Am Mi, den 02.06.2004 um 16:46 Uhr +0100 schrieb Alasdair G Kergon:

> + bio_for_each_segment(bv, bio, i) {
> + char *data = bvec_kmap_irq(bv, &flags);
> + memset(data, 0, bv->bv_len);

I just noticed, there's a

flush_dcache_page(bv->bv_page);

missing here.

> + bvec_kunmap_irq(bv, &flags);
> + }


Attachments:
signature.asc (189.00 B)
Dies ist ein digital signierter Nachrichtenteil

2004-06-02 16:09:28

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH] 5/5: Device-mapper: dm-zero

On Wed, Jun 02 2004, Christophe Saout wrote:
> Am Mi, den 02.06.2004 um 16:46 Uhr +0100 schrieb Alasdair G Kergon:
>
> > + bio_for_each_segment(bv, bio, i) {
> > + char *data = bvec_kmap_irq(bv, &flags);
> > + memset(data, 0, bv->bv_len);
>
> I just noticed, there's a
>
> flush_dcache_page(bv->bv_page);
>
> missing here.
>
> > + bvec_kunmap_irq(bv, &flags);

and even worse, passing bad argument to bvec_kunmap_irq().

--
Jens Axboe

2004-06-02 16:17:31

by Christophe Saout

[permalink] [raw]
Subject: Re: [PATCH] 5/5: Device-mapper: dm-zero

Am Mi, den 02.06.2004 um 18:09 Uhr +0200 schrieb Jens Axboe:
> On Wed, Jun 02 2004, Christophe Saout wrote:
> > Am Mi, den 02.06.2004 um 16:46 Uhr +0100 schrieb Alasdair G Kergon:
> >
> > > + bio_for_each_segment(bv, bio, i) {
> > > + char *data = bvec_kmap_irq(bv, &flags);
> > > + memset(data, 0, bv->bv_len);
> >
> > I just noticed, there's a
> >
> > flush_dcache_page(bv->bv_page);
> >
> > missing here.
> >
> > > + bvec_kunmap_irq(bv, &flags);
>
> and even worse, passing bad argument to bvec_kunmap_irq().

Oops. Right.

> extern inline void bvec_kunmap_irq(char *buffer, unsigned long *flags)
> {
> unsigned long ptr = (unsigned long) buffer & PAGE_MASK;
>
> kunmap_atomic((void *) ptr, KM_BIO_SRC_IRQ);
> local_irq_restore(*flags);
> }

What does this & PAGE_MASK do? This looks wrong too.


Attachments:
signature.asc (189.00 B)
Dies ist ein digital signierter Nachrichtenteil

2004-06-02 16:27:11

by Christophe Saout

[permalink] [raw]
Subject: Re: [PATCH] 5/5: Device-mapper: dm-zero

Am Mi, den 02.06.2004 um 18:17 Uhr +0200 schrieb Christophe Saout:

> What does this & PAGE_MASK do? This looks wrong too.

Sorry, please forget this.


--- linux.orig/drivers/md/dm-zero.c 2004-06-02 18:24:38.231186664 +0200
+++ linux/drivers/ms/dm-zero.c 2004-06-02 18:24:55.645539280 +0200
@@ -35,7 +35,8 @@
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);
+ flush_dcache_page(bv->bv_page);
+ bvec_kunmap_irq(data, &flags);
}
}



Attachments:
signature.asc (189.00 B)
Dies ist ein digital signierter Nachrichtenteil

2004-06-02 19:28:07

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH] 5/5: Device-mapper: dm-zero

On Wed, Jun 02 2004, Christophe Saout wrote:
> Am Mi, den 02.06.2004 um 18:17 Uhr +0200 schrieb Christophe Saout:
>
> > What does this & PAGE_MASK do? This looks wrong too.

:)

> Sorry, please forget this.
>
>
> --- linux.orig/drivers/md/dm-zero.c 2004-06-02 18:24:38.231186664 +0200
> +++ linux/drivers/ms/dm-zero.c 2004-06-02 18:24:55.645539280 +0200
> @@ -35,7 +35,8 @@
> 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);
> + flush_dcache_page(bv->bv_page);
> + bvec_kunmap_irq(data, &flags);
> }
> }

That looks good.


--
Jens Axboe