mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-11 20:58:50 +03:00
o Targets now get rw passed through so they can do COW for example
o Added error handler (not sure that this is the "correct" way to do this at the moment, so its a bit exprimental for now)
This commit is contained in:
parent
875fa752a0
commit
de37c802d7
@ -46,7 +46,8 @@ typedef int (*dm_ctr_fn)(struct dm_table *t,
|
|||||||
dm_error_fn fn, void *private);
|
dm_error_fn fn, void *private);
|
||||||
|
|
||||||
typedef void (*dm_dtr_fn)(struct dm_table *t, void *c);
|
typedef void (*dm_dtr_fn)(struct dm_table *t, void *c);
|
||||||
typedef int (*dm_map_fn)(struct buffer_head *bh, void *context);
|
typedef int (*dm_map_fn)(struct buffer_head *bh, int rw, void *context);
|
||||||
|
typedef int (*dm_err_fn)(struct buffer_head *bh, int rw, void *context);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* information about a target type
|
* information about a target type
|
||||||
@ -59,6 +60,7 @@ struct target_type {
|
|||||||
dm_ctr_fn ctr;
|
dm_ctr_fn ctr;
|
||||||
dm_dtr_fn dtr;
|
dm_dtr_fn dtr;
|
||||||
dm_map_fn map;
|
dm_map_fn map;
|
||||||
|
dm_err_fn err;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ static void linear_dtr(struct dm_table *t, void *c)
|
|||||||
kfree(c);
|
kfree(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int linear_map(struct buffer_head *bh, void *context)
|
static int linear_map(struct buffer_head *bh, int rw, void *context)
|
||||||
{
|
{
|
||||||
struct linear_c *lc = (struct linear_c *) context;
|
struct linear_c *lc = (struct linear_c *) context;
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ static void io_err_dtr(struct dm_table *t, void *c)
|
|||||||
/* empty */
|
/* empty */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int io_err_map(struct buffer_head *bh, void *context)
|
static int io_err_map(struct buffer_head *bh, int rw, void *context)
|
||||||
{
|
{
|
||||||
buffer_IO_error(bh);
|
buffer_IO_error(bh);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -48,6 +48,8 @@ int _version[3] = { 0, 1, 0 };
|
|||||||
|
|
||||||
struct io_hook {
|
struct io_hook {
|
||||||
struct mapped_device *md;
|
struct mapped_device *md;
|
||||||
|
struct target *target;
|
||||||
|
int rw;
|
||||||
void (*end_io) (struct buffer_head * bh, int uptodate);
|
void (*end_io) (struct buffer_head * bh, int uptodate);
|
||||||
void *context;
|
void *context;
|
||||||
};
|
};
|
||||||
@ -297,6 +299,11 @@ static void dec_pending(struct buffer_head *bh, int uptodate)
|
|||||||
{
|
{
|
||||||
struct io_hook *ih = bh->b_private;
|
struct io_hook *ih = bh->b_private;
|
||||||
|
|
||||||
|
if (!uptodate && ih->target->type->err) {
|
||||||
|
if (ih->target->type->err(bh, ih->rw, ih->target->private))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (atomic_dec_and_test(&ih->md->pending))
|
if (atomic_dec_and_test(&ih->md->pending))
|
||||||
/* nudge anyone waiting on suspend queue */
|
/* nudge anyone waiting on suspend queue */
|
||||||
wake_up(&ih->md->wait);
|
wake_up(&ih->md->wait);
|
||||||
@ -337,11 +344,11 @@ static int queue_io(struct mapped_device *md, struct buffer_head *bh, int rw)
|
|||||||
* do the bh mapping for a given leaf
|
* do the bh mapping for a given leaf
|
||||||
*/
|
*/
|
||||||
static inline int __map_buffer(struct mapped_device *md,
|
static inline int __map_buffer(struct mapped_device *md,
|
||||||
struct buffer_head *bh, int leaf)
|
struct buffer_head *bh, int rw, int leaf)
|
||||||
{
|
{
|
||||||
dm_map_fn fn;
|
dm_map_fn fn;
|
||||||
void *context;
|
void *context;
|
||||||
struct io_hook *ih = 0;
|
struct io_hook *ih = NULL;
|
||||||
int r;
|
int r;
|
||||||
struct target *ti = md->map->targets + leaf;
|
struct target *ti = md->map->targets + leaf;
|
||||||
|
|
||||||
@ -357,10 +364,12 @@ static inline int __map_buffer(struct mapped_device *md,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ih->md = md;
|
ih->md = md;
|
||||||
|
ih->rw = rw;
|
||||||
|
ih->target = ti;
|
||||||
ih->end_io = bh->b_end_io;
|
ih->end_io = bh->b_end_io;
|
||||||
ih->context = bh->b_private;
|
ih->context = bh->b_private;
|
||||||
|
|
||||||
r = fn(bh, context);
|
r = fn(bh, rw, context);
|
||||||
|
|
||||||
if (r > 0) {
|
if (r > 0) {
|
||||||
/* hook the end io request fn */
|
/* hook the end io request fn */
|
||||||
@ -430,7 +439,7 @@ static int dm_user_bmap(struct inode *inode, struct lv_bmap *lvb)
|
|||||||
struct target *t = md->map->targets + __find_node(md->map, &bh);
|
struct target *t = md->map->targets + __find_node(md->map, &bh);
|
||||||
struct target_type *target = t->type;
|
struct target_type *target = t->type;
|
||||||
if (target->flags & TF_BMAP) {
|
if (target->flags & TF_BMAP) {
|
||||||
err = target->map(&bh, t->private);
|
err = target->map(&bh, READ, t->private);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
up_read(&_dev_lock);
|
up_read(&_dev_lock);
|
||||||
@ -473,7 +482,7 @@ static int request(request_queue_t *q, int rw, struct buffer_head *bh)
|
|||||||
down_read(&_dev_lock); /* FIXME: there's still a race here */
|
down_read(&_dev_lock); /* FIXME: there's still a race here */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!__map_buffer(md, bh, __find_node(md->map, bh)))
|
if (!__map_buffer(md, bh, rw, __find_node(md->map, bh)))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
up_read(&_dev_lock);
|
up_read(&_dev_lock);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user