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 snapshot: wait for chunks in destructor
dm snapshot: fix register_snapshot deadlock
dm raid1: fix do_failures

+28 -9
+2 -1
drivers/md/dm-raid1.c
··· 656 656 return; 657 657 658 658 if (!ms->log_failure) { 659 - while ((bio = bio_list_pop(failures))) 659 + while ((bio = bio_list_pop(failures))) { 660 660 ms->in_sync = 0; 661 661 dm_rh_mark_nosync(ms->rh, bio, bio->bi_size, 0); 662 + } 662 663 return; 663 664 } 664 665
+24 -8
drivers/md/dm-snap.c
··· 229 229 */ 230 230 static int register_snapshot(struct dm_snapshot *snap) 231 231 { 232 - struct origin *o; 232 + struct origin *o, *new_o; 233 233 struct block_device *bdev = snap->origin->bdev; 234 + 235 + new_o = kmalloc(sizeof(*new_o), GFP_KERNEL); 236 + if (!new_o) 237 + return -ENOMEM; 234 238 235 239 down_write(&_origins_lock); 236 240 o = __lookup_origin(bdev); 237 241 238 - if (!o) { 242 + if (o) 243 + kfree(new_o); 244 + else { 239 245 /* New origin */ 240 - o = kmalloc(sizeof(*o), GFP_KERNEL); 241 - if (!o) { 242 - up_write(&_origins_lock); 243 - return -ENOMEM; 244 - } 246 + o = new_o; 245 247 246 248 /* Initialise the struct */ 247 249 INIT_LIST_HEAD(&o->snapshots); ··· 370 368 struct dm_snap_pending_exception *pe = mempool_alloc(s->pending_pool, 371 369 GFP_NOIO); 372 370 371 + atomic_inc(&s->pending_exceptions_count); 373 372 pe->snap = s; 374 373 375 374 return pe; ··· 378 375 379 376 static void free_pending_exception(struct dm_snap_pending_exception *pe) 380 377 { 381 - mempool_free(pe, pe->snap->pending_pool); 378 + struct dm_snapshot *s = pe->snap; 379 + 380 + mempool_free(pe, s->pending_pool); 381 + smp_mb__before_atomic_dec(); 382 + atomic_dec(&s->pending_exceptions_count); 382 383 } 383 384 384 385 static void insert_completed_exception(struct dm_snapshot *s, ··· 607 600 608 601 s->valid = 1; 609 602 s->active = 0; 603 + atomic_set(&s->pending_exceptions_count, 0); 610 604 init_rwsem(&s->lock); 611 605 spin_lock_init(&s->pe_lock); 612 606 s->ti = ti; ··· 733 725 /* Prevent further origin writes from using this snapshot. */ 734 726 /* After this returns there can be no new kcopyd jobs. */ 735 727 unregister_snapshot(s); 728 + 729 + while (atomic_read(&s->pending_exceptions_count)) 730 + yield(); 731 + /* 732 + * Ensure instructions in mempool_destroy aren't reordered 733 + * before atomic_read. 734 + */ 735 + smp_mb(); 736 736 737 737 #ifdef CONFIG_DM_DEBUG 738 738 for (i = 0; i < DM_TRACKED_CHUNK_HASH_SIZE; i++)
+2
drivers/md/dm-snap.h
··· 160 160 161 161 mempool_t *pending_pool; 162 162 163 + atomic_t pending_exceptions_count; 164 + 163 165 struct exception_table pending; 164 166 struct exception_table complete; 165 167