mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +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);
|
||||
|
||||
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
|
||||
@ -59,6 +60,7 @@ struct target_type {
|
||||
dm_ctr_fn ctr;
|
||||
dm_dtr_fn dtr;
|
||||
dm_map_fn map;
|
||||
dm_err_fn err;
|
||||
unsigned long flags;
|
||||
};
|
||||
|
||||
|
@ -103,7 +103,7 @@ static void linear_dtr(struct dm_table *t, void *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;
|
||||
|
||||
|
@ -134,7 +134,7 @@ static void io_err_dtr(struct dm_table *t, void *c)
|
||||
/* 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);
|
||||
return 0;
|
||||
|
@ -48,6 +48,8 @@ int _version[3] = { 0, 1, 0 };
|
||||
|
||||
struct io_hook {
|
||||
struct mapped_device *md;
|
||||
struct target *target;
|
||||
int rw;
|
||||
void (*end_io) (struct buffer_head * bh, int uptodate);
|
||||
void *context;
|
||||
};
|
||||
@ -297,6 +299,11 @@ static void dec_pending(struct buffer_head *bh, int uptodate)
|
||||
{
|
||||
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))
|
||||
/* nudge anyone waiting on suspend queue */
|
||||
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
|
||||
*/
|
||||
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;
|
||||
void *context;
|
||||
struct io_hook *ih = 0;
|
||||
struct io_hook *ih = NULL;
|
||||
int r;
|
||||
struct target *ti = md->map->targets + leaf;
|
||||
|
||||
@ -357,10 +364,12 @@ static inline int __map_buffer(struct mapped_device *md,
|
||||
return 0;
|
||||
|
||||
ih->md = md;
|
||||
ih->rw = rw;
|
||||
ih->target = ti;
|
||||
ih->end_io = bh->b_end_io;
|
||||
ih->context = bh->b_private;
|
||||
|
||||
r = fn(bh, context);
|
||||
r = fn(bh, rw, context);
|
||||
|
||||
if (r > 0) {
|
||||
/* 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_type *target = t->type;
|
||||
if (target->flags & TF_BMAP) {
|
||||
err = target->map(&bh, t->private);
|
||||
err = target->map(&bh, READ, t->private);
|
||||
}
|
||||
}
|
||||
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 */
|
||||
}
|
||||
|
||||
if (!__map_buffer(md, bh, __find_node(md->map, bh)))
|
||||
if (!__map_buffer(md, bh, rw, __find_node(md->map, bh)))
|
||||
goto bad;
|
||||
|
||||
up_read(&_dev_lock);
|
||||
|
Loading…
Reference in New Issue
Block a user