mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-16 22:10:24 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-2.6-dm
* git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-2.6-dm: dm mpath: add missing path switching locking dm: cope with access beyond end of device in dm_merge_bvec dm: always allow one page in dm_merge_bvec
This commit is contained in:
commit
7ac9c1c24c
@ -63,6 +63,7 @@ struct multipath {
|
||||
|
||||
const char *hw_handler_name;
|
||||
struct work_struct activate_path;
|
||||
struct pgpath *pgpath_to_activate;
|
||||
unsigned nr_priority_groups;
|
||||
struct list_head priority_groups;
|
||||
unsigned pg_init_required; /* pg_init needs calling? */
|
||||
@ -146,6 +147,7 @@ static struct priority_group *alloc_priority_group(void)
|
||||
|
||||
static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct pgpath *pgpath, *tmp;
|
||||
struct multipath *m = ti->private;
|
||||
|
||||
@ -154,6 +156,10 @@ static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti)
|
||||
if (m->hw_handler_name)
|
||||
scsi_dh_detach(bdev_get_queue(pgpath->path.dev->bdev));
|
||||
dm_put_device(ti, pgpath->path.dev);
|
||||
spin_lock_irqsave(&m->lock, flags);
|
||||
if (m->pgpath_to_activate == pgpath)
|
||||
m->pgpath_to_activate = NULL;
|
||||
spin_unlock_irqrestore(&m->lock, flags);
|
||||
free_pgpath(pgpath);
|
||||
}
|
||||
}
|
||||
@ -421,6 +427,7 @@ static void process_queued_ios(struct work_struct *work)
|
||||
__choose_pgpath(m);
|
||||
|
||||
pgpath = m->current_pgpath;
|
||||
m->pgpath_to_activate = m->current_pgpath;
|
||||
|
||||
if ((pgpath && !m->queue_io) ||
|
||||
(!pgpath && !m->queue_if_no_path))
|
||||
@ -1093,8 +1100,15 @@ static void activate_path(struct work_struct *work)
|
||||
int ret;
|
||||
struct multipath *m =
|
||||
container_of(work, struct multipath, activate_path);
|
||||
struct dm_path *path = &m->current_pgpath->path;
|
||||
struct dm_path *path;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&m->lock, flags);
|
||||
path = &m->pgpath_to_activate->path;
|
||||
m->pgpath_to_activate = NULL;
|
||||
spin_unlock_irqrestore(&m->lock, flags);
|
||||
if (!path)
|
||||
return;
|
||||
ret = scsi_dh_activate(bdev_get_queue(path->dev->bdev));
|
||||
pg_init_done(path, ret);
|
||||
}
|
||||
|
@ -837,12 +837,14 @@ static int dm_merge_bvec(struct request_queue *q,
|
||||
struct dm_table *map = dm_get_table(md);
|
||||
struct dm_target *ti;
|
||||
sector_t max_sectors;
|
||||
int max_size;
|
||||
int max_size = 0;
|
||||
|
||||
if (unlikely(!map))
|
||||
return 0;
|
||||
goto out;
|
||||
|
||||
ti = dm_table_find_target(map, bvm->bi_sector);
|
||||
if (!dm_target_is_valid(ti))
|
||||
goto out_table;
|
||||
|
||||
/*
|
||||
* Find maximum amount of I/O that won't need splitting
|
||||
@ -861,14 +863,16 @@ static int dm_merge_bvec(struct request_queue *q,
|
||||
if (max_size && ti->type->merge)
|
||||
max_size = ti->type->merge(ti, bvm, biovec, max_size);
|
||||
|
||||
out_table:
|
||||
dm_table_put(map);
|
||||
|
||||
out:
|
||||
/*
|
||||
* Always allow an entire first page
|
||||
*/
|
||||
if (max_size <= biovec->bv_len && !(bvm->bi_size >> SECTOR_SHIFT))
|
||||
max_size = biovec->bv_len;
|
||||
|
||||
dm_table_put(map);
|
||||
|
||||
return max_size;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user