--- /dev/null
+From 2defcc3fb4661e7351cb2ac48d843efc4c64db13 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Fri, 4 Sep 2009 20:40:41 +0100
+Subject: dm exception store: split set_chunk_size
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 2defcc3fb4661e7351cb2ac48d843efc4c64db13 upstream.
+
+Break the function set_chunk_size to two functions in preparation for
+the fix in the following patch.
+
+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 | 8 ++++++++
+ drivers/md/dm-exception-store.h | 4 ++++
+ 2 files changed, 12 insertions(+)
+
+--- a/drivers/md/dm-exception-store.c
++++ b/drivers/md/dm-exception-store.c
+@@ -171,6 +171,14 @@ static int set_chunk_size(struct dm_exce
+ */
+ chunk_size_ulong = round_up(chunk_size_ulong, PAGE_SIZE >> 9);
+
++ return dm_exception_store_set_chunk_size(store, chunk_size_ulong,
++ error);
++}
++
++int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
++ unsigned long chunk_size_ulong,
++ char **error)
++{
+ /* Check chunk_size is a power of 2 */
+ if (!is_power_of_2(chunk_size_ulong)) {
+ *error = "Chunk size is not a power of 2";
+--- a/drivers/md/dm-exception-store.h
++++ b/drivers/md/dm-exception-store.h
+@@ -168,6 +168,10 @@ static inline chunk_t sector_to_chunk(st
+ int dm_exception_store_type_register(struct dm_exception_store_type *type);
+ int dm_exception_store_type_unregister(struct dm_exception_store_type *type);
+
++int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
++ unsigned long chunk_size_ulong,
++ char **error);
++
+ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
+ unsigned *args_used,
+ struct dm_exception_store **store);
--- /dev/null
+From d2b698644c97cb033261536a4f2010924a00eac9 Mon Sep 17 00:00:00 2001
+From: Jonathan Brassow <jbrassow@redhat.com>
+Date: Fri, 4 Sep 2009 20:40:32 +0100
+Subject: dm raid1: do not allow log_failure variable to unset after being set
+
+From: Jonathan Brassow <jbrassow@redhat.com>
+
+commit d2b698644c97cb033261536a4f2010924a00eac9 upstream.
+
+This patch fixes a bug which was triggering a case where the primary leg
+could not be changed on failure even when the mirror was in-sync.
+
+The case involves the failure of the primary device along with
+the transient failure of the log device. The problem is that
+bios can be put on the 'failures' list (due to log failure)
+before 'fail_mirror' is called due to the primary device failure.
+Normally, this is fine, but if the log device failure is transient,
+a subsequent iteration of the work thread, 'do_mirror', will
+reset 'log_failure'. The 'do_failures' function then resets
+the 'in_sync' variable when processing bios on the failures list.
+The 'in_sync' variable is what is used to determine if the
+primary device can be switched in the event of a failure. Since
+this has been reset, the primary device is incorrectly assumed
+to be not switchable.
+
+The case has been seen in the cluster mirror context, where one
+machine realizes the log device is dead before the other machines.
+As the responsibilities of the server migrate from one node to
+another (because the mirror is being reconfigured due to the failure),
+the new server may think for a moment that the log device is fine -
+thus resetting the 'log_failure' variable.
+
+In any case, it is inappropiate for us to reset the 'log_failure'
+variable. The above bug simply illustrates that it can actually
+hurt us.
+
+Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/md/dm-raid1.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/md/dm-raid1.c
++++ b/drivers/md/dm-raid1.c
+@@ -648,7 +648,13 @@ static void do_writes(struct mirror_set
+ */
+ dm_rh_inc_pending(ms->rh, &sync);
+ dm_rh_inc_pending(ms->rh, &nosync);
+- ms->log_failure = dm_rh_flush(ms->rh) ? 1 : 0;
++
++ /*
++ * If the flush fails on a previous call and succeeds here,
++ * we must not reset the log_failure variable. We need
++ * userspace interaction to do that.
++ */
++ ms->log_failure = dm_rh_flush(ms->rh) ? 1 : ms->log_failure;
+
+ /*
+ * Dispatch io.
--- /dev/null
+From 61578dcd3fafe6babd72e8db32110cc0b630a432 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Fri, 4 Sep 2009 20:40:39 +0100
+Subject: dm snapshot: fix header corruption race on invalidation
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 61578dcd3fafe6babd72e8db32110cc0b630a432 upstream.
+
+If a persistent snapshot fills up, a race can corrupt the on-disk header
+which causes a crash on any future attempt to activate the snapshot
+(typically while booting). This patch fixes the race.
+
+When the snapshot overflows, __invalidate_snapshot is called, which calls
+snapshot store method drop_snapshot. It goes to persistent_drop_snapshot that
+calls write_header. write_header constructs the new header in the "area"
+location.
+
+Concurrently, an existing kcopyd job may finish, call copy_callback
+and commit_exception method, that goes to persistent_commit_exception.
+persistent_commit_exception doesn't do locking, relying on the fact that
+callbacks are single-threaded, but it can race with snapshot invalidation and
+overwrite the header that is just being written while the snapshot is being
+invalidated.
+
+The result of this race is a corrupted header being written that can
+lead to a crash on further reactivation (if chunk_size is zero in the
+corrupted header).
+
+The fix is to use separate memory areas for each.
+
+See the bug: https://bugzilla.redhat.com/show_bug.cgi?id=461506
+
+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-persistent.c | 44 ++++++++++++++++++++++++++++++----------
+ 1 file changed, 34 insertions(+), 10 deletions(-)
+
+--- a/drivers/md/dm-snap-persistent.c
++++ b/drivers/md/dm-snap-persistent.c
+@@ -106,6 +106,13 @@ struct pstore {
+ void *zero_area;
+
+ /*
++ * An area used for header. The header can be written
++ * concurrently with metadata (when invalidating the snapshot),
++ * so it needs a separate buffer.
++ */
++ void *header_area;
++
++ /*
+ * Used to keep track of which metadata area the data in
+ * 'chunk' refers to.
+ */
+@@ -148,16 +155,27 @@ static int alloc_area(struct pstore *ps)
+ */
+ ps->area = vmalloc(len);
+ if (!ps->area)
+- return r;
++ goto err_area;
+
+ ps->zero_area = vmalloc(len);
+- if (!ps->zero_area) {
+- vfree(ps->area);
+- return r;
+- }
++ if (!ps->zero_area)
++ goto err_zero_area;
+ memset(ps->zero_area, 0, len);
+
++ ps->header_area = vmalloc(len);
++ if (!ps->header_area)
++ goto err_header_area;
++
+ return 0;
++
++err_header_area:
++ vfree(ps->zero_area);
++
++err_zero_area:
++ vfree(ps->area);
++
++err_area:
++ return r;
+ }
+
+ static void free_area(struct pstore *ps)
+@@ -169,6 +187,10 @@ static void free_area(struct pstore *ps)
+ if (ps->zero_area)
+ vfree(ps->zero_area);
+ ps->zero_area = NULL;
++
++ if (ps->header_area)
++ vfree(ps->header_area);
++ ps->header_area = NULL;
+ }
+
+ struct mdata_req {
+@@ -285,11 +307,11 @@ static int read_header(struct pstore *ps
+ if (r)
+ return r;
+
+- r = chunk_io(ps, ps->area, 0, READ, 1);
++ r = chunk_io(ps, ps->header_area, 0, READ, 1);
+ if (r)
+ goto bad;
+
+- dh = (struct disk_header *) ps->area;
++ dh = ps->header_area;
+
+ if (le32_to_cpu(dh->magic) == 0) {
+ *new_snapshot = 1;
+@@ -339,15 +361,15 @@ static int write_header(struct pstore *p
+ {
+ struct disk_header *dh;
+
+- memset(ps->area, 0, ps->store->chunk_size << SECTOR_SHIFT);
++ memset(ps->header_area, 0, ps->store->chunk_size << SECTOR_SHIFT);
+
+- dh = (struct disk_header *) ps->area;
++ dh = ps->header_area;
+ dh->magic = cpu_to_le32(SNAP_MAGIC);
+ dh->valid = cpu_to_le32(ps->valid);
+ dh->version = cpu_to_le32(ps->version);
+ dh->chunk_size = cpu_to_le32(ps->store->chunk_size);
+
+- return chunk_io(ps, ps->area, 0, WRITE, 1);
++ return chunk_io(ps, ps->header_area, 0, WRITE, 1);
+ }
+
+ /*
+@@ -667,6 +689,8 @@ static int persistent_ctr(struct dm_exce
+ ps->valid = 1;
+ ps->version = SNAPSHOT_DISK_VERSION;
+ ps->area = NULL;
++ ps->zero_area = NULL;
++ ps->header_area = NULL;
+ ps->next_free = 2; /* skipping the header and first area */
+ ps->current_committed = 0;
+
--- /dev/null
+From ae0b7448e91353ea5f821601a055aca6b58042cd Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Fri, 4 Sep 2009 20:40:43 +0100
+Subject: dm snapshot: fix on disk chunk size validation
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit ae0b7448e91353ea5f821601a055aca6b58042cd upstream.
+
+Fix some problems seen in the chunk size processing when activating a
+pre-existing snapshot.
+
+For a new snapshot, the chunk size can either be supplied by the creator
+or a default value can be used. For an existing snapshot, the
+chunk size in the snapshot header on disk should always be used.
+
+If someone attempts to load an existing snapshot and has the 'default
+chunk size' option set, the kernel uses its default value even when it
+is incorrect for the snapshot being loaded. This patch ensures the
+correct on-disk value is always used.
+
+Secondly, when the code does use the chunk size stored on the disk it is
+prudent to revalidate it, so the code can exit cleanly if it got
+corrupted as happened in
+https://bugzilla.redhat.com/show_bug.cgi?id=461506 .
+
+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 | 5 +++++
+ drivers/md/dm-snap-persistent.c | 22 ++++++++++++++--------
+ 2 files changed, 19 insertions(+), 8 deletions(-)
+
+--- a/drivers/md/dm-exception-store.c
++++ b/drivers/md/dm-exception-store.c
+@@ -191,6 +191,11 @@ int dm_exception_store_set_chunk_size(st
+ return -EINVAL;
+ }
+
++ if (chunk_size_ulong > INT_MAX >> SECTOR_SHIFT) {
++ *error = "Chunk size is too high";
++ return -EINVAL;
++ }
++
+ store->chunk_size = chunk_size_ulong;
+ store->chunk_mask = chunk_size_ulong - 1;
+ store->chunk_shift = ffs(chunk_size_ulong) - 1;
+--- a/drivers/md/dm-snap-persistent.c
++++ b/drivers/md/dm-snap-persistent.c
+@@ -286,6 +286,7 @@ static int read_header(struct pstore *ps
+ struct disk_header *dh;
+ chunk_t chunk_size;
+ int chunk_size_supplied = 1;
++ char *chunk_err;
+
+ /*
+ * Use default chunk size (or hardsect_size, if larger) if none supplied
+@@ -329,20 +330,25 @@ static int read_header(struct pstore *ps
+ ps->version = le32_to_cpu(dh->version);
+ chunk_size = le32_to_cpu(dh->chunk_size);
+
+- if (!chunk_size_supplied || ps->store->chunk_size == chunk_size)
++ if (ps->store->chunk_size == chunk_size)
+ return 0;
+
+- DMWARN("chunk size %llu in device metadata overrides "
+- "table chunk size of %llu.",
+- (unsigned long long)chunk_size,
+- (unsigned long long)ps->store->chunk_size);
++ if (chunk_size_supplied)
++ DMWARN("chunk size %llu in device metadata overrides "
++ "table chunk size of %llu.",
++ (unsigned long long)chunk_size,
++ (unsigned long long)ps->store->chunk_size);
+
+ /* We had a bogus chunk_size. Fix stuff up. */
+ free_area(ps);
+
+- ps->store->chunk_size = chunk_size;
+- ps->store->chunk_mask = chunk_size - 1;
+- ps->store->chunk_shift = ffs(chunk_size) - 1;
++ r = dm_exception_store_set_chunk_size(ps->store, chunk_size,
++ &chunk_err);
++ if (r) {
++ DMERR("invalid on-disk chunk size %llu: %s.",
++ (unsigned long long)chunk_size, chunk_err);
++ return r;
++ }
+
+ r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size),
+ ps->io_client);
--- /dev/null
+From 02d2fd31defce6ff77146ad0fef4f19006055d86 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Fri, 4 Sep 2009 20:40:37 +0100
+Subject: dm snapshot: refactor zero_disk_area to use chunk_io
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 02d2fd31defce6ff77146ad0fef4f19006055d86 upstream.
+
+Refactor chunk_io to prepare for the fix in the following patch.
+
+Pass an area pointer to chunk_io and simplify zero_disk_area to use
+chunk_io. No functional change.
+
+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-persistent.c | 26 +++++++-------------------
+ 1 file changed, 7 insertions(+), 19 deletions(-)
+
+--- a/drivers/md/dm-snap-persistent.c
++++ b/drivers/md/dm-snap-persistent.c
+@@ -188,7 +188,8 @@ static void do_metadata(struct work_stru
+ /*
+ * Read or write a chunk aligned and sized block of data from a device.
+ */
+-static int chunk_io(struct pstore *ps, chunk_t chunk, int rw, int metadata)
++static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, int rw,
++ int metadata)
+ {
+ struct dm_io_region where = {
+ .bdev = ps->store->cow->bdev,
+@@ -198,7 +199,7 @@ static int chunk_io(struct pstore *ps, c
+ struct dm_io_request io_req = {
+ .bi_rw = rw,
+ .mem.type = DM_IO_VMA,
+- .mem.ptr.vma = ps->area,
++ .mem.ptr.vma = area,
+ .client = ps->io_client,
+ .notify.fn = NULL,
+ };
+@@ -240,7 +241,7 @@ static int area_io(struct pstore *ps, in
+
+ chunk = area_location(ps, ps->current_area);
+
+- r = chunk_io(ps, chunk, rw, 0);
++ r = chunk_io(ps, ps->area, chunk, rw, 0);
+ if (r)
+ return r;
+
+@@ -254,20 +255,7 @@ static void zero_memory_area(struct psto
+
+ static int zero_disk_area(struct pstore *ps, chunk_t area)
+ {
+- struct dm_io_region where = {
+- .bdev = ps->store->cow->bdev,
+- .sector = ps->store->chunk_size * area_location(ps, area),
+- .count = ps->store->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);
++ return chunk_io(ps, ps->zero_area, area_location(ps, area), WRITE, 0);
+ }
+
+ static int read_header(struct pstore *ps, int *new_snapshot)
+@@ -297,7 +285,7 @@ static int read_header(struct pstore *ps
+ if (r)
+ return r;
+
+- r = chunk_io(ps, 0, READ, 1);
++ r = chunk_io(ps, ps->area, 0, READ, 1);
+ if (r)
+ goto bad;
+
+@@ -359,7 +347,7 @@ static int write_header(struct pstore *p
+ dh->version = cpu_to_le32(ps->version);
+ dh->chunk_size = cpu_to_le32(ps->store->chunk_size);
+
+- return chunk_io(ps, 0, WRITE, 1);
++ return chunk_io(ps, ps->area, 0, WRITE, 1);
+ }
+
+ /*
--- /dev/null
+From bc8cec0dff072f1a45ce7f6b2c5234bb3411ac51 Mon Sep 17 00:00:00 2001
+From: Massimo Cirillo <maxcir@gmail.com>
+Date: Thu, 27 Aug 2009 10:44:09 +0200
+Subject: JFFS2: add missing verify buffer allocation/deallocation
+
+From: Massimo Cirillo <maxcir@gmail.com>
+
+commit bc8cec0dff072f1a45ce7f6b2c5234bb3411ac51 upstream.
+
+The function jffs2_nor_wbuf_flash_setup() doesn't allocate the verify buffer
+if CONFIG_JFFS2_FS_WBUF_VERIFY is defined, so causing a kernel panic when
+that macro is enabled and the verify function is called. Similarly the
+jffs2_nor_wbuf_flash_cleanup() must free the buffer if
+CONFIG_JFFS2_FS_WBUF_VERIFY is enabled.
+The following patch fixes the problem.
+The following patch applies to 2.6.30 kernel.
+
+Signed-off-by: Massimo Cirillo <maxcir@gmail.com>
+Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/jffs2/wbuf.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/fs/jffs2/wbuf.c
++++ b/fs/jffs2/wbuf.c
+@@ -1268,10 +1268,20 @@ int jffs2_nor_wbuf_flash_setup(struct jf
+ if (!c->wbuf)
+ return -ENOMEM;
+
++#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
++ c->wbuf_verify = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
++ if (!c->wbuf_verify) {
++ kfree(c->wbuf);
++ return -ENOMEM;
++ }
++#endif
+ return 0;
+ }
+
+ void jffs2_nor_wbuf_flash_cleanup(struct jffs2_sb_info *c) {
++#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
++ kfree(c->wbuf_verify);
++#endif
+ kfree(c->wbuf);
+ }
+
--- /dev/null
+From b1f1b8ce0a1d71cbc72f7540134d52b79bd8f5ac Mon Sep 17 00:00:00 2001
+From: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
+Date: Sun, 30 Aug 2009 04:21:41 +0900
+Subject: nilfs2: fix preempt count underflow in nilfs_btnode_prepare_change_key
+
+From: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
+
+commit b1f1b8ce0a1d71cbc72f7540134d52b79bd8f5ac upstream.
+
+This will fix the following preempt count underflow reported from
+users with the title "[NILFS users] segctord problem" (Message-ID:
+<949415.6494.qm@web58808.mail.re1.yahoo.com> and Message-ID:
+<debc30fc0908270825v747c1734xa59126623cfd5b05@mail.gmail.com>):
+
+ WARNING: at kernel/sched.c:4890 sub_preempt_count+0x95/0xa0()
+ Hardware name: HP Compaq 6530b (KR980UT#ABC)
+ Modules linked in: bridge stp llc bnep rfcomm l2cap xfs exportfs nilfs2 cowloop loop vboxnetadp vboxnetflt vboxdrv btusb bluetooth uvcvideo videodev v4l1_compat v4l2_compat_ioctl32 arc4 snd_hda_codec_analog ecb iwlagn iwlcore rfkill lib80211 mac80211 snd_hda_intel snd_hda_codec ehci_hcd uhci_hcd usbcore snd_hwdep snd_pcm tg3 cfg80211 psmouse snd_timer joydev libphy ohci1394 snd_page_alloc hp_accel lis3lv02d ieee1394 led_class i915 drm i2c_algo_bit video backlight output i2c_core dm_crypt dm_mod
+ Pid: 4197, comm: segctord Not tainted 2.6.30-gentoo-r4-64 #7
+ Call Trace:
+ [<ffffffff8023fa05>] ? sub_preempt_count+0x95/0xa0
+ [<ffffffff802470f8>] warn_slowpath_common+0x78/0xd0
+ [<ffffffff8024715f>] warn_slowpath_null+0xf/0x20
+ [<ffffffff8023fa05>] sub_preempt_count+0x95/0xa0
+ [<ffffffffa04ce4db>] nilfs_btnode_prepare_change_key+0x11b/0x190 [nilfs2]
+ [<ffffffffa04d01ad>] nilfs_btree_assign_p+0x19d/0x1e0 [nilfs2]
+ [<ffffffffa04d10ad>] nilfs_btree_assign+0xbd/0x130 [nilfs2]
+ [<ffffffffa04cead7>] nilfs_bmap_assign+0x47/0x70 [nilfs2]
+ [<ffffffffa04d9bc6>] nilfs_segctor_do_construct+0x956/0x20f0 [nilfs2]
+ [<ffffffff805ac8e2>] ? _spin_unlock_irqrestore+0x12/0x40
+ [<ffffffff803c06e0>] ? __up_write+0xe0/0x150
+ [<ffffffff80262959>] ? up_write+0x9/0x10
+ [<ffffffffa04ce9f3>] ? nilfs_bmap_test_and_clear_dirty+0x43/0x60 [nilfs2]
+ [<ffffffffa04cd627>] ? nilfs_mdt_fetch_dirty+0x27/0x60 [nilfs2]
+ [<ffffffffa04db5fc>] nilfs_segctor_construct+0x8c/0xd0 [nilfs2]
+ [<ffffffffa04dc3dc>] nilfs_segctor_thread+0x15c/0x3a0 [nilfs2]
+ [<ffffffffa04dbe20>] ? nilfs_construction_timeout+0x0/0x10 [nilfs2]
+ [<ffffffff80252633>] ? add_timer+0x13/0x20
+ [<ffffffff802370da>] ? __wake_up_common+0x5a/0x90
+ [<ffffffff8025e960>] ? autoremove_wake_function+0x0/0x40
+ [<ffffffffa04dc280>] ? nilfs_segctor_thread+0x0/0x3a0 [nilfs2]
+ [<ffffffffa04dc280>] ? nilfs_segctor_thread+0x0/0x3a0 [nilfs2]
+ [<ffffffff8025e556>] kthread+0x56/0x90
+ [<ffffffff8020cdea>] child_rip+0xa/0x20
+ [<ffffffff8025e500>] ? kthread+0x0/0x90
+ [<ffffffff8020cde0>] ? child_rip+0x0/0x20
+
+This problem was caused due to a missing radix_tree_preload() call in
+the retry path of nilfs_btnode_prepare_change_key() function.
+
+Reported-by: Eric A <eric225125@yahoo.com>
+Reported-by: Jerome Poulin <jeromepoulin@gmail.com>
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
+Tested-by: Jerome Poulin <jeromepoulin@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/nilfs2/btnode.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/nilfs2/btnode.c
++++ b/fs/nilfs2/btnode.c
+@@ -206,6 +206,7 @@ int nilfs_btnode_prepare_change_key(stru
+ * We cannot call radix_tree_preload for the kernels older
+ * than 2.6.23, because it is not exported for modules.
+ */
++retry:
+ err = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM);
+ if (err)
+ goto failed_unlock;
+@@ -216,7 +217,6 @@ int nilfs_btnode_prepare_change_key(stru
+ (unsigned long long)oldkey,
+ (unsigned long long)newkey);
+
+-retry:
+ spin_lock_irq(&btnc->tree_lock);
+ err = radix_tree_insert(&btnc->page_tree, newkey, obh->b_page);
+ spin_unlock_irq(&btnc->tree_lock);
--- /dev/null
+From 6faf17f6f1ffc586d16efc2f9fa2083a7785ee74 Mon Sep 17 00:00:00 2001
+From: Chris Wright <chrisw@sous-sol.org>
+Date: Fri, 28 Aug 2009 13:00:06 -0700
+Subject: PCI SR-IOV: correct broken resource alignment calculations
+
+From: Chris Wright <chrisw@sous-sol.org>
+
+commit 6faf17f6f1ffc586d16efc2f9fa2083a7785ee74 upstream.
+
+An SR-IOV capable device includes an SR-IOV PCIe capability which
+describes the Virtual Function (VF) BAR requirements. A typical SR-IOV
+device can support multiple VFs whose BARs must be in a contiguous region,
+effectively an array of VF BARs. The BAR reports the size requirement
+for a single VF. We calculate the full range needed by simply multiplying
+the VF BAR size with the number of possible VFs and create a resource
+spanning the full range.
+
+This all seems sane enough except it artificially inflates the alignment
+requirement for the VF BAR. The VF BAR need only be aligned to the size
+of a single BAR not the contiguous range of VF BARs. This can cause us
+to fail to allocate resources for the BAR despite the fact that we
+actually have enough space.
+
+This patch adds a thin PCI specific layer over the generic
+resource_alignment() function which is aware of the special nature of
+VF BARs and does sorting and allocation based on the smaller alignment
+requirement.
+
+I recognize that while resource_alignment is generic, it's basically a
+PCI helper. An alternative to this patch is to add PCI VF BAR specific
+information to struct resource. I opted for the extra layer rather than
+adding such PCI specific information to struct resource. This does
+have the slight downside that we don't cache the BAR size and re-read
+for each alignment query (happens a small handful of times during boot
+for each VF BAR).
+
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Matthew Wilcox <matthew@wil.cx>
+Cc: Yu Zhao <yu.zhao@intel.com>
+Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pci/iov.c | 23 +++++++++++++++++++++++
+ drivers/pci/pci.h | 13 +++++++++++++
+ drivers/pci/setup-bus.c | 4 ++--
+ drivers/pci/setup-res.c | 6 +++---
+ 4 files changed, 41 insertions(+), 5 deletions(-)
+
+--- a/drivers/pci/iov.c
++++ b/drivers/pci/iov.c
+@@ -595,6 +595,29 @@ int pci_iov_resource_bar(struct pci_dev
+ }
+
+ /**
++ * pci_sriov_resource_alignment - get resource alignment for VF BAR
++ * @dev: the PCI device
++ * @resno: the resource number
++ *
++ * Returns the alignment of the VF BAR found in the SR-IOV capability.
++ * This is not the same as the resource size which is defined as
++ * the VF BAR size multiplied by the number of VFs. The alignment
++ * is just the VF BAR size.
++ */
++int pci_sriov_resource_alignment(struct pci_dev *dev, int resno)
++{
++ struct resource tmp;
++ enum pci_bar_type type;
++ int reg = pci_iov_resource_bar(dev, resno, &type);
++
++ if (!reg)
++ return 0;
++
++ __pci_read_base(dev, type, &tmp, reg);
++ return resource_alignment(&tmp);
++}
++
++/**
+ * pci_restore_iov_state - restore the state of the IOV capability
+ * @dev: the PCI device
+ */
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -234,6 +234,7 @@ extern int pci_iov_init(struct pci_dev *
+ extern void pci_iov_release(struct pci_dev *dev);
+ extern int pci_iov_resource_bar(struct pci_dev *dev, int resno,
+ enum pci_bar_type *type);
++extern int pci_sriov_resource_alignment(struct pci_dev *dev, int resno);
+ extern void pci_restore_iov_state(struct pci_dev *dev);
+ extern int pci_iov_bus_range(struct pci_bus *bus);
+ #else
+@@ -259,4 +260,16 @@ static inline int pci_iov_bus_range(stru
+ }
+ #endif /* CONFIG_PCI_IOV */
+
++static inline int pci_resource_alignment(struct pci_dev *dev,
++ struct resource *res)
++{
++#ifdef CONFIG_PCI_IOV
++ int resno = res - dev->resource;
++
++ if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END)
++ return pci_sriov_resource_alignment(dev, resno);
++#endif
++ return resource_alignment(res);
++}
++
+ #endif /* DRIVERS_PCI_H */
+--- a/drivers/pci/setup-bus.c
++++ b/drivers/pci/setup-bus.c
+@@ -25,7 +25,7 @@
+ #include <linux/ioport.h>
+ #include <linux/cache.h>
+ #include <linux/slab.h>
+-
++#include "pci.h"
+
+ static void pbus_assign_resources_sorted(const struct pci_bus *bus)
+ {
+@@ -355,7 +355,7 @@ static int pbus_size_mem(struct pci_bus
+ continue;
+ r_size = resource_size(r);
+ /* For bridges size != alignment */
+- align = resource_alignment(r);
++ align = pci_resource_alignment(dev, r);
+ order = __ffs(align) - 20;
+ if (order > 11) {
+ dev_warn(&dev->dev, "BAR %d bad alignment %llx: "
+--- a/drivers/pci/setup-res.c
++++ b/drivers/pci/setup-res.c
+@@ -145,7 +145,7 @@ int pci_assign_resource(struct pci_dev *
+ size = resource_size(res);
+ min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
+
+- align = resource_alignment(res);
++ align = pci_resource_alignment(dev, res);
+ if (!align) {
+ dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus "
+ "alignment) %pR flags %#lx\n",
+@@ -236,7 +236,7 @@ void pdev_sort_resources(struct pci_dev
+ if (!(r->flags) || r->parent)
+ continue;
+
+- r_align = resource_alignment(r);
++ r_align = pci_resource_alignment(dev, r);
+ if (!r_align) {
+ dev_warn(&dev->dev, "BAR %d: bogus alignment "
+ "%pR flags %#lx\n",
+@@ -248,7 +248,7 @@ void pdev_sort_resources(struct pci_dev
+ struct resource_list *ln = list->next;
+
+ if (ln)
+- align = resource_alignment(ln->res);
++ align = pci_resource_alignment(ln->dev, ln->res);
+
+ if (r_align > align) {
+ tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
--- /dev/null
+From 601e7638254c118fca135af9b1a9f35061420f62 Mon Sep 17 00:00:00 2001
+From: James Bottomley <James.Bottomley@HansenPartnership.com>
+Date: Tue, 26 May 2009 20:35:48 +0000
+Subject: SCSI: sd: fix bug in SCSI async probing
+
+From: James Bottomley <James.Bottomley@HansenPartnership.com>
+
+commit 601e7638254c118fca135af9b1a9f35061420f62 upstream.
+
+The async split up of probing in sd.c created a potential failure case where
+something goes wrong with device_add(), but which we don't recover properly.
+Since, in general, asynchronous error handling is hard, move the device_add()
+into the asynchronous path (it should be fast) and make sure all the deferred
+processing cannot fail.
+
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/scsi/sd.c | 45 +++++++++++++++++++++------------------------
+ 1 file changed, 21 insertions(+), 24 deletions(-)
+
+--- a/drivers/scsi/sd.c
++++ b/drivers/scsi/sd.c
+@@ -1902,24 +1902,6 @@ static void sd_probe_async(void *data, a
+ index = sdkp->index;
+ dev = &sdp->sdev_gendev;
+
+- if (!sdp->request_queue->rq_timeout) {
+- if (sdp->type != TYPE_MOD)
+- blk_queue_rq_timeout(sdp->request_queue, SD_TIMEOUT);
+- else
+- blk_queue_rq_timeout(sdp->request_queue,
+- SD_MOD_TIMEOUT);
+- }
+-
+- device_initialize(&sdkp->dev);
+- sdkp->dev.parent = &sdp->sdev_gendev;
+- sdkp->dev.class = &sd_disk_class;
+- dev_set_name(&sdkp->dev, dev_name(&sdp->sdev_gendev));
+-
+- if (device_add(&sdkp->dev))
+- goto out_free_index;
+-
+- get_device(&sdp->sdev_gendev);
+-
+ if (index < SD_MAX_DISKS) {
+ gd->major = sd_major((index & 0xf0) >> 4);
+ gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
+@@ -1954,11 +1936,6 @@ static void sd_probe_async(void *data, a
+
+ sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
+ sdp->removable ? "removable " : "");
+-
+- return;
+-
+- out_free_index:
+- ida_remove(&sd_index_ida, index);
+ }
+
+ /**
+@@ -2026,6 +2003,24 @@ static int sd_probe(struct device *dev)
+ sdkp->openers = 0;
+ sdkp->previous_state = 1;
+
++ if (!sdp->request_queue->rq_timeout) {
++ if (sdp->type != TYPE_MOD)
++ blk_queue_rq_timeout(sdp->request_queue, SD_TIMEOUT);
++ else
++ blk_queue_rq_timeout(sdp->request_queue,
++ SD_MOD_TIMEOUT);
++ }
++
++ device_initialize(&sdkp->dev);
++ sdkp->dev.parent = &sdp->sdev_gendev;
++ sdkp->dev.class = &sd_disk_class;
++ dev_set_name(&sdkp->dev, dev_name(&sdp->sdev_gendev));
++
++ if (device_add(&sdkp->dev))
++ goto out_free_index;
++
++ get_device(&sdp->sdev_gendev);
++
+ async_schedule(sd_probe_async, sdkp);
+
+ return 0;
+@@ -2055,8 +2050,10 @@ static int sd_probe(struct device *dev)
+ **/
+ static int sd_remove(struct device *dev)
+ {
+- struct scsi_disk *sdkp = dev_get_drvdata(dev);
++ struct scsi_disk *sdkp;
+
++ async_synchronize_full();
++ sdkp = dev_get_drvdata(dev);
+ device_del(&sdkp->dev);
+ del_gendisk(sdkp->disk);
+ sd_shutdown(dev);
sparc64-validate-linear-d-tlb-misses.patch
sparc64-fix-bootup-with-mcount-in-some-configs.patch
sparc-sys32.s-incorrect-compat-layer-splice-system-call.patch
+jffs2-add-missing-verify-buffer-allocation-deallocation.patch
+slub-fix-kmem_cache_destroy-with-slab_destroy_by_rcu.patch
+nilfs2-fix-preempt-count-underflow-in-nilfs_btnode_prepare_change_key.patch
+pci-sr-iov-correct-broken-resource-alignment-calculations.patch
+scsi-sd-fix-bug-in-scsi-async-probing.patch
+sound-oxygen-handle-cards-with-missing-eeprom.patch
+sound-oxygen-fix-mclk-rate-for-192-khz-playback.patch
+dm-raid1-do-not-allow-log_failure-variable-to-unset-after-being-set.patch
+dm-snapshot-refactor-zero_disk_area-to-use-chunk_io.patch
+dm-snapshot-fix-header-corruption-race-on-invalidation.patch
+dm-exception-store-split-set_chunk_size.patch
+dm-snapshot-fix-on-disk-chunk-size-validation.patch
--- /dev/null
+From d76b1590e06a63a3d8697168cd0aabf1c4b3cb3a Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <eric.dumazet@gmail.com>
+Date: Thu, 3 Sep 2009 22:38:59 +0300
+Subject: slub: Fix kmem_cache_destroy() with SLAB_DESTROY_BY_RCU
+
+From: Eric Dumazet <eric.dumazet@gmail.com>
+
+commit d76b1590e06a63a3d8697168cd0aabf1c4b3cb3a upstream.
+
+kmem_cache_destroy() should call rcu_barrier() *after* kmem_cache_close() and
+*before* sysfs_slab_remove() or risk rcu_free_slab() being called after
+kmem_cache is deleted (kfreed).
+
+rmmod nf_conntrack can crash the machine because it has to kmem_cache_destroy()
+a SLAB_DESTROY_BY_RCU enabled cache.
+
+Reported-by: Zdenek Kabelac <zdenek.kabelac@gmail.com>
+Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
+Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ mm/slub.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/mm/slub.c
++++ b/mm/slub.c
+@@ -2490,8 +2490,6 @@ static inline int kmem_cache_close(struc
+ */
+ void kmem_cache_destroy(struct kmem_cache *s)
+ {
+- if (s->flags & SLAB_DESTROY_BY_RCU)
+- rcu_barrier();
+ down_write(&slub_lock);
+ s->refcount--;
+ if (!s->refcount) {
+@@ -2502,6 +2500,8 @@ void kmem_cache_destroy(struct kmem_cach
+ "still has objects.\n", s->name, __func__);
+ dump_stack();
+ }
++ if (s->flags & SLAB_DESTROY_BY_RCU)
++ rcu_barrier();
+ sysfs_slab_remove(s);
+ } else
+ up_write(&slub_lock);
--- /dev/null
+From b91ab72b830e1494c2c7f8de05ccb2ab2c9cfb26 Mon Sep 17 00:00:00 2001
+From: Clemens Ladisch <clemens@ladisch.de>
+Date: Tue, 1 Sep 2009 08:23:58 +0200
+Subject: sound: oxygen: fix MCLK rate for 192 kHz playback
+
+From: Clemens Ladisch <clemens@ladisch.de>
+
+commit b91ab72b830e1494c2c7f8de05ccb2ab2c9cfb26 upstream.
+
+Do not forget to program the MCLK ratio for the I2S output.
+Otherwise, the master clock frequency can be too high for
+the DACs at sample frequencies above 96 kHz.
+
+Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/pci/oxygen/oxygen_pcm.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/sound/pci/oxygen/oxygen_pcm.c
++++ b/sound/pci/oxygen/oxygen_pcm.c
+@@ -469,9 +469,11 @@ static int oxygen_multich_hw_params(stru
+ oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
+ oxygen_rate(hw_params) |
+ chip->model.dac_i2s_format |
++ oxygen_i2s_mclk(hw_params) |
+ oxygen_i2s_bits(hw_params),
+ OXYGEN_I2S_RATE_MASK |
+ OXYGEN_I2S_FORMAT_MASK |
++ OXYGEN_I2S_MCLK_MASK |
+ OXYGEN_I2S_BITS_MASK);
+ oxygen_update_dac_routing(chip);
+ oxygen_update_spdif_source(chip);
--- /dev/null
+From 92653453c3015c083b9fe0ad48261c6b2267d482 Mon Sep 17 00:00:00 2001
+From: Clemens Ladisch <clemens@ladisch.de>
+Date: Wed, 2 Sep 2009 18:25:39 +0200
+Subject: sound: oxygen: handle cards with missing EEPROM
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Clemens Ladisch <clemens@ladisch.de>
+
+commit 92653453c3015c083b9fe0ad48261c6b2267d482 upstream.
+
+The card model detection code introduced in 2.6.30 that tries to work
+around partially broken EEPROM contents by reading the EEPROM directly
+does not handle cards where the EEPROM has been omitted. In this case,
+we have to use the default ID to allow the driver to load.
+
+Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
+Reported-and-tested-by: Ozan Çağlayan <ozan@pardus.org.tr>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/pci/oxygen/oxygen_lib.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/sound/pci/oxygen/oxygen_lib.c
++++ b/sound/pci/oxygen/oxygen_lib.c
+@@ -260,6 +260,9 @@ oxygen_search_pci_id(struct oxygen *chip
+ * chip didn't if the first EEPROM word was overwritten.
+ */
+ subdevice = oxygen_read_eeprom(chip, 2);
++ /* use default ID if EEPROM is missing */
++ if (subdevice == 0xffff)
++ subdevice = 0x8788;
+ /*
+ * We use only the subsystem device ID for searching because it is
+ * unique even without the subsystem vendor ID, which may have been