History

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

Linus Torvalds committed 18 years ago

Commit 7f82f002 parents d6c3112 879129d3 files · +28 −9Browse files

Unified · Split

3 files
  1. drivers/md/dm-raid1.c +2 −1
  2. drivers/md/dm-snap.c +24 −8
  3. drivers/md/dm-snap.h +2 −0
drivers/md/dm-raid1.c+2−1
@@ -656,9 +656,10 @@ static void do_failures(struct mirror_set *ms, struct bio_list *failures) · 655 unmodified lines
656656 return;
657657
658658 if (!ms->log_failure) {
659− while ((bio = bio_list_pop(failures)))
659+ while ((bio = bio_list_pop(failures))) {
660660 ms->in_sync = 0;
661661 dm_rh_mark_nosync(ms->rh, bio, bio->bi_size, 0);
662+ }
662663 return;
663664 }
664665
drivers/md/dm-snap.c+24−8
@@ -229,19 +229,21 @@ static void __insert_origin(struct origin *o) · 228 unmodified lines
229229 */
230230 static int register_snapshot(struct dm_snapshot *snap)
231231 {
232− struct origin *o;
232+ struct origin *o, *new_o;
233233 struct block_device *bdev = snap->origin->bdev;
234234
235+ new_o = kmalloc(sizeof(*new_o), GFP_KERNEL);
236+ if (!new_o)
237+ return -ENOMEM;
238+
235239 down_write(&_origins_lock);
236240 o = __lookup_origin(bdev);
237241
238− if (!o) {
242+ if (o)
243+ kfree(new_o);
244+ else {
239245 /* 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;
245247
246248 /* Initialise the struct */
247249 INIT_LIST_HEAD(&o->snapshots);
@@ -368,6 +370,7 @@ static struct dm_snap_pending_exception *alloc_pending_exception(struct dm_snaps · 120 unmodified lines
368370 struct dm_snap_pending_exception *pe = mempool_alloc(s->pending_pool,
369371 GFP_NOIO);
370372
373+ atomic_inc(&s->pending_exceptions_count);
371374 pe->snap = s;
372375
373376 return pe;
@@ -375,7 +378,11 @@ static struct dm_snap_pending_exception *alloc_pending_exception(struct dm_snaps · 1 unmodified line
375378
376379 static void free_pending_exception(struct dm_snap_pending_exception *pe)
377380 {
378− mempool_free(pe, pe->snap->pending_pool);
381+ struct dm_snapshot *s = pe->snap;
382+
383+ mempool_free(pe, s->pending_pool);
384+ smp_mb__before_atomic_dec();
385+ atomic_dec(&s->pending_exceptions_count);
379386 }
380387
381388 static void insert_completed_exception(struct dm_snapshot *s,
@@ -600,6 +607,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) · 218 unmodified lines
600607
601608 s->valid = 1;
602609 s->active = 0;
610+ atomic_set(&s->pending_exceptions_count, 0);
603611 init_rwsem(&s->lock);
604612 spin_lock_init(&s->pe_lock);
605613 s->ti = ti;
@@ -726,6 +734,14 @@ static void snapshot_dtr(struct dm_target *ti) · 120 unmodified lines
726734 /* After this returns there can be no new kcopyd jobs. */
727735 unregister_snapshot(s);
728736
737+ while (atomic_read(&s->pending_exceptions_count))
738+ yield();
739+ /*
740+ * Ensure instructions in mempool_destroy aren't reordered
741+ * before atomic_read.
742+ */
743+ smp_mb();
744+
729745 #ifdef CONFIG_DM_DEBUG
730746 for (i = 0; i < DM_TRACKED_CHUNK_HASH_SIZE; i++)
731747 BUG_ON(!hlist_empty(&s->tracked_chunk_hash[i]));
drivers/md/dm-snap.h+2−0
@@ -160,6 +160,8 @@ struct dm_snapshot { · 159 unmodified lines
160160
161161 mempool_t *pending_pool;
162162
163+ atomic_t pending_exceptions_count;
164+
163165 struct exception_table pending;
164166 struct exception_table complete;
165167

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t