]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
start .27 branch
authorGreg Kroah-Hartman <gregkh@suse.de>
Tue, 12 May 2009 20:40:16 +0000 (13:40 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 12 May 2009 20:40:16 +0000 (13:40 -0700)
queue-2.6.27/md-fix-loading-of-out-of-date-bitmap.patch [new file with mode: 0644]
queue-2.6.27/md-fix-some-errors-with-bitmaps-on-devices-larger-than-2tb.patch [new file with mode: 0644]
queue-2.6.27/md-raid10-don-t-clear-bitmap-during-recovery-if-array-will-still-be-degraded.patch [new file with mode: 0644]
queue-2.6.27/md-remove-ability-to-explicit-set-an-inactive-array-to-clean.patch [new file with mode: 0644]
queue-2.6.27/series [new file with mode: 0644]
queue-2.6.27/usb-gadget-fix-utf-conversion-in-the-usbstring-library.patch [new file with mode: 0644]

diff --git a/queue-2.6.27/md-fix-loading-of-out-of-date-bitmap.patch b/queue-2.6.27/md-fix-loading-of-out-of-date-bitmap.patch
new file mode 100644 (file)
index 0000000..6c571d6
--- /dev/null
@@ -0,0 +1,59 @@
+From b74fd2826c5acce20e6f691437b2d19372bc2057 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Thu, 7 May 2009 12:47:19 +1000
+Subject: md: fix loading of out-of-date bitmap.
+
+From: NeilBrown <neilb@suse.de>
+
+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 <vojtech@suse.cz>
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/md/bitmap.c |   11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+--- a/drivers/md/bitmap.c
++++ b/drivers/md/bitmap.c
+@@ -986,6 +986,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
+@@ -998,15 +1001,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.27/md-fix-some-errors-with-bitmaps-on-devices-larger-than-2tb.patch b/queue-2.6.27/md-fix-some-errors-with-bitmaps-on-devices-larger-than-2tb.patch
new file mode 100644 (file)
index 0000000..85137e2
--- /dev/null
@@ -0,0 +1,73 @@
+From db305e507d554430a69ede901a6308e6ecb72349 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Thu, 7 May 2009 12:49:06 +1000
+Subject: md: fix some (more) errors with bitmaps on devices larger than 2TB.
+
+From: NeilBrown <neilb@suse.de>
+
+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 <neilb@suse.de>
+Reported-by: "Mario 'BitKoenig' Holbe" <Mario.Holbe@TU-Ilmenau.DE>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/md/bitmap.c |   18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+--- a/drivers/md/bitmap.c
++++ b/drivers/md/bitmap.c
+@@ -1013,9 +1013,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);
+               }
+@@ -1151,8 +1153,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);
+@@ -1166,7 +1169,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 */
+@@ -1482,7 +1486,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.27/md-raid10-don-t-clear-bitmap-during-recovery-if-array-will-still-be-degraded.patch b/queue-2.6.27/md-raid10-don-t-clear-bitmap-during-recovery-if-array-will-still-be-degraded.patch
new file mode 100644 (file)
index 0000000..d1c3236
--- /dev/null
@@ -0,0 +1,56 @@
+From 18055569127253755d01733f6ecc004ed02f88d0 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+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 <neilb@suse.de>
+
+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 <neilb@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/md/raid10.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -1805,17 +1805,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; j<conf->copies;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; j<conf->raid_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.27/md-remove-ability-to-explicit-set-an-inactive-array-to-clean.patch b/queue-2.6.27/md-remove-ability-to-explicit-set-an-inactive-array-to-clean.patch
new file mode 100644 (file)
index 0000000..d984d10
--- /dev/null
@@ -0,0 +1,57 @@
+From 5bf295975416f8e97117bbbcfb0191c00bc3e2b4 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Thu, 7 May 2009 12:50:57 +1000
+Subject: md: remove ability to explicit set an inactive array to 'clean'.
+
+From: NeilBrown <neilb@suse.de>
+
+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 <rafal.marszewski@intel.com>
+Acked-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/md/md.c |    7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -2772,11 +2772,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.27/series b/queue-2.6.27/series
new file mode 100644 (file)
index 0000000..3b529b5
--- /dev/null
@@ -0,0 +1,5 @@
+md-fix-loading-of-out-of-date-bitmap.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-remove-ability-to-explicit-set-an-inactive-array-to-clean.patch
+usb-gadget-fix-utf-conversion-in-the-usbstring-library.patch
diff --git a/queue-2.6.27/usb-gadget-fix-utf-conversion-in-the-usbstring-library.patch b/queue-2.6.27/usb-gadget-fix-utf-conversion-in-the-usbstring-library.patch
new file mode 100644 (file)
index 0000000..a0b80f4
--- /dev/null
@@ -0,0 +1,50 @@
+From 0f43158caddcbb110916212ebe4e39993ae70864 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Mon, 27 Apr 2009 13:22:40 -0400
+Subject: USB: Gadget: fix UTF conversion in the usbstring library
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+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 <stern@rowland.harvard.edu>
+Acked-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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;