[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
Re: [dm-devel] [RFC] File backed target for device-mapper
- From: Christophe Saout <christophe saout de>
- To: Alasdair G Kergon <agk uk sistina com>
- Cc: dm-devel sistina com
- Subject: Re: [dm-devel] [RFC] File backed target for device-mapper
- Date: Tue Jul 22 18:19:02 2003
Am Mi, 2003-07-23 um 01.17 schrieb Christophe Saout:
> Well, a /dev/zero-like target is very easy (attached).
Damn...
--
Christophe Saout <christophe saout de>
Please avoid sending me Word or PowerPoint attachments.
See http://www.fsf.org/philosophy/no-word-attachments.html
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
*
* This file is released under the GPL.
*/
#include "dm.h"
#include <linux/module.h>
#include <linux/init.h>
#include <linux/bio.h>
/*
* Returns the minimum that is _not_ zero, unless both are zero.
*/
#define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r))
/*
* Combine the io_restrictions with the default restrictions
*/
static void combine_default_restrictions(struct io_restrictions *rs)
{
rs->max_sectors =
min_not_zero(rs->max_sectors, (unsigned short)MAX_SECTORS);
rs->max_phys_segments =
min_not_zero(rs->max_phys_segments, (unsigned short)MAX_PHYS_SEGMENTS);
rs->max_hw_segments =
min_not_zero(rs->max_hw_segments, (unsigned short)MAX_HW_SEGMENTS);
rs->hardsect_size =
max(rs->hardsect_size, (unsigned short)(1 << SECTOR_SHIFT));
rs->max_segment_size =
min_not_zero(rs->max_segment_size, (unsigned int)MAX_SEGMENT_SIZE);
rs->seg_boundary_mask =
min_not_zero(rs->seg_boundary_mask, (unsigned long)0xffffffff);
}
/*
* Construct a dummy mapping that only returns zeroes
*/
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;
}
/*
* FIXME: Since we don't call dm_get_device, we
* have to combine the device limits ourself
*/
combine_default_restrictions(&ti->limits);
return 0;
}
/*
* Fills the bio pages with zeroes
*/
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 zeroes 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 dm_zero_exit(void)
{
int r = dm_unregister_target(&zero_target);
if (r < 0)
DMERR("zero: unregister failed %d", r);
}
/*
* module hooks
*/
module_init(dm_zero_init)
module_exit(dm_zero_exit)
MODULE_AUTHOR("Christophe Saout <christophe saout de>");
MODULE_DESCRIPTION(DM_NAME " dummy target returning zeroes");
MODULE_LICENSE("GPL");
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]