From: "Jun'ichi Nomura" <j-nomura@ce.jp.nec.com> Fix the bug in dm-raid1.c that the region returned by __rh_alloc() may be freed while it's in use. __rh_alloc() write-unlocks the hash_lock after inserting the new region. Though it read-locks the hash-lock just after that, it's possible that the region was reclaimed by rh_update_states() as the region was clean at the time. CPU0 CPU1 ----------------------------------------------------------------------- __rh_alloc() write_lock(hash_lock) <insert new region to clean list> write_unlock(hash_lock) rh_update_states() write_lock(hash_lock) <move clean regions to freeable list> write_unlock(hash_lock) <free regions in the freeable list> read_lock(hash_lock) <return the region> Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com> Signed-off-by: Andrew Morton <akpm@osdl.org> --- drivers/md/dm-raid1.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) diff -puN drivers/md/dm-raid1.c~md-__rh_alloc-rh_update_states-race-in-dm-raid1c drivers/md/dm-raid1.c --- 25/drivers/md/dm-raid1.c~md-__rh_alloc-rh_update_states-race-in-dm-raid1c 2005-06-16 16:49:41.000000000 -0700 +++ 25-akpm/drivers/md/dm-raid1.c 2005-06-16 16:49:41.000000000 -0700 @@ -269,9 +269,12 @@ static inline struct region *__rh_find(s { struct region *reg; +retry: reg = __rh_lookup(rh, region); - if (!reg) + if (!reg) { reg = __rh_alloc(rh, region); + goto retry; + } return reg; } _