<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/linux.git/drivers/md/dm-snap.c, branch v2.6.28</title>
<subtitle>Linux kernel stable tree (mirror)</subtitle>
<id>https://git.radix-linux.su/kernel/linux.git/atom?h=v2.6.28</id>
<link rel='self' href='https://git.radix-linux.su/kernel/linux.git/atom?h=v2.6.28'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/'/>
<updated>2008-10-30T13:33:16+00:00</updated>
<entry>
<title>dm snapshot: wait for chunks in destructor</title>
<updated>2008-10-30T13:33:16+00:00</updated>
<author>
<name>Mikulas Patocka</name>
<email>mpatocka@redhat.com</email>
</author>
<published>2008-10-30T13:33:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=879129d208f725267366296b631aef31409cf304'/>
<id>urn:sha1:879129d208f725267366296b631aef31409cf304</id>
<content type='text'>
If there are several snapshots sharing an origin and one is removed
while the origin is being written to, the snapshot's mempool may get
deleted while elements are still referenced.

Prior to dm-snapshot-use-per-device-mempools.patch the pending
exceptions may still have been referenced after the snapshot was
destroyed, but this was not a problem because the shared mempool
was still there.

This patch fixes the problem by tracking the number of mempool elements
in use.

The scenario:
- You have an origin and two snapshots 1 and 2.
- Someone writes to the origin.
- It creates two exceptions in the snapshots, snapshot 1 will be primary
exception, snapshot 2's pending_exception-&gt;primary_pe will point to the
exception in snapshot 1.
- The exceptions are being relocated, relocation of exception 1 finishes
(but it's pending_exception is still allocated, because it is referenced
by an exception from snapshot 2)
- The user lvremoves snapshot 1 --- it calls just suspend (does nothing)
and destructor. md-&gt;pending is zero (there is no I/O submitted to the
snapshot by md layer), so it won't help us.
- The destructor waits for kcopyd jobs to finish on snapshot 1 --- but
there are none.
- The destructor on snapshot 1 cleans up everything.
- The relocation of exception on snapshot 2 finishes, it drops reference
on primary_pe. This frees its primary_pe pointer. Primary_pe points to
pending exception created for snapshot 1. So it frees memory into
non-existing mempool.

Signed-off-by: Mikulas Patocka &lt;mpatocka@redhat.com&gt;
Signed-off-by: Alasdair G Kergon &lt;agk@redhat.com&gt;
</content>
</entry>
<entry>
<title>dm snapshot: fix register_snapshot deadlock</title>
<updated>2008-10-30T13:33:12+00:00</updated>
<author>
<name>Mikulas Patocka</name>
<email>mpatocka@redhat.com</email>
</author>
<published>2008-10-30T13:33:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=60c856c8e2f57a3f69c505735ef66e3719ea0bd6'/>
<id>urn:sha1:60c856c8e2f57a3f69c505735ef66e3719ea0bd6</id>
<content type='text'>
register_snapshot() performs a GFP_KERNEL allocation while holding
_origins_lock for write, but that could write out dirty pages onto a
device that attempts to acquire _origins_lock for read, resulting in
deadlock.

So move the allocation up before taking the lock.

This path is not performance-critical, so it doesn't matter that we
allocate memory and free it if we find that we won't need it.

Signed-off-by: Mikulas Patocka &lt;mpatocka@redhat.com&gt;
Signed-off-by: Alasdair G Kergon &lt;agk@redhat.com&gt;
</content>
</entry>
<entry>
<title>dm snapshot: drop unused last_percent</title>
<updated>2008-10-21T16:44:53+00:00</updated>
<author>
<name>Mikulas Patocka</name>
<email>mpatocka@redhat.com</email>
</author>
<published>2008-10-21T16:44:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=f68d4f3d394da5b1f69d855b8513f4256ccc803e'/>
<id>urn:sha1:f68d4f3d394da5b1f69d855b8513f4256ccc803e</id>
<content type='text'>
The last_percent field is unused - remove it.
(It dates from when events were triggered as each X% filled up.)

Signed-off-by: Mikulas Patocka &lt;mpatocka@redhat.com&gt;
Signed-off-by: Alasdair G Kergon &lt;agk@redhat.com&gt;
</content>
</entry>
<entry>
<title>dm snapshot: fix primary_pe race</title>
<updated>2008-10-21T16:44:51+00:00</updated>
<author>
<name>Mikulas Patocka</name>
<email>mpatocka@redhat.com</email>
</author>
<published>2008-10-21T16:44:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=7c5f78b9d7f21937e46c26db82976df4b459c95c'/>
<id>urn:sha1:7c5f78b9d7f21937e46c26db82976df4b459c95c</id>
<content type='text'>
Fix a race condition with primary_pe ref_count handling.

put_pending_exception runs under dm_snapshot-&gt;lock, it does atomic_dec_and_test
on primary_pe-&gt;ref_count, and later does atomic_read primary_pe-&gt;ref_count.

__origin_write does atomic_dec_and_test on primary_pe-&gt;ref_count without holding
dm_snapshot-&gt;lock.

This opens the following race condition:
Assume two CPUs, CPU1 is executing put_pending_exception (and holding
dm_snapshot-&gt;lock). CPU2 is executing __origin_write in parallel.
primary_pe-&gt;ref_count == 2.

CPU1:
if (primary_pe &amp;&amp; atomic_dec_and_test(&amp;primary_pe-&gt;ref_count))
	origin_bios = bio_list_get(&amp;primary_pe-&gt;origin_bios);
... decrements primary_pe-&gt;ref_count to 1. Doesn't load origin_bios

CPU2:
if (first &amp;&amp; atomic_dec_and_test(&amp;primary_pe-&gt;ref_count)) {
	flush_bios(bio_list_get(&amp;primary_pe-&gt;origin_bios));
	free_pending_exception(primary_pe);
	/* If we got here, pe_queue is necessarily empty. */
	return r;
}
... decrements primary_pe-&gt;ref_count to 0, submits pending bios, frees
primary_pe.

CPU1:
if (!primary_pe || primary_pe != pe)
	free_pending_exception(pe);
... this has no effect.
if (primary_pe &amp;&amp; !atomic_read(&amp;primary_pe-&gt;ref_count))
	free_pending_exception(primary_pe);
... sees ref_count == 0 (written by CPU 2), does double free !!

This bug can happen only if someone is simultaneously writing to both the
origin and the snapshot.

If someone is writing only to the origin, __origin_write will submit kcopyd
request after it decrements primary_pe-&gt;ref_count (so it can't happen that the
finished copy races with primary_pe-&gt;ref_count decrementation).

If someone is writing only to the snapshot, __origin_write isn't invoked at all
and the race can't happen.

The race happens when someone writes to the snapshot --- this creates
pending_exception with primary_pe == NULL and starts copying. Then, someone
writes to the same chunk in the snapshot, and __origin_write races with
termination of already submitted request in pending_complete (that calls
put_pending_exception).

This race may be reason for bugs:
  http://bugzilla.kernel.org/show_bug.cgi?id=11636
  https://bugzilla.redhat.com/show_bug.cgi?id=465825

The patch fixes the code to make sure that:
1. If atomic_dec_and_test(&amp;primary_pe-&gt;ref_count) returns false, the process
must no longer dereference primary_pe (because someone else may free it under
us).
2. If atomic_dec_and_test(&amp;primary_pe-&gt;ref_count) returns true, the process
is responsible for freeing primary_pe.

Signed-off-by: Mikulas Patocka &lt;mpatocka@redhat.com&gt;
Signed-off-by: Alasdair G Kergon &lt;agk@redhat.com&gt;
Cc: stable@kernel.org
</content>
</entry>
<entry>
<title>dm snapshot: use per device mempools</title>
<updated>2008-07-21T11:00:35+00:00</updated>
<author>
<name>Mikulas Patocka</name>
<email>mpatocka@redhat.com</email>
</author>
<published>2008-07-21T11:00:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=92e868122edf08b9fc06b112e7e0c80ab94c1f93'/>
<id>urn:sha1:92e868122edf08b9fc06b112e7e0c80ab94c1f93</id>
<content type='text'>
Change snapshot per-module mempool to per-device mempool.

Per-module mempools could cause a deadlock if multiple
snapshot devices are stacked above each other.

Signed-off-by: Mikulas Patocka &lt;mpatocka@redhat.com&gt;
Signed-off-by: Alasdair G Kergon &lt;agk@redhat.com&gt;
</content>
</entry>
<entry>
<title>dm snapshot: fix race during exception creation</title>
<updated>2008-07-21T11:00:34+00:00</updated>
<author>
<name>Mikulas Patocka</name>
<email>mpatocka@redhat.com</email>
</author>
<published>2008-07-21T11:00:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=a8d41b59f3f5a7ac19452ef442a7fc1b5fa17366'/>
<id>urn:sha1:a8d41b59f3f5a7ac19452ef442a7fc1b5fa17366</id>
<content type='text'>
Fix a race condition that returns incorrect data when a write causes an
exception to be allocated whilst a read is still in flight.

The race condition happens as follows:
* A read to non-reallocated sector in the snapshot is submitted so that the
  read is routed to the original device.
* A write to the original device is submitted. The write causes an exception
  that reallocates the block.  The write proceeds.
* The original read is dequeued and reads the wrong data.

This race can be triggered with CFQ scheduler and one thread writing and
multiple threads reading simultaneously.

(This patch relies upon the earlier dm-kcopyd-per-device.patch to avoid a
deadlock.)

Signed-off-by: Mikulas Patocka &lt;mpatocka@redhat.com&gt;
Signed-off-by: Alasdair G Kergon &lt;agk@redhat.com&gt;
</content>
</entry>
<entry>
<title>dm snapshot: track snapshot reads</title>
<updated>2008-07-21T11:00:32+00:00</updated>
<author>
<name>Mikulas Patocka</name>
<email>mpatocka@redhat.com</email>
</author>
<published>2008-07-21T11:00:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=cd45daffd1f7b53aac0835b23e97f814ec3f10dc'/>
<id>urn:sha1:cd45daffd1f7b53aac0835b23e97f814ec3f10dc</id>
<content type='text'>
Whenever a snapshot read gets mapped through to the origin, track it in
a per-snapshot hash table indexed by chunk number, using memory allocated
from a new per-snapshot mempool.

We need to track these reads to avoid race conditions which will be fixed
by patches that follow.

Signed-off-by: Mikulas Patocka &lt;mpatocka@redhat.com&gt;
Signed-off-by: Alasdair G Kergon &lt;agk@redhat.com&gt;
</content>
</entry>
<entry>
<title>dm: move include files</title>
<updated>2008-04-25T12:26:55+00:00</updated>
<author>
<name>Alasdair G Kergon</name>
<email>agk@redhat.com</email>
</author>
<published>2008-04-24T21:02:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=a765e20eeb423d0fa6a02ffab51141e53bbd93cb'/>
<id>urn:sha1:a765e20eeb423d0fa6a02ffab51141e53bbd93cb</id>
<content type='text'>
Publish the dm-io, dm-log and dm-kcopyd headers in include/linux.

Signed-off-by: Alasdair G Kergon &lt;agk@redhat.com&gt;
</content>
</entry>
<entry>
<title>dm kcopyd: clean interface</title>
<updated>2008-04-25T12:26:44+00:00</updated>
<author>
<name>Heinz Mauelshagen</name>
<email>hjm@redhat.com</email>
</author>
<published>2008-04-24T20:43:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=eb69aca5d3370b81450d68edeebc2bb9a3eb9689'/>
<id>urn:sha1:eb69aca5d3370b81450d68edeebc2bb9a3eb9689</id>
<content type='text'>
Clean up the kcopyd interface to prepare for publishing it in include/linux.

Signed-off-by: Heinz Mauelshagen &lt;hjm@redhat.com&gt;
Signed-off-by: Alasdair G Kergon &lt;agk@redhat.com&gt;
</content>
</entry>
<entry>
<title>dm io: clean interface</title>
<updated>2008-04-25T12:26:43+00:00</updated>
<author>
<name>Heinz Mauelshagen</name>
<email>hjm@redhat.com</email>
</author>
<published>2008-04-24T20:43:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=22a1ceb1e6a7fbce95a1531ff10bb4fb036d4a37'/>
<id>urn:sha1:22a1ceb1e6a7fbce95a1531ff10bb4fb036d4a37</id>
<content type='text'>
Clean up the dm-io interface to prepare for publishing it in include/linux.

Signed-off-by: Heinz Mauelshagen &lt;hjm@redhat.com&gt;
Signed-off-by: Alasdair G Kergon &lt;agk@redhat.com&gt;
</content>
</entry>
</feed>
