From: Greg Kroah-Hartman Date: Tue, 12 May 2009 19:27:17 +0000 (-0700) Subject: start .29 series up X-Git-Tag: v2.6.29.4~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c7ba85e58b422a56bdada7d79d93d05ed8f6844e;p=thirdparty%2Fkernel%2Fstable-queue.git start .29 series up --- diff --git a/queue-2.6.29/alsa-hda-fix-line-in-on-mac-mini-core2-duo.patch b/queue-2.6.29/alsa-hda-fix-line-in-on-mac-mini-core2-duo.patch new file mode 100644 index 00000000000..9b38fd5f4b0 --- /dev/null +++ b/queue-2.6.29/alsa-hda-fix-line-in-on-mac-mini-core2-duo.patch @@ -0,0 +1,38 @@ +From 5dd17cb992ef4c1ebb1a2d60cbef4b6967974673 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Thu, 7 May 2009 16:22:53 +0200 +Subject: ALSA: hda - Fix line-in on Mac Mini Core2 Duo + +From: Takashi Iwai + +commit 5dd17cb992ef4c1ebb1a2d60cbef4b6967974673 upstream. + +BIOS on Mac Mini Core2 Duo sets both INPUT and OUTPUT pinctl bits to +the line-in jack, and it confuses the driver as if it's a valid input. +This patch adds the check of OUTPUT bit so that the driver fixes the +invalid pin setup. + +Tested-by: Tino Keitel +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_sigmatel.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/sound/pci/hda/patch_sigmatel.c ++++ b/sound/pci/hda/patch_sigmatel.c +@@ -4007,7 +4007,12 @@ static int stac92xx_init(struct hda_code + pinctl = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); + /* if PINCTL already set then skip */ +- if (!(pinctl & AC_PINCTL_IN_EN)) { ++ /* Also, if both INPUT and OUTPUT are set, ++ * it must be a BIOS bug; need to override, too ++ */ ++ if (!(pinctl & AC_PINCTL_IN_EN) || ++ (pinctl & AC_PINCTL_OUT_EN)) { ++ pinctl &= ~AC_PINCTL_OUT_EN; + pinctl |= AC_PINCTL_IN_EN; + stac92xx_auto_set_pinctl(codec, nid, + pinctl); diff --git a/queue-2.6.29/asoc-fix-errors-in-wm8990.patch b/queue-2.6.29/asoc-fix-errors-in-wm8990.patch new file mode 100644 index 00000000000..c09a9cefd72 --- /dev/null +++ b/queue-2.6.29/asoc-fix-errors-in-wm8990.patch @@ -0,0 +1,115 @@ +From 97a775c49c7e1b47b016a492463486a5b86da479 Mon Sep 17 00:00:00 2001 +From: Jinyoung Park +Date: Fri, 1 May 2009 12:54:31 +0100 +Subject: ASoC: Fix errors in WM8990 + +From: Jinyoung Park + +commit 97a775c49c7e1b47b016a492463486a5b86da479 upstream. + +The mis-typing exist in dapm controller definitions and dapm route definitions, +so happen mis-matched error when snd_soc_dapm_add_routes(). + +Signed-off-by: Jinyoung Park +Signed-off-by: Mark Brown + +--- + sound/soc/codecs/wm8990.c | 40 ++++++++++++++++++++-------------------- + 1 file changed, 20 insertions(+), 20 deletions(-) + +--- a/sound/soc/codecs/wm8990.c ++++ b/sound/soc/codecs/wm8990.c +@@ -744,7 +744,7 @@ SND_SOC_DAPM_MIXER_E("INMIXL", WM8990_IN + inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + /* AINLMUX */ +-SND_SOC_DAPM_MUX_E("AILNMUX", WM8990_INTDRIVBITS, WM8990_AINLMUX_PWR_BIT, 0, ++SND_SOC_DAPM_MUX_E("AINLMUX", WM8990_INTDRIVBITS, WM8990_AINLMUX_PWR_BIT, 0, + &wm8990_dapm_ainlmux_controls, inmixer_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + +@@ -755,7 +755,7 @@ SND_SOC_DAPM_MIXER_E("INMIXR", WM8990_IN + inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + /* AINRMUX */ +-SND_SOC_DAPM_MUX_E("AIRNMUX", WM8990_INTDRIVBITS, WM8990_AINRMUX_PWR_BIT, 0, ++SND_SOC_DAPM_MUX_E("AINRMUX", WM8990_INTDRIVBITS, WM8990_AINRMUX_PWR_BIT, 0, + &wm8990_dapm_ainrmux_controls, inmixer_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + +@@ -863,40 +863,40 @@ static const struct snd_soc_dapm_route a + {"LIN12 PGA", "LIN2 Switch", "LIN2"}, + /* LIN34 PGA */ + {"LIN34 PGA", "LIN3 Switch", "LIN3"}, +- {"LIN34 PGA", "LIN4 Switch", "LIN4"}, ++ {"LIN34 PGA", "LIN4 Switch", "LIN4/RXN"}, + /* INMIXL */ + {"INMIXL", "Record Left Volume", "LOMIX"}, + {"INMIXL", "LIN2 Volume", "LIN2"}, + {"INMIXL", "LINPGA12 Switch", "LIN12 PGA"}, + {"INMIXL", "LINPGA34 Switch", "LIN34 PGA"}, +- /* AILNMUX */ +- {"AILNMUX", "INMIXL Mix", "INMIXL"}, +- {"AILNMUX", "DIFFINL Mix", "LIN12PGA"}, +- {"AILNMUX", "DIFFINL Mix", "LIN34PGA"}, +- {"AILNMUX", "RXVOICE Mix", "LIN4/RXN"}, +- {"AILNMUX", "RXVOICE Mix", "RIN4/RXP"}, ++ /* AINLMUX */ ++ {"AINLMUX", "INMIXL Mix", "INMIXL"}, ++ {"AINLMUX", "DIFFINL Mix", "LIN12 PGA"}, ++ {"AINLMUX", "DIFFINL Mix", "LIN34 PGA"}, ++ {"AINLMUX", "RXVOICE Mix", "LIN4/RXN"}, ++ {"AINLMUX", "RXVOICE Mix", "RIN4/RXP"}, + /* ADC */ +- {"Left ADC", NULL, "AILNMUX"}, ++ {"Left ADC", NULL, "AINLMUX"}, + + /* RIN12 PGA */ + {"RIN12 PGA", "RIN1 Switch", "RIN1"}, + {"RIN12 PGA", "RIN2 Switch", "RIN2"}, + /* RIN34 PGA */ + {"RIN34 PGA", "RIN3 Switch", "RIN3"}, +- {"RIN34 PGA", "RIN4 Switch", "RIN4"}, ++ {"RIN34 PGA", "RIN4 Switch", "RIN4/RXP"}, + /* INMIXL */ + {"INMIXR", "Record Right Volume", "ROMIX"}, + {"INMIXR", "RIN2 Volume", "RIN2"}, + {"INMIXR", "RINPGA12 Switch", "RIN12 PGA"}, + {"INMIXR", "RINPGA34 Switch", "RIN34 PGA"}, +- /* AIRNMUX */ +- {"AIRNMUX", "INMIXR Mix", "INMIXR"}, +- {"AIRNMUX", "DIFFINR Mix", "RIN12PGA"}, +- {"AIRNMUX", "DIFFINR Mix", "RIN34PGA"}, +- {"AIRNMUX", "RXVOICE Mix", "RIN4/RXN"}, +- {"AIRNMUX", "RXVOICE Mix", "RIN4/RXP"}, ++ /* AINRMUX */ ++ {"AINRMUX", "INMIXR Mix", "INMIXR"}, ++ {"AINRMUX", "DIFFINR Mix", "RIN12 PGA"}, ++ {"AINRMUX", "DIFFINR Mix", "RIN34 PGA"}, ++ {"AINRMUX", "RXVOICE Mix", "LIN4/RXN"}, ++ {"AINRMUX", "RXVOICE Mix", "RIN4/RXP"}, + /* ADC */ +- {"Right ADC", NULL, "AIRNMUX"}, ++ {"Right ADC", NULL, "AINRMUX"}, + + /* LOMIX */ + {"LOMIX", "LOMIX RIN3 Bypass Switch", "RIN3"}, +@@ -937,7 +937,7 @@ static const struct snd_soc_dapm_route a + {"LOPMIX", "LOPMIX Left Mixer PGA Switch", "LOPGA"}, + + /* OUT3MIX */ +- {"OUT3MIX", "OUT3MIX LIN4/RXP Bypass Switch", "LIN4/RXP"}, ++ {"OUT3MIX", "OUT3MIX LIN4/RXP Bypass Switch", "LIN4/RXN"}, + {"OUT3MIX", "OUT3MIX Left Out PGA Switch", "LOPGA"}, + + /* OUT4MIX */ +@@ -964,7 +964,7 @@ static const struct snd_soc_dapm_route a + /* Output Pins */ + {"LON", NULL, "LONMIX"}, + {"LOP", NULL, "LOPMIX"}, +- {"OUT", NULL, "OUT3MIX"}, ++ {"OUT3", NULL, "OUT3MIX"}, + {"LOUT", NULL, "LOUT PGA"}, + {"SPKN", NULL, "SPKMIX"}, + {"ROUT", NULL, "ROUT PGA"}, diff --git a/queue-2.6.29/fiemap-fix-problem-with-setting-fiemap_extent_last.patch b/queue-2.6.29/fiemap-fix-problem-with-setting-fiemap_extent_last.patch new file mode 100644 index 00000000000..f6dca6b8056 --- /dev/null +++ b/queue-2.6.29/fiemap-fix-problem-with-setting-fiemap_extent_last.patch @@ -0,0 +1,150 @@ +From df3935ffd6166fdd00702cf548fb5bb55737758b Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Wed, 6 May 2009 16:02:53 -0700 +Subject: fiemap: fix problem with setting FIEMAP_EXTENT_LAST + +From: Josef Bacik + +commit df3935ffd6166fdd00702cf548fb5bb55737758b upstream. + +Fix a problem where the generic block based fiemap stuff would not +properly set FIEMAP_EXTENT_LAST on the last extent. I've reworked things +to keep track if we go past the EOF, and mark the last extent properly. +The problem was reported by and tested by Eric Sandeen. + +Tested-by: Eric Sandeen +Signed-off-by: Josef Bacik +Cc: +Cc: +Cc: +Cc: Steven Whitehouse +Cc: Mark Fasheh +Cc: Joel Becker +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ioctl.c | 75 ++++++++++++++++++++++++++++++++++++++++++++----------------- + 1 file changed, 55 insertions(+), 20 deletions(-) + +--- a/fs/ioctl.c ++++ b/fs/ioctl.c +@@ -258,7 +258,7 @@ int __generic_block_fiemap(struct inode + long long length = 0, map_len = 0; + u64 logical = 0, phys = 0, size = 0; + u32 flags = FIEMAP_EXTENT_MERGED; +- int ret = 0; ++ int ret = 0, past_eof = 0, whole_file = 0; + + if ((ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC))) + return ret; +@@ -266,6 +266,9 @@ int __generic_block_fiemap(struct inode + start_blk = logical_to_blk(inode, start); + + length = (long long)min_t(u64, len, i_size_read(inode)); ++ if (length < len) ++ whole_file = 1; ++ + map_len = length; + + do { +@@ -282,11 +285,26 @@ int __generic_block_fiemap(struct inode + + /* HOLE */ + if (!buffer_mapped(&tmp)) { ++ length -= blk_to_logical(inode, 1); ++ start_blk++; ++ ++ /* ++ * we want to handle the case where there is an ++ * allocated block at the front of the file, and then ++ * nothing but holes up to the end of the file properly, ++ * to make sure that extent at the front gets properly ++ * marked with FIEMAP_EXTENT_LAST ++ */ ++ if (!past_eof && ++ blk_to_logical(inode, start_blk) >= ++ blk_to_logical(inode, 0)+i_size_read(inode)) ++ past_eof = 1; ++ + /* + * first hole after going past the EOF, this is our + * last extent + */ +- if (length <= 0) { ++ if (past_eof && size) { + flags = FIEMAP_EXTENT_MERGED|FIEMAP_EXTENT_LAST; + ret = fiemap_fill_next_extent(fieinfo, logical, + phys, size, +@@ -294,15 +312,37 @@ int __generic_block_fiemap(struct inode + break; + } + +- length -= blk_to_logical(inode, 1); +- + /* if we have holes up to/past EOF then we're done */ +- if (length <= 0) ++ if (length <= 0 || past_eof) + break; +- +- start_blk++; + } else { +- if (length <= 0 && size) { ++ /* ++ * we have gone over the length of what we wanted to ++ * map, and it wasn't the entire file, so add the extent ++ * we got last time and exit. ++ * ++ * This is for the case where say we want to map all the ++ * way up to the second to the last block in a file, but ++ * the last block is a hole, making the second to last ++ * block FIEMAP_EXTENT_LAST. In this case we want to ++ * see if there is a hole after the second to last block ++ * so we can mark it properly. If we found data after ++ * we exceeded the length we were requesting, then we ++ * are good to go, just add the extent to the fieinfo ++ * and break ++ */ ++ if (length <= 0 && !whole_file) { ++ ret = fiemap_fill_next_extent(fieinfo, logical, ++ phys, size, ++ flags); ++ break; ++ } ++ ++ /* ++ * if size != 0 then we know we already have an extent ++ * to add, so add it. ++ */ ++ if (size) { + ret = fiemap_fill_next_extent(fieinfo, logical, + phys, size, + flags); +@@ -319,19 +359,14 @@ int __generic_block_fiemap(struct inode + start_blk += logical_to_blk(inode, size); + + /* +- * if we are past the EOF we need to loop again to see +- * if there is a hole so we can mark this extent as the +- * last one, and if not keep mapping things until we +- * find a hole, or we run out of slots in the extent +- * array ++ * If we are past the EOF, then we need to make sure as ++ * soon as we find a hole that the last extent we found ++ * is marked with FIEMAP_EXTENT_LAST + */ +- if (length <= 0) +- continue; +- +- ret = fiemap_fill_next_extent(fieinfo, logical, phys, +- size, flags); +- if (ret) +- break; ++ if (!past_eof && ++ logical+size >= ++ blk_to_logical(inode, 0)+i_size_read(inode)) ++ past_eof = 1; + } + cond_resched(); + } while (1); diff --git a/queue-2.6.29/md-fix-loading-of-out-of-date-bitmap.patch b/queue-2.6.29/md-fix-loading-of-out-of-date-bitmap.patch new file mode 100644 index 00000000000..88c06ce9beb --- /dev/null +++ b/queue-2.6.29/md-fix-loading-of-out-of-date-bitmap.patch @@ -0,0 +1,59 @@ +From b74fd2826c5acce20e6f691437b2d19372bc2057 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Thu, 7 May 2009 12:47:19 +1000 +Subject: md: fix loading of out-of-date bitmap. + +From: NeilBrown + +commit b74fd2826c5acce20e6f691437b2d19372bc2057 upstream. + +When md is loading a bitmap which it knows is out of date, it fills +each page with 1s and writes it back out again. However the +write_page call makes used of bitmap->file_pages and +bitmap->last_page_size which haven't been set correctly yet. So this +can sometimes fail. + +Move the setting of file_pages and last_page_size to before the call +to write_page. + +This bug can cause the assembly on an array to fail, thus making the +data inaccessible. Hence I think it is a suitable candidate for +-stable. + +Reported-by: Vojtech Pavlik +Signed-off-by: NeilBrown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/bitmap.c | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) + +--- a/drivers/md/bitmap.c ++++ b/drivers/md/bitmap.c +@@ -985,6 +985,9 @@ static int bitmap_init_from_disk(struct + oldindex = index; + oldpage = page; + ++ bitmap->filemap[bitmap->file_pages++] = page; ++ bitmap->last_page_size = count; ++ + if (outofdate) { + /* + * if bitmap is out of date, dirty the +@@ -997,15 +1000,9 @@ static int bitmap_init_from_disk(struct + write_page(bitmap, page, 1); + + ret = -EIO; +- if (bitmap->flags & BITMAP_WRITE_ERROR) { +- /* release, page not in filemap yet */ +- put_page(page); ++ if (bitmap->flags & BITMAP_WRITE_ERROR) + goto err; +- } + } +- +- bitmap->filemap[bitmap->file_pages++] = page; +- bitmap->last_page_size = count; + } + paddr = kmap_atomic(page, KM_USER0); + if (bitmap->flags & BITMAP_HOSTENDIAN) diff --git a/queue-2.6.29/md-fix-some-errors-with-bitmaps-on-devices-larger-than-2tb.patch b/queue-2.6.29/md-fix-some-errors-with-bitmaps-on-devices-larger-than-2tb.patch new file mode 100644 index 00000000000..fc06f84e7b6 --- /dev/null +++ b/queue-2.6.29/md-fix-some-errors-with-bitmaps-on-devices-larger-than-2tb.patch @@ -0,0 +1,73 @@ +From db305e507d554430a69ede901a6308e6ecb72349 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Thu, 7 May 2009 12:49:06 +1000 +Subject: md: fix some (more) errors with bitmaps on devices larger than 2TB. + +From: NeilBrown + +commit db305e507d554430a69ede901a6308e6ecb72349 upstream. + +If a write intent bitmap covers more than 2TB, we sometimes work with +values beyond 32bit, so these need to be sector_t. This patches +add the required casts to some unsigned longs that are being shifted +up. + +This will affect any raid10 larger than 2TB, or any raid1/4/5/6 with +member devices that are larger than 2TB. + +Signed-off-by: NeilBrown +Reported-by: "Mario 'BitKoenig' Holbe" +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/bitmap.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +--- a/drivers/md/bitmap.c ++++ b/drivers/md/bitmap.c +@@ -1015,9 +1015,11 @@ static int bitmap_init_from_disk(struct + kunmap_atomic(paddr, KM_USER0); + if (b) { + /* if the disk bit is set, set the memory bit */ +- bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap), +- ((i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) >= start) +- ); ++ int needed = ((sector_t)(i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) ++ >= start); ++ bitmap_set_memory_bits(bitmap, ++ (sector_t)i << CHUNK_BLOCK_SHIFT(bitmap), ++ needed); + bit_cnt++; + set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); + } +@@ -1153,8 +1155,9 @@ void bitmap_daemon_work(struct bitmap *b + spin_lock_irqsave(&bitmap->lock, flags); + clear_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); + } +- bmc = bitmap_get_counter(bitmap, j << CHUNK_BLOCK_SHIFT(bitmap), +- &blocks, 0); ++ bmc = bitmap_get_counter(bitmap, ++ (sector_t)j << CHUNK_BLOCK_SHIFT(bitmap), ++ &blocks, 0); + if (bmc) { + /* + if (j < 100) printk("bitmap: j=%lu, *bmc = 0x%x\n", j, *bmc); +@@ -1168,7 +1171,8 @@ void bitmap_daemon_work(struct bitmap *b + } else if (*bmc == 1) { + /* we can clear the bit */ + *bmc = 0; +- bitmap_count_page(bitmap, j << CHUNK_BLOCK_SHIFT(bitmap), ++ bitmap_count_page(bitmap, ++ (sector_t)j << CHUNK_BLOCK_SHIFT(bitmap), + -1); + + /* clear the bit */ +@@ -1484,7 +1488,7 @@ void bitmap_dirty_bits(struct bitmap *bi + unsigned long chunk; + + for (chunk = s; chunk <= e; chunk++) { +- sector_t sec = chunk << CHUNK_BLOCK_SHIFT(bitmap); ++ sector_t sec = (sector_t)chunk << CHUNK_BLOCK_SHIFT(bitmap); + bitmap_set_memory_bits(bitmap, sec, 1); + bitmap_file_set_bit(bitmap, sec); + } diff --git a/queue-2.6.29/md-raid10-don-t-clear-bitmap-during-recovery-if-array-will-still-be-degraded.patch b/queue-2.6.29/md-raid10-don-t-clear-bitmap-during-recovery-if-array-will-still-be-degraded.patch new file mode 100644 index 00000000000..bf268947850 --- /dev/null +++ b/queue-2.6.29/md-raid10-don-t-clear-bitmap-during-recovery-if-array-will-still-be-degraded.patch @@ -0,0 +1,56 @@ +From 18055569127253755d01733f6ecc004ed02f88d0 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Thu, 7 May 2009 12:48:10 +1000 +Subject: md/raid10: don't clear bitmap during recovery if array will still be degraded. + +From: NeilBrown + +commit 18055569127253755d01733f6ecc004ed02f88d0 upstream. + +If we have a raid10 with multiple missing devices, and we recover just +one of these to a spare, then we risk (depending on the bitmap and +array chunk size) clearing bits of the bitmap for which recovery isn't +complete (because a device is still missing). + +This can lead to a subsequent "re-add" being recovered without +any IO happening, which would result in loss of data. + +This patch takes the safe approach of not clearing bitmap bits +if the array will still be degraded. + +This patch is suitable for all active -stable kernels. + +Cc: stable@kernel.org +Signed-off-by: NeilBrown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/raid10.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -1807,17 +1807,17 @@ static sector_t sync_request(mddev_t *md + r10_bio->sector = sect; + + raid10_find_phys(conf, r10_bio); +- /* Need to check if this section will still be ++ ++ /* Need to check if the array will still be + * degraded + */ +- for (j=0; jcopies;j++) { +- int d = r10_bio->devs[j].devnum; +- if (conf->mirrors[d].rdev == NULL || +- test_bit(Faulty, &conf->mirrors[d].rdev->flags)) { ++ for (j=0; jraid_disks; j++) ++ if (conf->mirrors[j].rdev == NULL || ++ test_bit(Faulty, &conf->mirrors[j].rdev->flags)) { + still_degraded = 1; + break; + } +- } ++ + must_sync = bitmap_start_sync(mddev->bitmap, sect, + &sync_blocks, still_degraded); + diff --git a/queue-2.6.29/md-remove-ability-to-explicit-set-an-inactive-array-to-clean.patch b/queue-2.6.29/md-remove-ability-to-explicit-set-an-inactive-array-to-clean.patch new file mode 100644 index 00000000000..9e8da3fadfe --- /dev/null +++ b/queue-2.6.29/md-remove-ability-to-explicit-set-an-inactive-array-to-clean.patch @@ -0,0 +1,57 @@ +From 5bf295975416f8e97117bbbcfb0191c00bc3e2b4 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Thu, 7 May 2009 12:50:57 +1000 +Subject: md: remove ability to explicit set an inactive array to 'clean'. + +From: NeilBrown + +commit 5bf295975416f8e97117bbbcfb0191c00bc3e2b4 upstream. + +Being able to write 'clean' to an 'array_state' of an inactive array +to activate it in 'clean' mode is both unnecessary and inconvenient. + +It is unnecessary because the same can be achieved by writing +'active'. This activates and array, but it still remains 'clean' +until the first write. + +It is inconvenient because writing 'clean' is more often used to +cause an 'active' array to revert to 'clean' mode (thus blocking +any writes until a 'write-pending' is promoted to 'active'). + +Allowing 'clean' to both activate an array and mark an active array as +clean can lead to races: One program writes 'clean' to mark the +active array as clean at the same time as another program writes +'inactive' to deactivate (stop) and active array. Depending on which +writes first, the array could be deactivated and immediately +reactivated which isn't what was desired. + +So just disable the use of 'clean' to activate an array. + +This avoids a race that can be triggered with mdadm-3.0 and external +metadata, so it suitable for -stable. + +Reported-by: Rafal Marszewski +Acked-by: Dan Williams +Signed-off-by: NeilBrown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/md.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -2844,11 +2844,8 @@ array_state_store(mddev_t *mddev, const + } else + err = -EBUSY; + spin_unlock_irq(&mddev->write_lock); +- } else { +- mddev->ro = 0; +- mddev->recovery_cp = MaxSector; +- err = do_md_run(mddev); +- } ++ } else ++ err = -EINVAL; + break; + case active: + if (mddev->pers) { diff --git a/queue-2.6.29/series b/queue-2.6.29/series new file mode 100644 index 00000000000..149de8b3ce1 --- /dev/null +++ b/queue-2.6.29/series @@ -0,0 +1,9 @@ +fiemap-fix-problem-with-setting-fiemap_extent_last.patch +md-remove-ability-to-explicit-set-an-inactive-array-to-clean.patch +md-fix-some-errors-with-bitmaps-on-devices-larger-than-2tb.patch +md-raid10-don-t-clear-bitmap-during-recovery-if-array-will-still-be-degraded.patch +md-fix-loading-of-out-of-date-bitmap.patch +usb-serial-ftdi_sio-fix-reference-counting-of-ftdi_private.patch +usb-gadget-fix-utf-conversion-in-the-usbstring-library.patch +alsa-hda-fix-line-in-on-mac-mini-core2-duo.patch +asoc-fix-errors-in-wm8990.patch diff --git a/queue-2.6.29/usb-gadget-fix-utf-conversion-in-the-usbstring-library.patch b/queue-2.6.29/usb-gadget-fix-utf-conversion-in-the-usbstring-library.patch new file mode 100644 index 00000000000..a0b80f48227 --- /dev/null +++ b/queue-2.6.29/usb-gadget-fix-utf-conversion-in-the-usbstring-library.patch @@ -0,0 +1,50 @@ +From 0f43158caddcbb110916212ebe4e39993ae70864 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Mon, 27 Apr 2009 13:22:40 -0400 +Subject: USB: Gadget: fix UTF conversion in the usbstring library + +From: Alan Stern + +commit 0f43158caddcbb110916212ebe4e39993ae70864 upstream. + +This patch (as1234) fixes a bug in the UTF8 -> UTF-16 conversion +routine in the gadget/usbstring library. In a UTF-8 multi-byte +sequence, all bytes after the first should have their high-order +two bits set to 10, not 11. + +Signed-off-by: Alan Stern +Acked-by: David Brownell +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/usbstring.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/usb/gadget/usbstring.c ++++ b/drivers/usb/gadget/usbstring.c +@@ -38,7 +38,7 @@ static int utf8_to_utf16le(const char *s + uchar = (c & 0x1f) << 6; + + c = (u8) *s++; +- if ((c & 0xc0) != 0xc0) ++ if ((c & 0xc0) != 0x80) + goto fail; + c &= 0x3f; + uchar |= c; +@@ -49,13 +49,13 @@ static int utf8_to_utf16le(const char *s + uchar = (c & 0x0f) << 12; + + c = (u8) *s++; +- if ((c & 0xc0) != 0xc0) ++ if ((c & 0xc0) != 0x80) + goto fail; + c &= 0x3f; + uchar |= c << 6; + + c = (u8) *s++; +- if ((c & 0xc0) != 0xc0) ++ if ((c & 0xc0) != 0x80) + goto fail; + c &= 0x3f; + uchar |= c; diff --git a/queue-2.6.29/usb-serial-ftdi_sio-fix-reference-counting-of-ftdi_private.patch b/queue-2.6.29/usb-serial-ftdi_sio-fix-reference-counting-of-ftdi_private.patch new file mode 100644 index 00000000000..79daa967dc0 --- /dev/null +++ b/queue-2.6.29/usb-serial-ftdi_sio-fix-reference-counting-of-ftdi_private.patch @@ -0,0 +1,92 @@ +From c45d63202fbaccef7ef7946c03f27f72c809b1cc Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Thu, 30 Apr 2009 10:06:19 -0400 +Subject: usb-serial: ftdi_sio: fix reference counting of ftdi_private + +From: Alan Stern + +commit c45d63202fbaccef7ef7946c03f27f72c809b1cc upstream. + +This patch (as1238) adds proper reference counting for ftdi_sio's +private data structure. Without it, the driver will free the +structure while it is still in use if the user unplugs the serial +device before closing the device file. + +The patch also replaces a slightly dangerous +cancel_delayed_work/flush_scheduled_work pair with +cancel_delayed_work_sync, which is always safer. + +Signed-off-by: Alan Stern +Reported-by: Daniel Mack +Tested-by: Daniel Mack +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ftdi_sio.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -56,6 +56,7 @@ static __u16 vendor = FTDI_VID; + static __u16 product; + + struct ftdi_private { ++ struct kref kref; + ftdi_chip_type_t chip_type; + /* type of device, either SIO or FT8U232AM */ + int baud_base; /* baud base clock for divisor setting */ +@@ -1352,6 +1353,7 @@ static int ftdi_sio_port_probe(struct us + return -ENOMEM; + } + ++ kref_init(&priv->kref); + spin_lock_init(&priv->rx_lock); + spin_lock_init(&priv->tx_lock); + init_waitqueue_head(&priv->delta_msr_wait); +@@ -1468,6 +1470,13 @@ static void ftdi_shutdown(struct usb_ser + dbg("%s", __func__); + } + ++static void ftdi_sio_priv_release(struct kref *k) ++{ ++ struct ftdi_private *priv = container_of(k, struct ftdi_private, kref); ++ ++ kfree(priv); ++} ++ + static int ftdi_sio_port_remove(struct usb_serial_port *port) + { + struct ftdi_private *priv = usb_get_serial_port_data(port); +@@ -1482,7 +1491,7 @@ static int ftdi_sio_port_remove(struct u + + if (priv) { + usb_set_serial_port_data(port, NULL); +- kfree(priv); ++ kref_put(&priv->kref, ftdi_sio_priv_release); + } + + return 0; +@@ -1547,7 +1556,8 @@ static int ftdi_open(struct tty_struct * + dev_err(&port->dev, + "%s - failed submitting read urb, error %d\n", + __func__, result); +- ++ else ++ kref_get(&priv->kref); + + return result; + } /* ftdi_open */ +@@ -1589,11 +1599,11 @@ static void ftdi_close(struct tty_struct + mutex_unlock(&port->serial->disc_mutex); + + /* cancel any scheduled reading */ +- cancel_delayed_work(&priv->rx_work); +- flush_scheduled_work(); ++ cancel_delayed_work_sync(&priv->rx_work); + + /* shutdown our bulk read */ + usb_kill_urb(port->read_urb); ++ kref_put(&priv->kref, ftdi_sio_priv_release); + } /* ftdi_close */ + +