mirror of
git://sourceware.org/git/lvm2.git
synced 2025-02-23 13:57:47 +03:00
o Bug fix to LV_BMAP ioctl()
o Account for I/O against tables rather than logical volume devices
This commit is contained in:
parent
25f2335b7d
commit
7439f2e6c0
@ -129,6 +129,9 @@ struct dm_table *dm_table_create(void)
|
||||
|
||||
memset(t, 0, sizeof(*t));
|
||||
|
||||
atomic_set(&t->pending, 0);
|
||||
init_waitqueue_head(&t->wait);
|
||||
|
||||
/* allocate a single nodes worth of targets to
|
||||
begin with */
|
||||
t->hardsect_size = PAGE_CACHE_SIZE;
|
||||
|
@ -47,7 +47,7 @@ const char *_name = "device-mapper";
|
||||
int _version[3] = { 0, 1, 0 };
|
||||
|
||||
struct io_hook {
|
||||
struct mapped_device *md;
|
||||
struct dm_table *table;
|
||||
struct target *target;
|
||||
int rw;
|
||||
void (*end_io) (struct buffer_head * bh, int uptodate);
|
||||
@ -304,9 +304,9 @@ static void dec_pending(struct buffer_head *bh, int uptodate)
|
||||
return;
|
||||
}
|
||||
|
||||
if (atomic_dec_and_test(&ih->md->pending))
|
||||
if (atomic_dec_and_test(&ih->table->pending))
|
||||
/* nudge anyone waiting on suspend queue */
|
||||
wake_up(&ih->md->wait);
|
||||
wake_up(&ih->table->wait);
|
||||
|
||||
bh->b_end_io = ih->end_io;
|
||||
bh->b_private = ih->context;
|
||||
@ -355,15 +355,12 @@ static inline int __map_buffer(struct mapped_device *md,
|
||||
fn = ti->type->map;
|
||||
context = ti->private;
|
||||
|
||||
if (!fn)
|
||||
return 0;
|
||||
|
||||
ih = alloc_io_hook();
|
||||
|
||||
if (!ih)
|
||||
return 0;
|
||||
|
||||
ih->md = md;
|
||||
ih->table = md->map;
|
||||
ih->rw = rw;
|
||||
ih->target = ti;
|
||||
ih->end_io = bh->b_end_io;
|
||||
@ -373,7 +370,7 @@ static inline int __map_buffer(struct mapped_device *md,
|
||||
|
||||
if (r > 0) {
|
||||
/* hook the end io request fn */
|
||||
atomic_inc(&md->pending);
|
||||
atomic_inc(&md->map->pending);
|
||||
bh->b_end_io = dec_pending;
|
||||
bh->b_private = ih;
|
||||
|
||||
@ -435,16 +432,21 @@ static int dm_user_bmap(struct inode *inode, struct lv_bmap *lvb)
|
||||
|
||||
err = -EINVAL;
|
||||
down_read(&_dev_lock);
|
||||
if (test_bit(DM_ACTIVE, &md->state) && md->map) {
|
||||
if (test_bit(DM_ACTIVE, &md->state)) {
|
||||
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, READ, t->private);
|
||||
if (bh.b_private) {
|
||||
struct io_hook *ih = (struct io_hook *)bh.b_private;
|
||||
free_io_hook(ih);
|
||||
}
|
||||
err = (err == 0) ? -EINVAL : 0;
|
||||
}
|
||||
}
|
||||
up_read(&_dev_lock);
|
||||
|
||||
if (err >= 0) {
|
||||
if (err == 0) {
|
||||
if (put_user(kdev_t_to_nr(bh.b_rdev), &lvb->lv_dev))
|
||||
return -EFAULT;
|
||||
if (put_user(bh.b_rsector / (bh.b_size >> 9), &lvb->lv_dev))
|
||||
@ -553,8 +555,6 @@ static struct mapped_device *alloc_dev(int minor)
|
||||
md->name[0] = '\0';
|
||||
md->state = 0;
|
||||
|
||||
init_waitqueue_head(&md->wait);
|
||||
|
||||
_devs[minor] = md;
|
||||
up_write(&_dev_lock);
|
||||
|
||||
@ -796,11 +796,11 @@ void dm_suspend(struct mapped_device *md)
|
||||
up_write(&_dev_lock);
|
||||
|
||||
/* wait for all the pending io to flush */
|
||||
add_wait_queue(&md->wait, &wait);
|
||||
add_wait_queue(&md->map->wait, &wait);
|
||||
current->state = TASK_UNINTERRUPTIBLE;
|
||||
do {
|
||||
down_write(&_dev_lock);
|
||||
if (!atomic_read(&md->pending))
|
||||
if (!atomic_read(&md->map->pending))
|
||||
break;
|
||||
|
||||
up_write(&_dev_lock);
|
||||
@ -809,7 +809,7 @@ void dm_suspend(struct mapped_device *md)
|
||||
} while (1);
|
||||
|
||||
current->state = TASK_RUNNING;
|
||||
remove_wait_queue(&md->wait, &wait);
|
||||
remove_wait_queue(&md->map->wait, &wait);
|
||||
|
||||
md->map = 0;
|
||||
up_write(&_dev_lock);
|
||||
|
@ -177,6 +177,9 @@ struct dm_table {
|
||||
int num_allocated;
|
||||
offset_t *highs;
|
||||
struct target *targets;
|
||||
|
||||
atomic_t pending;
|
||||
wait_queue_head_t wait;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -190,9 +193,6 @@ struct mapped_device {
|
||||
int use_count;
|
||||
int state;
|
||||
|
||||
wait_queue_head_t wait;
|
||||
atomic_t pending; /* # of 'in flight' buffers */
|
||||
|
||||
/* a list of io's that arrived while we were suspended */
|
||||
struct deferred_io *deferred;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user