Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7f82f000 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 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
parents d6c3112a 879129d2
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -656,9 +656,10 @@ static void do_failures(struct mirror_set *ms, struct bio_list *failures)
		return;

	if (!ms->log_failure) {
		while ((bio = bio_list_pop(failures)))
		while ((bio = bio_list_pop(failures))) {
			ms->in_sync = 0;
			dm_rh_mark_nosync(ms->rh, bio, bio->bi_size, 0);
		}
		return;
	}

+24 −8
Original line number Diff line number Diff line
@@ -229,19 +229,21 @@ static void __insert_origin(struct origin *o)
 */
static int register_snapshot(struct dm_snapshot *snap)
{
	struct origin *o;
	struct origin *o, *new_o;
	struct block_device *bdev = snap->origin->bdev;

	new_o = kmalloc(sizeof(*new_o), GFP_KERNEL);
	if (!new_o)
		return -ENOMEM;

	down_write(&_origins_lock);
	o = __lookup_origin(bdev);

	if (!o) {
	if (o)
		kfree(new_o);
	else {
		/* New origin */
		o = kmalloc(sizeof(*o), GFP_KERNEL);
		if (!o) {
			up_write(&_origins_lock);
			return -ENOMEM;
		}
		o = new_o;

		/* Initialise the struct */
		INIT_LIST_HEAD(&o->snapshots);
@@ -368,6 +370,7 @@ static struct dm_snap_pending_exception *alloc_pending_exception(struct dm_snaps
	struct dm_snap_pending_exception *pe = mempool_alloc(s->pending_pool,
							     GFP_NOIO);

	atomic_inc(&s->pending_exceptions_count);
	pe->snap = s;

	return pe;
@@ -375,7 +378,11 @@ static struct dm_snap_pending_exception *alloc_pending_exception(struct dm_snaps

static void free_pending_exception(struct dm_snap_pending_exception *pe)
{
	mempool_free(pe, pe->snap->pending_pool);
	struct dm_snapshot *s = pe->snap;

	mempool_free(pe, s->pending_pool);
	smp_mb__before_atomic_dec();
	atomic_dec(&s->pending_exceptions_count);
}

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)

	s->valid = 1;
	s->active = 0;
	atomic_set(&s->pending_exceptions_count, 0);
	init_rwsem(&s->lock);
	spin_lock_init(&s->pe_lock);
	s->ti = ti;
@@ -726,6 +734,14 @@ static void snapshot_dtr(struct dm_target *ti)
	/* After this returns there can be no new kcopyd jobs. */
	unregister_snapshot(s);

	while (atomic_read(&s->pending_exceptions_count))
		yield();
	/*
	 * Ensure instructions in mempool_destroy aren't reordered
	 * before atomic_read.
	 */
	smp_mb();

#ifdef CONFIG_DM_DEBUG
	for (i = 0; i < DM_TRACKED_CHUNK_HASH_SIZE; i++)
		BUG_ON(!hlist_empty(&s->tracked_chunk_hash[i]));
+2 −0
Original line number Diff line number Diff line
@@ -160,6 +160,8 @@ struct dm_snapshot {

	mempool_t *pending_pool;

	atomic_t pending_exceptions_count;

	struct exception_table pending;
	struct exception_table complete;