--- /dev/null
+From jejb@kernel.org Thu Oct 23 13:11:21 2008
+From: Andreas Herrmann <andreas.herrmann3@amd.com>
+Date: Thu, 23 Oct 2008 17:35:28 GMT
+Subject: amd_iommu: fix nasty bug that caused ILLEGAL_DEVICE_TABLE_ENTRY errors
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810231735.m9NHZSI0008803@hera.kernel.org>
+
+From: Andreas Herrmann <andreas.herrmann3@amd.com>
+
+commit f609891f428e1c20e270e7c350daf8c93cc459d7 upstream
+
+We are on 64-bit so better use u64 instead of u32 to deal with
+addresses:
+
+static void __init iommu_set_device_table(struct amd_iommu *iommu)
+{
+ u64 entry;
+ ...
+ entry = virt_to_phys(amd_iommu_dev_table);
+ ...
+
+(I am wondering why gcc 4.2.x did not warn about the assignment
+between u32 and unsigned long.)
+
+Cc: iommu@lists.linux-foundation.org
+Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com>
+Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/kernel/amd_iommu_init.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/x86/kernel/amd_iommu_init.c
++++ b/arch/x86/kernel/amd_iommu_init.c
+@@ -210,7 +210,7 @@ static void __init iommu_set_exclusion_r
+ /* Programs the physical address of the device table into the IOMMU hardware */
+ static void __init iommu_set_device_table(struct amd_iommu *iommu)
+ {
+- u32 entry;
++ u64 entry;
+
+ BUG_ON(iommu->mmio_base == NULL);
+
--- /dev/null
+From d9d332e0874f46b91d8ac4604b68ee42b8a7a2c6 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Sun, 19 Oct 2008 10:32:20 -0700
+Subject: anon_vma_prepare: properly lock even newly allocated entries
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit d9d332e0874f46b91d8ac4604b68ee42b8a7a2c6 upstream
+
+The anon_vma code is very subtle, and we end up doing optimistic lookups
+of anon_vmas under RCU in page_lock_anon_vma() with no locking. Other
+CPU's can also see the newly allocated entry immediately after we've
+exposed it by setting "vma->anon_vma" to the new value.
+
+We protect against the anon_vma being destroyed by having the SLAB
+marked as SLAB_DESTROY_BY_RCU, so the RCU lookup can depend on the
+allocation not being destroyed - but it might still be free'd and
+re-allocated here to a new vma.
+
+As a result, we should not do the anon_vma list ops on a newly allocated
+vma without proper locking.
+
+Acked-by: Nick Piggin <npiggin@suse.de>
+Acked-by: Hugh Dickins <hugh@veritas.com>
+Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ mm/rmap.c | 42 ++++++++++++++++++++++++++++++++----------
+ 1 file changed, 32 insertions(+), 10 deletions(-)
+
+--- a/mm/rmap.c
++++ b/mm/rmap.c
+@@ -55,7 +55,33 @@
+
+ struct kmem_cache *anon_vma_cachep;
+
+-/* This must be called under the mmap_sem. */
++/**
++ * anon_vma_prepare - attach an anon_vma to a memory region
++ * @vma: the memory region in question
++ *
++ * This makes sure the memory mapping described by 'vma' has
++ * an 'anon_vma' attached to it, so that we can associate the
++ * anonymous pages mapped into it with that anon_vma.
++ *
++ * The common case will be that we already have one, but if
++ * if not we either need to find an adjacent mapping that we
++ * can re-use the anon_vma from (very common when the only
++ * reason for splitting a vma has been mprotect()), or we
++ * allocate a new one.
++ *
++ * Anon-vma allocations are very subtle, because we may have
++ * optimistically looked up an anon_vma in page_lock_anon_vma()
++ * and that may actually touch the spinlock even in the newly
++ * allocated vma (it depends on RCU to make sure that the
++ * anon_vma isn't actually destroyed).
++ *
++ * As a result, we need to do proper anon_vma locking even
++ * for the new allocation. At the same time, we do not want
++ * to do any locking for the common case of already having
++ * an anon_vma.
++ *
++ * This must be called with the mmap_sem held for reading.
++ */
+ int anon_vma_prepare(struct vm_area_struct *vma)
+ {
+ struct anon_vma *anon_vma = vma->anon_vma;
+@@ -63,20 +89,17 @@ int anon_vma_prepare(struct vm_area_stru
+ might_sleep();
+ if (unlikely(!anon_vma)) {
+ struct mm_struct *mm = vma->vm_mm;
+- struct anon_vma *allocated, *locked;
++ struct anon_vma *allocated;
+
+ anon_vma = find_mergeable_anon_vma(vma);
+- if (anon_vma) {
+- allocated = NULL;
+- locked = anon_vma;
+- spin_lock(&locked->lock);
+- } else {
++ allocated = NULL;
++ if (!anon_vma) {
+ anon_vma = anon_vma_alloc();
+ if (unlikely(!anon_vma))
+ return -ENOMEM;
+ allocated = anon_vma;
+- locked = NULL;
+ }
++ spin_lock(&anon_vma->lock);
+
+ /* page_table_lock to protect against threads */
+ spin_lock(&mm->page_table_lock);
+@@ -87,8 +110,7 @@ int anon_vma_prepare(struct vm_area_stru
+ }
+ spin_unlock(&mm->page_table_lock);
+
+- if (locked)
+- spin_unlock(&locked->lock);
++ spin_unlock(&anon_vma->lock);
+ if (unlikely(allocated))
+ anon_vma_free(allocated);
+ }
--- /dev/null
+From jejb@kernel.org Thu Oct 23 13:12:20 2008
+From: Jeff Layton <sfrench@us.ibm.com>
+Date: Thu, 23 Oct 2008 18:05:02 GMT
+Subject: CIFS: fix saving of resume key before CIFSFindNext
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810231805.m9NI526B029178@hera.kernel.org>
+
+From: Jeff Layton <sfrench@us.ibm.com>
+
+commit a364bc0b37f14ffd66c1f982af42990a9d77fa43 upstream
+
+We recently fixed the cifs readdir code so that it saves the resume key
+before calling CIFSFindNext. Unfortunately, this assumes that we have
+just done a CIFSFindFirst (or FindNext) and have resume info to save.
+This isn't necessarily the case. Fix the code to save resume info if we
+had to reinitiate the search, and after a FindNext.
+
+This fixes connectathon basic test6 against NetApp filers.
+
+Signed-off-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Steve French <sfrench@us.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/cifs/readdir.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/cifs/readdir.c
++++ b/fs/cifs/readdir.c
+@@ -762,14 +762,15 @@ static int find_cifs_entry(const int xid
+ rc));
+ return rc;
+ }
++ cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
+ }
+
+ while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
+ (rc == 0) && !cifsFile->srch_inf.endOfSearch) {
+ cFYI(1, ("calling findnext2"));
+- cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
+ rc = CIFSFindNext(xid, pTcon, cifsFile->netfid,
+ &cifsFile->srch_inf);
++ cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
+ if (rc)
+ return -ENOENT;
+ }
--- /dev/null
+From jejb@kernel.org Thu Oct 23 13:10:46 2008
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Thu, 23 Oct 2008 17:35:17 GMT
+Subject: dm exception store: fix misordered writes
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810231735.m9NHZHnu008554@hera.kernel.org>
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 7acedc5b98a2fcff64f00c21110aae7d3ac2f7df upstream
+
+We must zero the next chunk on disk *before* writing out the current chunk, not
+after. Otherwise if the machine crashes at the wrong time, the "end of metadata"
+marker may be missing.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/md/dm-exception-store.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/md/dm-exception-store.c
++++ b/drivers/md/dm-exception-store.c
+@@ -603,17 +603,22 @@ static void persistent_commit(struct exc
+ return;
+
+ /*
++ * If we completely filled the current area, then wipe the next one.
++ */
++ if ((ps->current_committed == ps->exceptions_per_area) &&
++ zero_disk_area(ps, ps->current_area + 1))
++ ps->valid = 0;
++
++ /*
+ * Commit exceptions to disk.
+ */
+- if (area_io(ps, WRITE))
++ if (ps->valid && area_io(ps, WRITE))
+ ps->valid = 0;
+
+ /*
+ * Advance to the next area if this one is full.
+ */
+ if (ps->current_committed == ps->exceptions_per_area) {
+- if (zero_disk_area(ps, ps->current_area + 1))
+- ps->valid = 0;
+ ps->current_committed = 0;
+ ps->current_area++;
+ zero_memory_area(ps);
--- /dev/null
+From jejb@kernel.org Thu Oct 23 13:05:28 2008
+From: Alasdair G Kergon <agk@redhat.com>
+Date: Thu, 23 Oct 2008 17:35:19 GMT
+Subject: dm exception store: refactor zero_area
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810231735.m9NHZJcS008600@hera.kernel.org>
+
+From: Alasdair G Kergon <agk@redhat.com>
+
+commit 7c9e6c17325fab380fbe9c9787680ff7d4a51abd upstream
+
+Use a separate buffer for writing zeroes to the on-disk snapshot
+exception store, make the updating of ps->current_area explicit and
+refactor the code in preparation for the fix in the next patch.
+
+No functional change.
+
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/md/dm-exception-store.c | 103 ++++++++++++++++++++++++++--------------
+ 1 file changed, 69 insertions(+), 34 deletions(-)
+
+--- a/drivers/md/dm-exception-store.c
++++ b/drivers/md/dm-exception-store.c
+@@ -105,6 +105,11 @@ struct pstore {
+ void *area;
+
+ /*
++ * An area of zeros used to clear the next area.
++ */
++ void *zero_area;
++
++ /*
+ * Used to keep track of which metadata area the data in
+ * 'chunk' refers to.
+ */
+@@ -149,6 +154,13 @@ static int alloc_area(struct pstore *ps)
+ if (!ps->area)
+ return r;
+
++ ps->zero_area = vmalloc(len);
++ if (!ps->zero_area) {
++ vfree(ps->area);
++ return r;
++ }
++ memset(ps->zero_area, 0, len);
++
+ return 0;
+ }
+
+@@ -156,6 +168,8 @@ static void free_area(struct pstore *ps)
+ {
+ vfree(ps->area);
+ ps->area = NULL;
++ vfree(ps->zero_area);
++ ps->zero_area = NULL;
+ }
+
+ struct mdata_req {
+@@ -212,13 +226,13 @@ static int chunk_io(struct pstore *ps, u
+ * Read or write a metadata area. Remembering to skip the first
+ * chunk which holds the header.
+ */
+-static int area_io(struct pstore *ps, uint32_t area, int rw)
++static int area_io(struct pstore *ps, int rw)
+ {
+ int r;
+ uint32_t chunk;
+
+ /* convert a metadata area index to a chunk index */
+- chunk = 1 + ((ps->exceptions_per_area + 1) * area);
++ chunk = area_location(ps, ps->current_area);
+
+ r = chunk_io(ps, chunk, rw, 0);
+ if (r)
+@@ -228,10 +242,27 @@ static int area_io(struct pstore *ps, ui
+ return 0;
+ }
+
+-static int zero_area(struct pstore *ps, uint32_t area)
++static void zero_memory_area(struct pstore *ps)
+ {
+ memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT);
+- return area_io(ps, area, WRITE);
++}
++
++static int zero_disk_area(struct pstore *ps, chunk_t area)
++{
++ struct dm_io_region where = {
++ .bdev = ps->snap->cow->bdev,
++ .sector = ps->snap->chunk_size * area_location(ps, area),
++ .count = ps->snap->chunk_size,
++ };
++ struct dm_io_request io_req = {
++ .bi_rw = WRITE,
++ .mem.type = DM_IO_VMA,
++ .mem.ptr.vma = ps->zero_area,
++ .client = ps->io_client,
++ .notify.fn = NULL,
++ };
++
++ return dm_io(&io_req, 1, &where, NULL);
+ }
+
+ static int read_header(struct pstore *ps, int *new_snapshot)
+@@ -404,15 +435,14 @@ static int insert_exceptions(struct psto
+
+ static int read_exceptions(struct pstore *ps)
+ {
+- uint32_t area;
+ int r, full = 1;
+
+ /*
+ * Keeping reading chunks and inserting exceptions until
+ * we find a partially full area.
+ */
+- for (area = 0; full; area++) {
+- r = area_io(ps, area, READ);
++ for (ps->current_area = 0; full; ps->current_area++) {
++ r = area_io(ps, READ);
+ if (r)
+ return r;
+
+@@ -421,6 +451,8 @@ static int read_exceptions(struct pstore
+ return r;
+ }
+
++ ps->current_area--;
++
+ return 0;
+ }
+
+@@ -479,12 +511,13 @@ static int persistent_read_metadata(stru
+ return r;
+ }
+
+- r = zero_area(ps, 0);
++ ps->current_area = 0;
++ zero_memory_area(ps);
++ r = zero_disk_area(ps, 0);
+ if (r) {
+- DMWARN("zero_area(0) failed");
++ DMWARN("zero_disk_area(0) failed");
+ return r;
+ }
+-
+ } else {
+ /*
+ * Sanity checks.
+@@ -542,7 +575,6 @@ static void persistent_commit(struct exc
+ void (*callback) (void *, int success),
+ void *callback_context)
+ {
+- int r;
+ unsigned int i;
+ struct pstore *ps = get_info(store);
+ struct disk_exception de;
+@@ -563,33 +595,36 @@ static void persistent_commit(struct exc
+ cb->context = callback_context;
+
+ /*
+- * If there are no more exceptions in flight, or we have
+- * filled this metadata area we commit the exceptions to
+- * disk.
+- */
+- if (atomic_dec_and_test(&ps->pending_count) ||
+- (ps->current_committed == ps->exceptions_per_area)) {
+- r = area_io(ps, ps->current_area, WRITE);
+- if (r)
+- ps->valid = 0;
++ * If there are exceptions in flight and we have not yet
++ * filled this metadata area there's nothing more to do.
++ */
++ if (!atomic_dec_and_test(&ps->pending_count) &&
++ (ps->current_committed != ps->exceptions_per_area))
++ return;
+
+- /*
+- * Have we completely filled the current area ?
+- */
+- if (ps->current_committed == ps->exceptions_per_area) {
+- ps->current_committed = 0;
+- r = zero_area(ps, ps->current_area + 1);
+- if (r)
+- ps->valid = 0;
+- }
++ /*
++ * Commit exceptions to disk.
++ */
++ if (area_io(ps, WRITE))
++ ps->valid = 0;
+
+- for (i = 0; i < ps->callback_count; i++) {
+- cb = ps->callbacks + i;
+- cb->callback(cb->context, r == 0 ? 1 : 0);
+- }
++ /*
++ * Advance to the next area if this one is full.
++ */
++ if (ps->current_committed == ps->exceptions_per_area) {
++ if (zero_disk_area(ps, ps->current_area + 1))
++ ps->valid = 0;
++ ps->current_committed = 0;
++ ps->current_area++;
++ zero_memory_area(ps);
++ }
+
+- ps->callback_count = 0;
++ for (i = 0; i < ps->callback_count; i++) {
++ cb = ps->callbacks + i;
++ cb->callback(cb->context, ps->valid);
+ }
++
++ ps->callback_count = 0;
+ }
+
+ static void persistent_drop(struct exception_store *store)
--- /dev/null
+From jejb@kernel.org Thu Oct 23 13:06:15 2008
+From: Kazuo Ito <ito.kazuo@oss.ntt.co.jp>
+Date: Thu, 23 Oct 2008 17:35:24 GMT
+Subject: dm kcopyd: avoid queue shuffle
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810231735.m9NHZOgW008656@hera.kernel.org>
+
+From: Kazuo Ito <ito.kazuo@oss.ntt.co.jp>
+
+commit b673c3a8192e28f13e2050a4b82c1986be92cc15 upstream
+
+Write throughput to LVM snapshot origin volume is an order
+of magnitude slower than those to LV without snapshots or
+snapshot target volumes, especially in the case of sequential
+writes with O_SYNC on.
+
+The following patch originally written by Kevin Jamieson and
+Jan Blunck and slightly modified for the current RCs by myself
+tries to improve the performance by modifying the behaviour
+of kcopyd, so that it pushes back an I/O job to the head of
+the job queue instead of the tail as process_jobs() currently
+does when it has to wait for free pages. This way, write
+requests aren't shuffled to cause extra seeks.
+
+I tested the patch against 2.6.27-rc5 and got the following results.
+The test is a dd command writing to snapshot origin followed by fsync
+to the file just created/updated. A couple of filesystem benchmarks
+gave me similar results in case of sequential writes, while random
+writes didn't suffer much.
+
+dd if=/dev/zero of=<somewhere on snapshot origin> bs=4096 count=...
+ [conv=notrunc when updating]
+
+1) linux 2.6.27-rc5 without the patch, write to snapshot origin,
+average throughput (MB/s)
+ 10M 100M 1000M
+create,dd 511.46 610.72 11.81
+create,dd+fsync 7.10 6.77 8.13
+update,dd 431.63 917.41 12.75
+update,dd+fsync 7.79 7.43 8.12
+
+compared with write throughput to LV without any snapshots,
+all dd+fsync and 1000 MiB writes perform very poorly.
+
+ 10M 100M 1000M
+create,dd 555.03 608.98 123.29
+create,dd+fsync 114.27 72.78 76.65
+update,dd 152.34 1267.27 124.04
+update,dd+fsync 130.56 77.81 77.84
+
+2) linux 2.6.27-rc5 with the patch, write to snapshot origin,
+average throughput (MB/s)
+
+ 10M 100M 1000M
+create,dd 537.06 589.44 46.21
+create,dd+fsync 31.63 29.19 29.23
+update,dd 487.59 897.65 37.76
+update,dd+fsync 34.12 30.07 26.85
+
+Although still not on par with plain LV performance -
+cannot be avoided because it's copy on write anyway -
+this simple patch successfully improves throughtput
+of dd+fsync while not affecting the rest.
+
+Signed-off-by: Jan Blunck <jblunck@suse.de>
+Signed-off-by: Kazuo Ito <ito.kazuo@oss.ntt.co.jp>
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/md/dm-kcopyd.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/drivers/md/dm-kcopyd.c
++++ b/drivers/md/dm-kcopyd.c
+@@ -268,6 +268,17 @@ static void push(struct list_head *jobs,
+ spin_unlock_irqrestore(&kc->job_lock, flags);
+ }
+
++
++static void push_head(struct list_head *jobs, struct kcopyd_job *job)
++{
++ unsigned long flags;
++ struct dm_kcopyd_client *kc = job->kc;
++
++ spin_lock_irqsave(&kc->job_lock, flags);
++ list_add(&job->list, jobs);
++ spin_unlock_irqrestore(&kc->job_lock, flags);
++}
++
+ /*
+ * These three functions process 1 item from the corresponding
+ * job list.
+@@ -398,7 +409,7 @@ static int process_jobs(struct list_head
+ * We couldn't service this job ATM, so
+ * push this job back onto the list.
+ */
+- push(jobs, job);
++ push_head(jobs, job);
+ break;
+ }
+
--- /dev/null
+From jejb@kernel.org Thu Oct 23 13:07:01 2008
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Thu, 23 Oct 2008 17:35:22 GMT
+Subject: dm snapshot: fix primary_pe race
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810231735.m9NHZMDk008629@hera.kernel.org>
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 7c5f78b9d7f21937e46c26db82976df4b459c95c upstream
+
+Fix a race condition with primary_pe ref_count handling.
+
+put_pending_exception runs under dm_snapshot->lock, it does atomic_dec_and_test
+on primary_pe->ref_count, and later does atomic_read primary_pe->ref_count.
+
+__origin_write does atomic_dec_and_test on primary_pe->ref_count without holding
+dm_snapshot->lock.
+
+This opens the following race condition:
+Assume two CPUs, CPU1 is executing put_pending_exception (and holding
+dm_snapshot->lock). CPU2 is executing __origin_write in parallel.
+primary_pe->ref_count == 2.
+
+CPU1:
+if (primary_pe && atomic_dec_and_test(&primary_pe->ref_count))
+ origin_bios = bio_list_get(&primary_pe->origin_bios);
+.. decrements primary_pe->ref_count to 1. Doesn't load origin_bios
+
+CPU2:
+if (first && atomic_dec_and_test(&primary_pe->ref_count)) {
+ flush_bios(bio_list_get(&primary_pe->origin_bios));
+ free_pending_exception(primary_pe);
+ /* If we got here, pe_queue is necessarily empty. */
+ return r;
+}
+.. decrements primary_pe->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 && !atomic_read(&primary_pe->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->ref_count (so it can't happen that the
+finished copy races with primary_pe->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(&primary_pe->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(&primary_pe->ref_count) returns true, the process
+is responsible for freeing primary_pe.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/md/dm-snap.c | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+--- a/drivers/md/dm-snap.c
++++ b/drivers/md/dm-snap.c
+@@ -824,8 +824,10 @@ static struct bio *put_pending_exception
+ * the bios for the original write to the origin.
+ */
+ if (primary_pe &&
+- atomic_dec_and_test(&primary_pe->ref_count))
++ atomic_dec_and_test(&primary_pe->ref_count)) {
+ origin_bios = bio_list_get(&primary_pe->origin_bios);
++ free_pending_exception(primary_pe);
++ }
+
+ /*
+ * Free the pe if it's not linked to an origin write or if
+@@ -834,12 +836,6 @@ static struct bio *put_pending_exception
+ if (!primary_pe || primary_pe != pe)
+ free_pending_exception(pe);
+
+- /*
+- * Free the primary pe if nothing references it.
+- */
+- if (primary_pe && !atomic_read(&primary_pe->ref_count))
+- free_pending_exception(primary_pe);
+-
+ return origin_bios;
+ }
+
--- /dev/null
+From jejb@kernel.org Thu Oct 23 12:58:23 2008
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Date: Mon, 20 Oct 2008 16:50:07 GMT
+Subject: edac cell: fix incorrect edac_mode
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810201650.m9KGo7ld012751@hera.kernel.org>
+
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+
+commit 3b274f44d2ca05f719fe39947b6a5293a2dbd8fd upstream
+
+The cell_edac driver is setting the edac_mode field of the csrow's to an
+incorrect value, causing the sysfs show routine for that field to go out
+of an array bound and Oopsing the kernel when used.
+
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Doug Thompson <dougthompson@xmission.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/edac/cell_edac.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/edac/cell_edac.c
++++ b/drivers/edac/cell_edac.c
+@@ -142,7 +142,7 @@ static void __devinit cell_edac_init_csr
+ csrow->nr_pages = (r.end - r.start + 1) >> PAGE_SHIFT;
+ csrow->last_page = csrow->first_page + csrow->nr_pages - 1;
+ csrow->mtype = MEM_XDR;
+- csrow->edac_mode = EDAC_FLAG_EC | EDAC_FLAG_SECDED;
++ csrow->edac_mode = EDAC_SECDED;
+ dev_dbg(mci->dev,
+ "Initialized on node %d, chanmask=0x%x,"
+ " first_page=0x%lx, nr_pages=0x%x\n",
--- /dev/null
+From sandeen@redhat.com Thu Oct 23 13:13:44 2008
+From: Eric Sandeen <sandeen@redhat.com>
+Date: Wed, 22 Oct 2008 10:11:52 -0500
+Subject: ext[234]: Avoid printk floods in the face of directory corruption (CVE-2008-3528)
+To: stable@kernel.org
+Cc: ext4 development <linux-ext4@vger.kernel.org>
+Message-ID: <48FF42B8.3030606@redhat.com>
+
+From: Eric Sandeen <sandeen@redhat.com>
+
+This is a trivial backport of the following upstream commits:
+
+- bd39597cbd42a784105a04010100e27267481c67 (ext2)
+- cdbf6dba28e8e6268c8420857696309470009fd9 (ext3)
+- 9d9f177572d9e4eba0f2e18523b44f90dd51fe74 (ext4)
+
+This addresses CVE-2008-3528
+
+ext[234]: Avoid printk floods in the face of directory corruption
+
+Note: some people thinks this represents a security bug, since it
+might make the system go away while it is printing a large number of
+console messages, especially if a serial console is involved. Hence,
+it has been assigned CVE-2008-3528, but it requires that the attacker
+either has physical access to your machine to insert a USB disk with a
+corrupted filesystem image (at which point why not just hit the power
+button), or is otherwise able to convince the system administrator to
+mount an arbitrary filesystem image (at which point why not just
+include a setuid shell or world-writable hard disk device file or some
+such). Me, I think they're just being silly. --tytso
+
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Cc: linux-ext4@vger.kernel.org
+Cc: Eugene Teo <eugeneteo@kernel.sg>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ext2/dir.c | 60 +++++++++++++++++++++++++++++++++-------------------------
+ fs/ext3/dir.c | 10 ++++++---
+ fs/ext4/dir.c | 11 +++++++---
+ 3 files changed, 50 insertions(+), 31 deletions(-)
+
+--- a/fs/ext2/dir.c
++++ b/fs/ext2/dir.c
+@@ -103,7 +103,7 @@ static int ext2_commit_chunk(struct page
+ return err;
+ }
+
+-static void ext2_check_page(struct page *page)
++static void ext2_check_page(struct page *page, int quiet)
+ {
+ struct inode *dir = page->mapping->host;
+ struct super_block *sb = dir->i_sb;
+@@ -146,10 +146,10 @@ out:
+ /* Too bad, we had an error */
+
+ Ebadsize:
+- ext2_error(sb, "ext2_check_page",
+- "size of directory #%lu is not a multiple of chunk size",
+- dir->i_ino
+- );
++ if (!quiet)
++ ext2_error(sb, __func__,
++ "size of directory #%lu is not a multiple "
++ "of chunk size", dir->i_ino);
+ goto fail;
+ Eshort:
+ error = "rec_len is smaller than minimal";
+@@ -166,32 +166,36 @@ Espan:
+ Einumber:
+ error = "inode out of bounds";
+ bad_entry:
+- ext2_error (sb, "ext2_check_page", "bad entry in directory #%lu: %s - "
+- "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
+- dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
+- (unsigned long) le32_to_cpu(p->inode),
+- rec_len, p->name_len);
++ if (!quiet)
++ ext2_error(sb, __func__, "bad entry in directory #%lu: : %s - "
++ "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
++ dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
++ (unsigned long) le32_to_cpu(p->inode),
++ rec_len, p->name_len);
+ goto fail;
+ Eend:
+- p = (ext2_dirent *)(kaddr + offs);
+- ext2_error (sb, "ext2_check_page",
+- "entry in directory #%lu spans the page boundary"
+- "offset=%lu, inode=%lu",
+- dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
+- (unsigned long) le32_to_cpu(p->inode));
++ if (!quiet) {
++ p = (ext2_dirent *)(kaddr + offs);
++ ext2_error(sb, "ext2_check_page",
++ "entry in directory #%lu spans the page boundary"
++ "offset=%lu, inode=%lu",
++ dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
++ (unsigned long) le32_to_cpu(p->inode));
++ }
+ fail:
+ SetPageChecked(page);
+ SetPageError(page);
+ }
+
+-static struct page * ext2_get_page(struct inode *dir, unsigned long n)
++static struct page * ext2_get_page(struct inode *dir, unsigned long n,
++ int quiet)
+ {
+ struct address_space *mapping = dir->i_mapping;
+ struct page *page = read_mapping_page(mapping, n, NULL);
+ if (!IS_ERR(page)) {
+ kmap(page);
+ if (!PageChecked(page))
+- ext2_check_page(page);
++ ext2_check_page(page, quiet);
+ if (PageError(page))
+ goto fail;
+ }
+@@ -292,7 +296,7 @@ ext2_readdir (struct file * filp, void *
+ for ( ; n < npages; n++, offset = 0) {
+ char *kaddr, *limit;
+ ext2_dirent *de;
+- struct page *page = ext2_get_page(inode, n);
++ struct page *page = ext2_get_page(inode, n, 0);
+
+ if (IS_ERR(page)) {
+ ext2_error(sb, __func__,
+@@ -361,6 +365,7 @@ struct ext2_dir_entry_2 * ext2_find_entr
+ struct page *page = NULL;
+ struct ext2_inode_info *ei = EXT2_I(dir);
+ ext2_dirent * de;
++ int dir_has_error = 0;
+
+ if (npages == 0)
+ goto out;
+@@ -374,7 +379,7 @@ struct ext2_dir_entry_2 * ext2_find_entr
+ n = start;
+ do {
+ char *kaddr;
+- page = ext2_get_page(dir, n);
++ page = ext2_get_page(dir, n, dir_has_error);
+ if (!IS_ERR(page)) {
+ kaddr = page_address(page);
+ de = (ext2_dirent *) kaddr;
+@@ -391,7 +396,9 @@ struct ext2_dir_entry_2 * ext2_find_entr
+ de = ext2_next_entry(de);
+ }
+ ext2_put_page(page);
+- }
++ } else
++ dir_has_error = 1;
++
+ if (++n >= npages)
+ n = 0;
+ /* next page is past the blocks we've got */
+@@ -414,7 +421,7 @@ found:
+
+ struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p)
+ {
+- struct page *page = ext2_get_page(dir, 0);
++ struct page *page = ext2_get_page(dir, 0, 0);
+ ext2_dirent *de = NULL;
+
+ if (!IS_ERR(page)) {
+@@ -487,7 +494,7 @@ int ext2_add_link (struct dentry *dentry
+ for (n = 0; n <= npages; n++) {
+ char *dir_end;
+
+- page = ext2_get_page(dir, n);
++ page = ext2_get_page(dir, n, 0);
+ err = PTR_ERR(page);
+ if (IS_ERR(page))
+ goto out;
+@@ -655,14 +662,17 @@ int ext2_empty_dir (struct inode * inode
+ {
+ struct page *page = NULL;
+ unsigned long i, npages = dir_pages(inode);
++ int dir_has_error = 0;
+
+ for (i = 0; i < npages; i++) {
+ char *kaddr;
+ ext2_dirent * de;
+- page = ext2_get_page(inode, i);
++ page = ext2_get_page(inode, i, dir_has_error);
+
+- if (IS_ERR(page))
++ if (IS_ERR(page)) {
++ dir_has_error = 1;
+ continue;
++ }
+
+ kaddr = page_address(page);
+ de = (ext2_dirent *)kaddr;
+--- a/fs/ext3/dir.c
++++ b/fs/ext3/dir.c
+@@ -102,6 +102,7 @@ static int ext3_readdir(struct file * fi
+ int err;
+ struct inode *inode = filp->f_path.dentry->d_inode;
+ int ret = 0;
++ int dir_has_error = 0;
+
+ sb = inode->i_sb;
+
+@@ -148,9 +149,12 @@ static int ext3_readdir(struct file * fi
+ * of recovering data when there's a bad sector
+ */
+ if (!bh) {
+- ext3_error (sb, "ext3_readdir",
+- "directory #%lu contains a hole at offset %lu",
+- inode->i_ino, (unsigned long)filp->f_pos);
++ if (!dir_has_error) {
++ ext3_error(sb, __func__, "directory #%lu "
++ "contains a hole at offset %lld",
++ inode->i_ino, filp->f_pos);
++ dir_has_error = 1;
++ }
+ /* corrupt size? Maybe no more blocks to read */
+ if (filp->f_pos > inode->i_blocks << 9)
+ break;
+--- a/fs/ext4/dir.c
++++ b/fs/ext4/dir.c
+@@ -102,6 +102,7 @@ static int ext4_readdir(struct file * fi
+ int err;
+ struct inode *inode = filp->f_path.dentry->d_inode;
+ int ret = 0;
++ int dir_has_error = 0;
+
+ sb = inode->i_sb;
+
+@@ -148,9 +149,13 @@ static int ext4_readdir(struct file * fi
+ * of recovering data when there's a bad sector
+ */
+ if (!bh) {
+- ext4_error (sb, "ext4_readdir",
+- "directory #%lu contains a hole at offset %lu",
+- inode->i_ino, (unsigned long)filp->f_pos);
++ if (!dir_has_error) {
++ ext4_error(sb, __func__, "directory #%lu "
++ "contains a hole at offset %Lu",
++ inode->i_ino,
++ (unsigned long long) filp->f_pos);
++ dir_has_error = 1;
++ }
+ /* corrupt size? Maybe no more blocks to read */
+ if (filp->f_pos > inode->i_blocks << 9)
+ break;
--- /dev/null
+From jejb@kernel.org Thu Oct 23 12:54:37 2008
+From: David Brownell <dbrownell@users.sourceforge.net>
+Date: Mon, 20 Oct 2008 16:50:10 GMT
+Subject: gpiolib: fix oops in gpio_get_value_cansleep()
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810201650.m9KGoAvI012814@hera.kernel.org>
+
+From: David Brownell <dbrownell@users.sourceforge.net>
+
+commit 978ccaa8ea5d8c7bf6b676209f2fc126eae6355b upstream
+
+We can get the following oops from gpio_get_value_cansleep() when a GPIO
+controller doesn't provide a get() callback:
+
+ Unable to handle kernel paging request for instruction fetch
+ Faulting instruction address: 0x00000000
+ Oops: Kernel access of bad area, sig: 11 [#1]
+ [...]
+ NIP [00000000] 0x0
+ LR [c0182fb0] gpio_get_value_cansleep+0x40/0x50
+ Call Trace:
+ [c7b79e80] [c0183f28] gpio_value_show+0x5c/0x94
+ [c7b79ea0] [c01a584c] dev_attr_show+0x30/0x7c
+ [c7b79eb0] [c00d6b48] fill_read_buffer+0x68/0xe0
+ [c7b79ed0] [c00d6c54] sysfs_read_file+0x94/0xbc
+ [c7b79ef0] [c008f24c] vfs_read+0xb4/0x16c
+ [c7b79f10] [c008f580] sys_read+0x4c/0x90
+ [c7b79f40] [c0013a14] ret_from_syscall+0x0/0x38
+
+It's OK to request the value of *any* GPIO; most GPIOs are bidirectional,
+so configuring them as outputs just enables an output driver and doesn't
+disable the input logic.
+
+So the problem is that gpio_get_value_cansleep() isn't making the same
+sanity check that gpio_get_value() does: making sure this GPIO isn't one
+of the atypical "no input logic" cases.
+
+Reported-by: Anton Vorontsov <avorontsov@ru.mvista.com>
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpio/gpiolib.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -1020,7 +1020,7 @@ int gpio_get_value_cansleep(unsigned gpi
+
+ might_sleep_if(extra_checks);
+ chip = gpio_to_chip(gpio);
+- return chip->get(chip, gpio - chip->base);
++ return chip->get ? chip->get(chip, gpio - chip->base) : 0;
+ }
+ EXPORT_SYMBOL_GPL(gpio_get_value_cansleep);
+
--- /dev/null
+From benh@kernel.crashing.org Thu Oct 23 13:18:50 2008
+From: Christian Borntraeger <borntraeger@de.ibm.com>
+Date: Thu, 23 Oct 2008 12:18:31 +1100
+Subject: hvc_console: Fix free_irq in spinlocked section
+To: stable <stable@kernel.org>
+Message-ID: <1224724711.7654.357.camel@pasglop>
+
+From: Christian Borntraeger <borntraeger@de.ibm.com>
+
+commit eef2622a9fcfa964073333ea72c7c9cd20ad45e6 upstream
+
+hvc_console: Fix free_irq in spinlocked section
+
+ commit 611e097d7707741a336a0677d9d69bec40f29f3d
+ Author: Christian Borntraeger <borntraeger@de.ibm.com>
+ hvc_console: rework setup to replace irq functions with callbacks
+ introduced a spinlock recursion problem. The notifier_del is
+ called with a lock held, and in turns calls free_irq which then
+ complains when manipulating procfs. This fixes it by moving the
+ call to the notifier to outside of the locked section.
+
+Signed-off-by: Christian Borntraeger<borntraeger@de.ibm.com>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/hvc_console.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/char/hvc_console.c
++++ b/drivers/char/hvc_console.c
+@@ -367,13 +367,13 @@ static void hvc_close(struct tty_struct
+ spin_lock_irqsave(&hp->lock, flags);
+
+ if (--hp->count == 0) {
+- if (hp->ops->notifier_del)
+- hp->ops->notifier_del(hp, hp->data);
+-
+ /* We are done with the tty pointer now. */
+ hp->tty = NULL;
+ spin_unlock_irqrestore(&hp->lock, flags);
+
++ if (hp->ops->notifier_del)
++ hp->ops->notifier_del(hp, hp->data);
++
+ /*
+ * Chain calls chars_in_buffer() and returns immediately if
+ * there is no buffered data otherwise sleeps on a wait queue
+@@ -416,11 +416,11 @@ static void hvc_hangup(struct tty_struct
+ hp->n_outbuf = 0;
+ hp->tty = NULL;
+
++ spin_unlock_irqrestore(&hp->lock, flags);
++
+ if (hp->ops->notifier_del)
+ hp->ops->notifier_del(hp, hp->data);
+
+- spin_unlock_irqrestore(&hp->lock, flags);
+-
+ while(temp_open_count) {
+ --temp_open_count;
+ kref_put(&hp->kref, destroy_hvc_struct);
--- /dev/null
+From kaber@trash.net Thu Oct 23 13:16:48 2008
+From: Patrick McHardy <kaber@trash.net>
+Date: Wed, 22 Oct 2008 19:41:31 +0200 (MEST)
+Subject: netfilter: restore lost ifdef guarding defrag exception
+To: stable@kernel.org
+Cc: netfilter-devel@vger.kernel.org, Patrick McHardy <kaber@trash.net>, davem@davemloft.net
+Message-ID: <20081022174130.21341.48347.sendpatchset@x2.localnet>
+
+From: Patrick McHardy <kaber@trash.net>
+
+netfilter: restore lost #ifdef guarding defrag exception
+
+Upstream commit 38f7ac3eb:
+
+Nir Tzachar <nir.tzachar@gmail.com> reported a warning when sending
+fragments over loopback with NAT:
+
+[ 6658.338121] WARNING: at net/ipv4/netfilter/nf_nat_standalone.c:89 nf_nat_fn+0x33/0x155()
+
+The reason is that defragmentation is skipped for already tracked connections.
+This is wrong in combination with NAT and ip_conntrack actually had some ifdefs
+to avoid this behaviour when NAT is compiled in.
+
+The entire "optimization" may seem a bit silly, for now simply restoring the
+lost #ifdef is the easiest solution until we can come up with something better.
+
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
++++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+@@ -150,10 +150,12 @@ static unsigned int ipv4_conntrack_defra
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+ {
++#if !defined(CONFIG_NF_NAT) && !defined(CONFIG_NF_NAT_MODULE)
+ /* Previously seen (loopback)? Ignore. Do this before
+ fragment check. */
+ if (skb->nfct)
+ return NF_ACCEPT;
++#endif
+
+ /* Gather fragments. */
+ if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
--- /dev/null
+From kaber@trash.net Thu Oct 23 13:16:08 2008
+From: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
+Date: Wed, 22 Oct 2008 19:41:29 +0200 (MEST)
+Subject: netfilter: snmp nat leaks memory in case of failure
+To: stable@kernel.org
+Cc: netfilter-devel@vger.kernel.org, Patrick McHardy <kaber@trash.net>, davem@davemloft.net
+Message-ID: <20081022174129.21341.93881.sendpatchset@x2.localnet>
+
+From: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
+
+netfilter: snmp nat leaks memory in case of failure
+
+Upstream commit 311670f3e:
+
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+
+---
+ net/ipv4/netfilter/nf_nat_snmp_basic.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
++++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
+@@ -742,6 +742,7 @@ static unsigned char snmp_object_decode(
+ *obj = kmalloc(sizeof(struct snmp_object) + len,
+ GFP_ATOMIC);
+ if (*obj == NULL) {
++ kfree(p);
+ kfree(id);
+ if (net_ratelimit())
+ printk("OOM in bsalg (%d)\n", __LINE__);
--- /dev/null
+From kaber@trash.net Thu Oct 23 13:14:58 2008
+From: Alexey Dobriyan <adobriyan@gmail.com>
+Date: Wed, 22 Oct 2008 19:41:28 +0200 (MEST)
+Subject: netfilter: xt_iprange: fix range inversion match
+To: stable@kernel.org
+Cc: netfilter-devel@vger.kernel.org, Patrick McHardy <kaber@trash.net>, davem@davemloft.net
+Message-ID: <20081022174128.21341.79877.sendpatchset@x2.localnet>
+
+
+From: Alexey Dobriyan <adobriyan@gmail.com>
+
+netfilter: xt_iprange: fix range inversion match
+
+Upstream commit 6def1eb48:
+
+Inverted IPv4 v1 and IPv6 v0 matches don't match anything since 2.6.25-rc1!
+
+Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
+Acked-by: Jan Engelhardt <jengelh@medozas.de>
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/netfilter/xt_iprange.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/net/netfilter/xt_iprange.c
++++ b/net/netfilter/xt_iprange.c
+@@ -67,7 +67,7 @@ iprange_mt4(const struct sk_buff *skb, c
+ if (info->flags & IPRANGE_SRC) {
+ m = ntohl(iph->saddr) < ntohl(info->src_min.ip);
+ m |= ntohl(iph->saddr) > ntohl(info->src_max.ip);
+- m ^= info->flags & IPRANGE_SRC_INV;
++ m ^= !!(info->flags & IPRANGE_SRC_INV);
+ if (m) {
+ pr_debug("src IP " NIPQUAD_FMT " NOT in range %s"
+ NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
+@@ -81,7 +81,7 @@ iprange_mt4(const struct sk_buff *skb, c
+ if (info->flags & IPRANGE_DST) {
+ m = ntohl(iph->daddr) < ntohl(info->dst_min.ip);
+ m |= ntohl(iph->daddr) > ntohl(info->dst_max.ip);
+- m ^= info->flags & IPRANGE_DST_INV;
++ m ^= !!(info->flags & IPRANGE_DST_INV);
+ if (m) {
+ pr_debug("dst IP " NIPQUAD_FMT " NOT in range %s"
+ NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
+@@ -123,14 +123,14 @@ iprange_mt6(const struct sk_buff *skb, c
+ if (info->flags & IPRANGE_SRC) {
+ m = iprange_ipv6_sub(&iph->saddr, &info->src_min.in6) < 0;
+ m |= iprange_ipv6_sub(&iph->saddr, &info->src_max.in6) > 0;
+- m ^= info->flags & IPRANGE_SRC_INV;
++ m ^= !!(info->flags & IPRANGE_SRC_INV);
+ if (m)
+ return false;
+ }
+ if (info->flags & IPRANGE_DST) {
+ m = iprange_ipv6_sub(&iph->daddr, &info->dst_min.in6) < 0;
+ m |= iprange_ipv6_sub(&iph->daddr, &info->dst_max.in6) > 0;
+- m ^= info->flags & IPRANGE_DST_INV;
++ m ^= !!(info->flags & IPRANGE_DST_INV);
+ if (m)
+ return false;
+ }
--- /dev/null
+From bart.vanassche@gmail.com Thu Oct 23 13:40:27 2008
+From: Bart Van Assche <bart.vanassche@gmail.com>
+Date: Tue, 21 Oct 2008 19:05:50 +0200
+Subject: Regression: inclusion of <linux/module.h> triggers a compiler warning
+To: stable@kernel.org
+Cc: Vladislav Bolkhovitin <vst@vlnb.net>, Andrew Morton <akpm@linux-foundation.org>, Linus Torvalds <torvalds@linux-foundation.org>, Dave Young <hidave.darkstar@gmail.com>
+Message-ID: <200810211905.50915.bart.vanassche@gmail.com>
+Content-Disposition: inline
+
+From: Bart Van Assche <bart.vanassche@gmail.com>
+
+Not upstream, only a 2.6.27-stable issue.
+
+When compiling kernel modules against the 2.6.27, 2.6.27.1 or 2.6.27.2 kernel
+headers, a compiler warning similar to the following is reported:
+
+CC [M] trunk/scst/src/scst_targ.o
+In file included from include/linux/kernel.h:19,
+ from include/asm/system.h:11,
+ from include/asm/processor.h:18,
+ from include/linux/prefetch.h:15,
+ from include/linux/list.h:7,
+ from include/linux/module.h:10,
+ from trunk/scst/src/scst_main.c:20:
+include/linux/ratelimit.h: In function 'ratelimit':
+include/linux/ratelimit.h:23: warning: missing initializer
+include/linux/ratelimit.h:23: warning: (near initialization for 'rs.printed')
+
+This issue was introduced through commit
+717115e1a5856b57af0f71e1df7149108294fc10
+(http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.27.y.git;a=commit;h=717115e1a5856b57af0f71e1df7149108294fc10).
+I have added the people who signed this patch in CC.
+
+The patch below fixes this warning, without changing the semantics of the code.
+
+Signed-off-by: Bart Van Assche <bart.vanassche@gmail.com>
+Acked-by: Dave Young <hidave.darkstar@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/ratelimit.h | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/include/linux/ratelimit.h
++++ b/include/linux/ratelimit.h
+@@ -13,8 +13,9 @@ struct ratelimit_state {
+ unsigned long begin;
+ };
+
+-#define DEFINE_RATELIMIT_STATE(name, interval, burst) \
+- struct ratelimit_state name = {interval, burst,}
++#define DEFINE_RATELIMIT_STATE(name, interval_value, burst_value) \
++ struct ratelimit_state name \
++ = { .interval = (interval_value), .burst = (burst_value) }
+
+ extern int __ratelimit(struct ratelimit_state *rs);
+
--- /dev/null
+From jejb@kernel.org Thu Oct 23 13:00:30 2008
+From: Miao Xie <miaox@cn.fujitsu.com>
+Date: Thu, 23 Oct 2008 16:50:03 GMT
+Subject: sched: fix the wrong mask_len
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810231650.m9NGo3aY001438@hera.kernel.org>
+
+From: Miao Xie <miaox@cn.fujitsu.com>
+
+commit c851c8676bd7ae456e9b3af8e6bb2c434eddcc75 upstream
+
+If NR_CPUS isn't a multiple of 32, we get a truncated string of sched
+domains by catting /proc/schedstat. This is caused by the wrong mask_len.
+
+This patch fixes it.
+
+Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ kernel/sched_stats.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/sched_stats.h
++++ b/kernel/sched_stats.h
+@@ -9,7 +9,7 @@
+ static int show_schedstat(struct seq_file *seq, void *v)
+ {
+ int cpu;
+- int mask_len = NR_CPUS/32 * 9;
++ int mask_len = (NR_CPUS/32 + 1) * 9;
+ char *mask_str = kmalloc(mask_len, GFP_KERNEL);
+
+ if (mask_str == NULL)
--- /dev/null
+gpiolib-fix-oops-in-gpio_get_value_cansleep.patch
+edac-cell-fix-incorrect-edac_mode.patch
+x86-acpi-fix-breakage-of-resume-on-64-bit-up-systems-with-smp-kernel.patch
+sched-fix-the-wrong-mask_len.patch
+usb-cdc-wdm-make-module-autoload-work.patch
+usb-don-t-rebind-drivers-after-failed-resume-or-reset.patch
+usb-fix-memory-leak-in-cdc-acm.patch
+usb-speedtouch-add-pre_reset-and-post_reset-routines.patch
+dm-kcopyd-avoid-queue-shuffle.patch
+dm-snapshot-fix-primary_pe-race.patch
+dm-exception-store-refactor-zero_area.patch
+dm-exception-store-fix-misordered-writes.patch
+amd_iommu-fix-nasty-bug-that-caused-illegal_device_table_entry-errors.patch
+cifs-fix-saving-of-resume-key-before-cifsfindnext.patch
+ext-avoid-printk-floods-in-the-face-of-directory-corruption.patch
+netfilter-xt_iprange-fix-range-inversion-match.patch
+netfilter-snmp-nat-leaks-memory-in-case-of-failure.patch
+netfilter-restore-lost-ifdef-guarding-defrag-exception.patch
+anon_vma_prepare-properly-lock-even-newly-allocated-entries.patch
+hvc_console-fix-free_irq-in-spinlocked-section.patch
+regression-inclusion-of-linux-module.h-triggers-a-compiler-warning.patch
--- /dev/null
+From jejb@kernel.org Thu Oct 23 13:02:01 2008
+From: Oliver Neukum <oliver@neukum.org>
+Date: Thu, 23 Oct 2008 17:35:11 GMT
+Subject: USB: cdc-wdm: make module autoload work
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810231735.m9NHZBH3008400@hera.kernel.org>
+
+From: Oliver Neukum <oliver@neukum.org>
+
+commit aa5380b904e7f896db0931320160bdea93e41f6a upstream
+
+this fixes an omission that led to no alias being computed for the
+cdc-wdm module.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/class/cdc-wdm.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/class/cdc-wdm.c
++++ b/drivers/usb/class/cdc-wdm.c
+@@ -42,6 +42,8 @@ static struct usb_device_id wdm_ids[] =
+ { }
+ };
+
++MODULE_DEVICE_TABLE (usb, wdm_ids);
++
+ #define WDM_MINOR_BASE 176
+
+
--- /dev/null
+From jejb@kernel.org Thu Oct 23 13:02:28 2008
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Thu, 23 Oct 2008 17:35:07 GMT
+Subject: USB: don't rebind drivers after failed resume or reset
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810231735.m9NHZ7jJ008353@hera.kernel.org>
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 6c6409459a18a825ce12ecb003d5686af61f7a2f upstream
+
+This patch (as1152) may help prevent some problems associated with the
+new policy of unbinding drivers that don't support suspend/resume or
+pre_reset/post_reset. If for any reason the resume or reset fails, and
+the device is logically disconnected, there's no point in trying to
+rebind the driver. So the patch checks for success before carrying
+out the unbind/rebind.
+
+There was a report from one user that this fixed a problem he was
+experiencing, but the details never became fully clear. In any case,
+adding these tests can't hurt.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/core/driver.c | 3 ++-
+ drivers/usb/core/hub.c | 2 +-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/driver.c
++++ b/drivers/usb/core/driver.c
+@@ -1609,7 +1609,8 @@ int usb_external_resume_device(struct us
+ status = usb_resume_both(udev);
+ udev->last_busy = jiffies;
+ usb_pm_unlock(udev);
+- do_unbind_rebind(udev, DO_REBIND);
++ if (status == 0)
++ do_unbind_rebind(udev, DO_REBIND);
+
+ /* Now that the device is awake, we can start trying to autosuspend
+ * it again. */
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -3424,7 +3424,7 @@ int usb_reset_device(struct usb_device *
+ USB_INTERFACE_BOUND)
+ rebind = 1;
+ }
+- if (rebind)
++ if (ret == 0 && rebind)
+ usb_rebind_intf(cintf);
+ }
+ }
--- /dev/null
+From jejb@kernel.org Thu Oct 23 13:04:06 2008
+From: Oliver Neukum <oliver@neukum.org>
+Date: Thu, 23 Oct 2008 17:35:09 GMT
+Subject: USB: fix memory leak in cdc-acm
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810231735.m9NHZ9bR008373@hera.kernel.org>
+
+From: Oliver Neukum <oliver@neukum.org>
+
+commit a496c64f1363ec4d67ebdc1e1f619ad6372a574c upstream
+
+This fixes a memory leak on disconnect in cdc-acm
+
+Thanks to 施金前 for finding it.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/class/cdc-acm.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -849,9 +849,10 @@ static void acm_write_buffers_free(struc
+ {
+ int i;
+ struct acm_wb *wb;
++ struct usb_device *usb_dev = interface_to_usbdev(acm->control);
+
+ for (wb = &acm->wb[0], i = 0; i < ACM_NW; i++, wb++) {
+- usb_buffer_free(acm->dev, acm->writesize, wb->buf, wb->dmah);
++ usb_buffer_free(usb_dev, acm->writesize, wb->buf, wb->dmah);
+ }
+ }
+
--- /dev/null
+From jejb@kernel.org Thu Oct 23 13:04:42 2008
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Thu, 23 Oct 2008 17:35:13 GMT
+Subject: USB: Speedtouch: add pre_reset and post_reset routines
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810231735.m9NHZDhu008428@hera.kernel.org>
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 8fc7aeab3851ed8c3ecf28901ca2c6f0400955c7 upstream
+
+This patch (as1150) fixes a problem in the speedtch driver. When it
+resets the modem during probe it will be unbound from the other
+interfaces it has claimed, because it doesn't define a pre_reset and a
+post_reset method.
+
+The patch defines "do-nothing" methods. This fixes Bugzilla #11767.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/atm/speedtch.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/usb/atm/speedtch.c
++++ b/drivers/usb/atm/speedtch.c
+@@ -722,6 +722,16 @@ static void speedtch_atm_stop(struct usb
+ flush_scheduled_work();
+ }
+
++static int speedtch_pre_reset(struct usb_interface *intf)
++{
++ return 0;
++}
++
++static int speedtch_post_reset(struct usb_interface *intf)
++{
++ return 0;
++}
++
+
+ /**********
+ ** USB **
+@@ -740,6 +750,8 @@ static struct usb_driver speedtch_usb_dr
+ .name = speedtch_driver_name,
+ .probe = speedtch_usb_probe,
+ .disconnect = usbatm_usb_disconnect,
++ .pre_reset = speedtch_pre_reset,
++ .post_reset = speedtch_post_reset,
+ .id_table = speedtch_usb_ids
+ };
+
--- /dev/null
+From jejb@kernel.org Thu Oct 23 12:59:15 2008
+From: Rafael J. Wysocki <rjw@sisk.pl>
+Date: Mon, 20 Oct 2008 21:30:19 GMT
+Subject: x86 ACPI: fix breakage of resume on 64-bit UP systems with SMP kernel
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200810202130.m9KLUJU5017800@hera.kernel.org>
+
+From: Rafael J. Wysocki <rjw@sisk.pl>
+
+commit 3038edabf48f01421c621cb77a712b446d3a5d67 upstream
+
+x86 ACPI: Fix breakage of resume on 64-bit UP systems with SMP kernel
+
+We are now using per CPU GDT tables in head_64.S and the original
+early_gdt_descr.address is invalidated after boot by
+setup_per_cpu_areas(). This breaks resume from suspend to RAM on
+x86_64 UP systems using SMP kernels, because this part of head_64.S
+is also executed during the resume and the invalid GDT address
+causes the system to crash. It doesn't break on 'true' SMP systems,
+because early_gdt_descr.address is modified every time
+native_cpu_up() runs. However, during resume it should point to the
+GDT of the boot CPU rather than to another CPU's GDT.
+
+For this reason, during suspend to RAM always make
+early_gdt_descr.address point to the boot CPU's GDT.
+
+This fixes http://bugzilla.kernel.org/show_bug.cgi?id=11568, which
+is a regression from 2.6.26.
+
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+Acked-by: Pavel Machek <pavel@suse.cz>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Reported-and-tested-by: Andy Wettstein <ajw1980@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/kernel/acpi/sleep.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/x86/kernel/acpi/sleep.c
++++ b/arch/x86/kernel/acpi/sleep.c
+@@ -10,6 +10,7 @@
+ #include <linux/dmi.h>
+ #include <linux/cpumask.h>
+ #include <asm/segment.h>
++#include <asm/desc.h>
+
+ #include "realmode/wakeup.h"
+ #include "sleep.h"
+@@ -98,6 +99,8 @@ int acpi_save_state_mem(void)
+ header->trampoline_segment = setup_trampoline() >> 4;
+ #ifdef CONFIG_SMP
+ stack_start.sp = temp_stack + 4096;
++ early_gdt_descr.address =
++ (unsigned long)get_cpu_gdt_table(smp_processor_id());
+ #endif
+ initial_code = (unsigned long)wakeup_long64;
+ saved_magic = 0x123456789abcdef0;