--- drivers/md/persistent-data/dm-transaction-manager.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) Index: linux-3.0/drivers/md/persistent-data/dm-transaction-manager.c =================================================================== --- linux-3.0.orig/drivers/md/persistent-data/dm-transaction-manager.c +++ linux-3.0/drivers/md/persistent-data/dm-transaction-manager.c @@ -35,6 +35,7 @@ struct dm_transaction_manager { struct dm_block_manager *bm; struct dm_space_map *sm; + spinlock_t lock; struct hlist_head buckets[HASH_SIZE]; }; @@ -45,12 +46,18 @@ static int is_shadow(struct dm_transacti unsigned bucket = dm_hash_block(b, HASH_MASK); struct shadow_info *si; struct hlist_node *n; + unsigned long flags; + int r = 0; + + spin_lock_irqsave(&tm->lock, flags); hlist_for_each_entry(si, n, tm->buckets + bucket, hlist) if (si->where == b) - return 1; + r = 1; - return 0; + spin_unlock_irqrestore(&tm->lock, flags); + + return r; } /* @@ -61,12 +68,16 @@ static void insert_shadow(struct dm_tran { unsigned bucket; struct shadow_info *si; + unsigned long flags; si = kmalloc(sizeof(*si), GFP_NOIO); if (si) { si->where = b; bucket = dm_hash_block(b, HASH_MASK); + + spin_lock_irqsave(&tm->lock, flags); hlist_add_head(&si->hlist, tm->buckets + bucket); + spin_unlock_irqrestore(&tm->lock, flags); } } @@ -75,8 +86,10 @@ static void wipe_shadow_table(struct dm_ struct shadow_info *si; struct hlist_node *n, *tmp; struct hlist_head *bucket; + unsigned long flags; int i; + spin_lock_irqsave(&tm->lock, flags); for (i = 0; i < HASH_SIZE; i++) { bucket = tm->buckets + i; hlist_for_each_entry_safe(si, n, tmp, bucket, hlist) @@ -84,6 +97,7 @@ static void wipe_shadow_table(struct dm_ INIT_HLIST_HEAD(bucket); } + spin_unlock_irqrestore(&tm->lock, flags); } /*----------------------------------------------------------------*/ @@ -103,6 +117,7 @@ static struct dm_transaction_manager *dm tm->bm = bm; tm->sm = sm; + spin_lock_init(&tm->lock); for (i = 0; i < HASH_SIZE; i++) INIT_HLIST_HEAD(tm->buckets + i);