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

+23 -5
+15 -1
drivers/md/dm-mpath.c
··· 63 63 64 64 const char *hw_handler_name; 65 65 struct work_struct activate_path; 66 + struct pgpath *pgpath_to_activate; 66 67 unsigned nr_priority_groups; 67 68 struct list_head priority_groups; 68 69 unsigned pg_init_required; /* pg_init needs calling? */ ··· 147 146 148 147 static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti) 149 148 { 149 + unsigned long flags; 150 150 struct pgpath *pgpath, *tmp; 151 151 struct multipath *m = ti->private; 152 152 ··· 156 154 if (m->hw_handler_name) 157 155 scsi_dh_detach(bdev_get_queue(pgpath->path.dev->bdev)); 158 156 dm_put_device(ti, pgpath->path.dev); 157 + spin_lock_irqsave(&m->lock, flags); 158 + if (m->pgpath_to_activate == pgpath) 159 + m->pgpath_to_activate = NULL; 160 + spin_unlock_irqrestore(&m->lock, flags); 159 161 free_pgpath(pgpath); 160 162 } 161 163 } ··· 427 421 __choose_pgpath(m); 428 422 429 423 pgpath = m->current_pgpath; 424 + m->pgpath_to_activate = m->current_pgpath; 430 425 431 426 if ((pgpath && !m->queue_io) || 432 427 (!pgpath && !m->queue_if_no_path)) ··· 1100 1093 int ret; 1101 1094 struct multipath *m = 1102 1095 container_of(work, struct multipath, activate_path); 1103 - struct dm_path *path = &m->current_pgpath->path; 1096 + struct dm_path *path; 1097 + unsigned long flags; 1104 1098 1099 + spin_lock_irqsave(&m->lock, flags); 1100 + path = &m->pgpath_to_activate->path; 1101 + m->pgpath_to_activate = NULL; 1102 + spin_unlock_irqrestore(&m->lock, flags); 1103 + if (!path) 1104 + return; 1105 1105 ret = scsi_dh_activate(bdev_get_queue(path->dev->bdev)); 1106 1106 pg_init_done(path, ret); 1107 1107 }
+8 -4
drivers/md/dm.c
··· 837 837 struct dm_table *map = dm_get_table(md); 838 838 struct dm_target *ti; 839 839 sector_t max_sectors; 840 - int max_size; 840 + int max_size = 0; 841 841 842 842 if (unlikely(!map)) 843 - return 0; 843 + goto out; 844 844 845 845 ti = dm_table_find_target(map, bvm->bi_sector); 846 + if (!dm_target_is_valid(ti)) 847 + goto out_table; 846 848 847 849 /* 848 850 * Find maximum amount of I/O that won't need splitting ··· 863 861 if (max_size && ti->type->merge) 864 862 max_size = ti->type->merge(ti, bvm, biovec, max_size); 865 863 864 + out_table: 865 + dm_table_put(map); 866 + 867 + out: 866 868 /* 867 869 * Always allow an entire first page 868 870 */ 869 871 if (max_size <= biovec->bv_len && !(bvm->bi_size >> SECTOR_SHIFT)) 870 872 max_size = biovec->bv_len; 871 - 872 - dm_table_put(map); 873 873 874 874 return max_size; 875 875 }