diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-05-30 08:59:26 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-05-30 08:59:26 +0800 |
commit | 88969150d82fd7a1c8bb39aca99a106ed57655f5 (patch) | |
tree | f82cc3d75e78eb418b72a287bb347ab36482e09c | |
parent | 8b93abfaba1141446f8749a52d2a2b4c2eaa4ffb (diff) | |
download | stable-queue-88969150d82fd7a1c8bb39aca99a106ed57655f5.tar.gz |
.38 patches
6 files changed, 309 insertions, 0 deletions
diff --git a/queue-2.6.38/ext3-fix-fs-corruption-when-make_indexed_dir-fails.patch b/queue-2.6.38/ext3-fix-fs-corruption-when-make_indexed_dir-fails.patch new file mode 100644 index 0000000000..b143db1698 --- /dev/null +++ b/queue-2.6.38/ext3-fix-fs-corruption-when-make_indexed_dir-fails.patch @@ -0,0 +1,47 @@ +From 86c4f6d85595cd7da635dc6985d27bfa43b1ae10 Mon Sep 17 00:00:00 2001 +From: Jan Kara <jack@suse.cz> +Date: Wed, 27 Apr 2011 18:20:44 +0200 +Subject: ext3: Fix fs corruption when make_indexed_dir() fails + +From: Jan Kara <jack@suse.cz> + +commit 86c4f6d85595cd7da635dc6985d27bfa43b1ae10 upstream. + +When make_indexed_dir() fails (e.g. because of ENOSPC) after it has allocated +block for index tree root, we did not properly mark all changed buffers dirty. +This lead to only some of these buffers being written out and thus effectively +corrupting the directory. + +Fix the issue by marking all changed data dirty even in the error failure case. + +Signed-off-by: Jan Kara <jack@suse.cz> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + fs/ext3/namei.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/fs/ext3/namei.c ++++ b/fs/ext3/namei.c +@@ -1416,10 +1416,19 @@ static int make_indexed_dir(handle_t *ha + frame->at = entries; + frame->bh = bh; + bh = bh2; ++ /* ++ * Mark buffers dirty here so that if do_split() fails we write a ++ * consistent set of buffers to disk. ++ */ ++ ext3_journal_dirty_metadata(handle, frame->bh); ++ ext3_journal_dirty_metadata(handle, bh); + de = do_split(handle,dir, &bh, frame, &hinfo, &retval); +- dx_release (frames); +- if (!(de)) ++ if (!de) { ++ ext3_mark_inode_dirty(handle, dir); ++ dx_release(frames); + return retval; ++ } ++ dx_release(frames); + + return add_dirent_to_buf(handle, dentry, inode, de, bh); + } diff --git a/queue-2.6.38/ext4-release-page-cache-in-ext4_mb_load_buddy-error-path.patch b/queue-2.6.38/ext4-release-page-cache-in-ext4_mb_load_buddy-error-path.patch new file mode 100644 index 0000000000..cb8bfeb56e --- /dev/null +++ b/queue-2.6.38/ext4-release-page-cache-in-ext4_mb_load_buddy-error-path.patch @@ -0,0 +1,30 @@ +From 26626f1172fb4f3f323239a6a5cf4e082643fa46 Mon Sep 17 00:00:00 2001 +From: Yang Ruirui <ruirui.r.yang@tieto.com> +Date: Sat, 16 Apr 2011 19:17:48 -0400 +Subject: ext4: release page cache in ext4_mb_load_buddy error path + +From: Yang Ruirui <ruirui.r.yang@tieto.com> + +commit 26626f1172fb4f3f323239a6a5cf4e082643fa46 upstream. + +Add missing page_cache_release in the error path of ext4_mb_load_buddy + +Signed-off-by: Yang Ruirui <ruirui.r.yang@tieto.com> +Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + fs/ext4/mballoc.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -1268,6 +1268,8 @@ repeat_load_buddy: + return 0; + + err: ++ if (page) ++ page_cache_release(page); + if (e4b->bd_bitmap_page) + page_cache_release(e4b->bd_bitmap_page); + if (e4b->bd_buddy_page) diff --git a/queue-2.6.38/jbd-fix-forever-sleeping-process-in-do_get_write_access.patch b/queue-2.6.38/jbd-fix-forever-sleeping-process-in-do_get_write_access.patch new file mode 100644 index 0000000000..080cb35fc8 --- /dev/null +++ b/queue-2.6.38/jbd-fix-forever-sleeping-process-in-do_get_write_access.patch @@ -0,0 +1,43 @@ +From 2842bb20eed2e25cde5114298edc62c8883a1d9a Mon Sep 17 00:00:00 2001 +From: Jan Kara <jack@suse.cz> +Date: Thu, 5 May 2011 13:59:35 +0200 +Subject: jbd: Fix forever sleeping process in do_get_write_access() + +From: Jan Kara <jack@suse.cz> + +commit 2842bb20eed2e25cde5114298edc62c8883a1d9a upstream. + +In do_get_write_access() we wait on BH_Unshadow bit for buffer to get +from shadow state. The waking code in journal_commit_transaction() has +a bug because it does not issue a memory barrier after the buffer is moved +from the shadow state and before wake_up_bit() is called. Thus a waitqueue +check can happen before the buffer is actually moved from the shadow state +and waiting process may never be woken. Fix the problem by issuing proper +barrier. + +Reported-by: Tao Ma <boyu.mt@taobao.com> +Signed-off-by: Jan Kara <jack@suse.cz> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + fs/jbd/commit.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/fs/jbd/commit.c ++++ b/fs/jbd/commit.c +@@ -722,8 +722,13 @@ wait_for_iobuf: + required. */ + JBUFFER_TRACE(jh, "file as BJ_Forget"); + journal_file_buffer(jh, commit_transaction, BJ_Forget); +- /* Wake up any transactions which were waiting for this +- IO to complete */ ++ /* ++ * Wake up any transactions which were waiting for this ++ * IO to complete. The barrier must be here so that changes ++ * by journal_file_buffer() take effect before wake_up_bit() ++ * does the waitqueue check. ++ */ ++ smp_mb(); + wake_up_bit(&bh->b_state, BH_Unshadow); + JBUFFER_TRACE(jh, "brelse shadowed buffer"); + __brelse(bh); diff --git a/queue-2.6.38/jbd-fix-fsync-tid-wraparound-bug.patch b/queue-2.6.38/jbd-fix-fsync-tid-wraparound-bug.patch new file mode 100644 index 0000000000..619c26f523 --- /dev/null +++ b/queue-2.6.38/jbd-fix-fsync-tid-wraparound-bug.patch @@ -0,0 +1,68 @@ +From d9b01934d56a96d9f4ae2d6204d4ea78a36f5f36 Mon Sep 17 00:00:00 2001 +From: Ted Ts'o <tytso@mit.edu> +Date: Sat, 30 Apr 2011 13:17:11 -0400 +Subject: jbd: fix fsync() tid wraparound bug + +From: Ted Ts'o <tytso@mit.edu> + +commit d9b01934d56a96d9f4ae2d6204d4ea78a36f5f36 upstream. + +If an application program does not make any changes to the indirect +blocks or extent tree, i_datasync_tid will not get updated. If there +are enough commits (i.e., 2**31) such that tid_geq()'s calculations +wrap, and there isn't a currently active transaction at the time of +the fdatasync() call, this can end up triggering a BUG_ON in +fs/jbd/commit.c: + + J_ASSERT(journal->j_running_transaction != NULL); + +It's pretty rare that this can happen, since it requires the use of +fdatasync() plus *very* frequent and excessive use of fsync(). But +with the right workload, it can. + +We fix this by replacing the use of tid_geq() with an equality test, +since there's only one valid transaction id that is valid for us to +start: namely, the currently running transaction (if it exists). + +Reported-by: Martin_Zielinski@McAfee.com +Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> +Signed-off-by: Jan Kara <jack@suse.cz> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + fs/jbd/journal.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +--- a/fs/jbd/journal.c ++++ b/fs/jbd/journal.c +@@ -437,9 +437,12 @@ int __log_space_left(journal_t *journal) + int __log_start_commit(journal_t *journal, tid_t target) + { + /* +- * Are we already doing a recent enough commit? ++ * The only transaction we can possibly wait upon is the ++ * currently running transaction (if it exists). Otherwise, ++ * the target tid must be an old one. + */ +- if (!tid_geq(journal->j_commit_request, target)) { ++ if (journal->j_running_transaction && ++ journal->j_running_transaction->t_tid == target) { + /* + * We want a new commit: OK, mark the request and wakeup the + * commit thread. We do _not_ do the commit ourselves. +@@ -451,7 +454,14 @@ int __log_start_commit(journal_t *journa + journal->j_commit_sequence); + wake_up(&journal->j_wait_commit); + return 1; +- } ++ } else if (!tid_geq(journal->j_commit_request, target)) ++ /* This should never happen, but if it does, preserve ++ the evidence before kjournald goes into a loop and ++ increments j_commit_sequence beyond all recognition. */ ++ WARN_ONCE(1, "jbd: bad log_start_commit: %u %u %u %u\n", ++ journal->j_commit_request, journal->j_commit_sequence, ++ target, journal->j_running_transaction ? ++ journal->j_running_transaction->t_tid : 0); + return 0; + } + diff --git a/queue-2.6.38/pata_cm64x-fix-boot-crash-on-parisc.patch b/queue-2.6.38/pata_cm64x-fix-boot-crash-on-parisc.patch new file mode 100644 index 0000000000..b000daf0ea --- /dev/null +++ b/queue-2.6.38/pata_cm64x-fix-boot-crash-on-parisc.patch @@ -0,0 +1,116 @@ +From 9281b16caac1276817b77033c5b8a1f5ca30102c Mon Sep 17 00:00:00 2001 +From: James Bottomley <James.Bottomley@suse.de> +Date: Sun, 24 Apr 2011 14:30:14 -0500 +Subject: pata_cm64x: fix boot crash on parisc + +From: James Bottomley <James.Bottomley@suse.de> + +commit 9281b16caac1276817b77033c5b8a1f5ca30102c upstream. + +The old IDE cmd64x checks the status of the CNTRL register to see if +the ports are enabled before probing them. pata_cmd64x doesn't do +this, which causes a HPMC on parisc when it tries to poke at the +secondary port because apparently the BAR isn't wired up (and a +non-responding piece of memory causes a HPMC). + +Fix this by porting the CNTRL register port detection logic from IDE +cmd64x. In addition, following converns from Alan Cox, add a check to +see if a mobility electronics bridge is the immediate parent and forgo +the check if it is (prevents problems on hotplug controllers). + +Signed-off-by: James Bottomley <James.Bottomley@suse.de> +Signed-off-by: Jeff Garzik <jgarzik@pobox.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/ata/pata_cmd64x.c | 42 ++++++++++++++++++++++++++++++++++++++---- + include/linux/pci_ids.h | 2 ++ + 2 files changed, 40 insertions(+), 4 deletions(-) + +--- a/drivers/ata/pata_cmd64x.c ++++ b/drivers/ata/pata_cmd64x.c +@@ -41,6 +41,9 @@ + enum { + CFR = 0x50, + CFR_INTR_CH0 = 0x04, ++ CNTRL = 0x51, ++ CNTRL_CH0 = 0x04, ++ CNTRL_CH1 = 0x08, + CMDTIM = 0x52, + ARTTIM0 = 0x53, + DRWTIM0 = 0x54, +@@ -328,9 +331,19 @@ static int cmd64x_init_one(struct pci_de + .port_ops = &cmd648_port_ops + } + }; +- const struct ata_port_info *ppi[] = { &cmd_info[id->driver_data], NULL }; +- u8 mrdmode; ++ const struct ata_port_info *ppi[] = { ++ &cmd_info[id->driver_data], ++ &cmd_info[id->driver_data], ++ NULL ++ }; ++ u8 mrdmode, reg; + int rc; ++ struct pci_dev *bridge = pdev->bus->self; ++ /* mobility split bridges don't report enabled ports correctly */ ++ int port_ok = !(bridge && bridge->vendor == ++ PCI_VENDOR_ID_MOBILITY_ELECTRONICS); ++ /* all (with exceptions below) apart from 643 have CNTRL_CH0 bit */ ++ int cntrl_ch0_ok = (id->driver_data != 0); + + rc = pcim_enable_device(pdev); + if (rc) +@@ -341,11 +354,18 @@ static int cmd64x_init_one(struct pci_de + + if (pdev->device == PCI_DEVICE_ID_CMD_646) { + /* Does UDMA work ? */ +- if (pdev->revision > 4) ++ if (pdev->revision > 4) { + ppi[0] = &cmd_info[2]; ++ ppi[1] = &cmd_info[2]; ++ } + /* Early rev with other problems ? */ +- else if (pdev->revision == 1) ++ else if (pdev->revision == 1) { + ppi[0] = &cmd_info[3]; ++ ppi[1] = &cmd_info[3]; ++ } ++ /* revs 1,2 have no CNTRL_CH0 */ ++ if (pdev->revision < 3) ++ cntrl_ch0_ok = 0; + } + + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); +@@ -354,6 +374,20 @@ static int cmd64x_init_one(struct pci_de + mrdmode |= 0x02; /* Memory read line enable */ + pci_write_config_byte(pdev, MRDMODE, mrdmode); + ++ /* check for enabled ports */ ++ pci_read_config_byte(pdev, CNTRL, ®); ++ if (!port_ok) ++ dev_printk(KERN_NOTICE, &pdev->dev, "Mobility Bridge detected, ignoring CNTRL port enable/disable\n"); ++ if (port_ok && cntrl_ch0_ok && !(reg & CNTRL_CH0)) { ++ dev_printk(KERN_NOTICE, &pdev->dev, "Primary port is disabled\n"); ++ ppi[0] = &ata_dummy_port_info; ++ ++ } ++ if (port_ok && !(reg & CNTRL_CH1)) { ++ dev_printk(KERN_NOTICE, &pdev->dev, "Secondary port is disabled\n"); ++ ppi[1] = &ata_dummy_port_info; ++ } ++ + /* Force PIO 0 here.. */ + + /* PPC specific fixup copied from old driver */ +--- a/include/linux/pci_ids.h ++++ b/include/linux/pci_ids.h +@@ -607,6 +607,8 @@ + #define PCI_DEVICE_ID_MATROX_G550 0x2527 + #define PCI_DEVICE_ID_MATROX_VIA 0x4536 + ++#define PCI_VENDOR_ID_MOBILITY_ELECTRONICS 0x14f2 ++ + #define PCI_VENDOR_ID_CT 0x102c + #define PCI_DEVICE_ID_CT_69000 0x00c0 + #define PCI_DEVICE_ID_CT_65545 0x00d8 diff --git a/queue-2.6.38/series b/queue-2.6.38/series index 5f2a3b7679..31ae6c70a8 100644 --- a/queue-2.6.38/series +++ b/queue-2.6.38/series @@ -39,3 +39,8 @@ wire-up-clock_adjtime-syscall.patch wire-up-the-fhandle-syscalls.patch wire-up-syncfs-syscall.patch drm-send-pending-vblank-events-before-disabling-vblank.patch +pata_cm64x-fix-boot-crash-on-parisc.patch +ext3-fix-fs-corruption-when-make_indexed_dir-fails.patch +jbd-fix-forever-sleeping-process-in-do_get_write_access.patch +jbd-fix-fsync-tid-wraparound-bug.patch +ext4-release-page-cache-in-ext4_mb_load_buddy-error-path.patch |