Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-2.6-dm
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Linus Torvalds committed Oct 1, 2008
2 parents ae1cfb1 + 7253a33 commit 7ac9c1c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 5 deletions.
16 changes: 15 additions & 1 deletion drivers/md/dm-mpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -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? */
Expand Down Expand Up @@ -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;

Expand All @@ -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);
}
}
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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);
}
Expand Down
12 changes: 8 additions & 4 deletions drivers/md/dm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
}

Expand Down

0 comments on commit 7ac9c1c

Please sign in to comment.