]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.0-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 11 Sep 2012 16:47:34 +0000 (09:47 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 11 Sep 2012 16:47:34 +0000 (09:47 -0700)
added patches:
ext3-fix-fdatasync-for-files-with-only-i_size-changes.patch
fuse-fix-retrieve-length.patch
scsi-fix-device-not-ready-issue-on-mpt2sas.patch
scsi-megaraid_sas-move-poll_aen_lock-initializer.patch
scsi-mpt2sas-fix-for-driver-oops-when-loading-driver-with-max_queue_depth-command-line-option-to-a-very-small-value.patch
udf-fix-data-corruption-for-files-in-icb.patch

queue-3.0/ext3-fix-fdatasync-for-files-with-only-i_size-changes.patch [new file with mode: 0644]
queue-3.0/fuse-fix-retrieve-length.patch [new file with mode: 0644]
queue-3.0/scsi-fix-device-not-ready-issue-on-mpt2sas.patch [new file with mode: 0644]
queue-3.0/scsi-megaraid_sas-move-poll_aen_lock-initializer.patch [new file with mode: 0644]
queue-3.0/scsi-mpt2sas-fix-for-driver-oops-when-loading-driver-with-max_queue_depth-command-line-option-to-a-very-small-value.patch [new file with mode: 0644]
queue-3.0/series
queue-3.0/udf-fix-data-corruption-for-files-in-icb.patch [new file with mode: 0644]

diff --git a/queue-3.0/ext3-fix-fdatasync-for-files-with-only-i_size-changes.patch b/queue-3.0/ext3-fix-fdatasync-for-files-with-only-i_size-changes.patch
new file mode 100644 (file)
index 0000000..2cb84cf
--- /dev/null
@@ -0,0 +1,72 @@
+From 156bddd8e505b295540f3ca0e27dda68cb0d49aa Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Mon, 3 Sep 2012 16:50:42 +0200
+Subject: ext3: Fix fdatasync() for files with only i_size changes
+
+From: Jan Kara <jack@suse.cz>
+
+commit 156bddd8e505b295540f3ca0e27dda68cb0d49aa upstream.
+
+Code tracking when transaction needs to be committed on fdatasync(2) forgets
+to handle a situation when only inode's i_size is changed. Thus in such
+situations fdatasync(2) doesn't force transaction with new i_size to disk
+and that can result in wrong i_size after a crash.
+
+Fix the issue by updating inode's i_datasync_tid whenever its size is
+updated.
+
+Reported-by: Kristian Nielsen <knielsen@knielsen-hq.org>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext3/inode.c |   17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+--- a/fs/ext3/inode.c
++++ b/fs/ext3/inode.c
+@@ -3013,6 +3013,8 @@ static int ext3_do_update_inode(handle_t
+       struct ext3_inode_info *ei = EXT3_I(inode);
+       struct buffer_head *bh = iloc->bh;
+       int err = 0, rc, block;
++      int need_datasync = 0;
++      __le32 disksize;
+ again:
+       /* we can't allow multiple procs in here at once, its a bit racey */
+@@ -3050,7 +3052,11 @@ again:
+               raw_inode->i_gid_high = 0;
+       }
+       raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
+-      raw_inode->i_size = cpu_to_le32(ei->i_disksize);
++      disksize = cpu_to_le32(ei->i_disksize);
++      if (disksize != raw_inode->i_size) {
++              need_datasync = 1;
++              raw_inode->i_size = disksize;
++      }
+       raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
+       raw_inode->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec);
+       raw_inode->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec);
+@@ -3066,8 +3072,11 @@ again:
+       if (!S_ISREG(inode->i_mode)) {
+               raw_inode->i_dir_acl = cpu_to_le32(ei->i_dir_acl);
+       } else {
+-              raw_inode->i_size_high =
+-                      cpu_to_le32(ei->i_disksize >> 32);
++              disksize = cpu_to_le32(ei->i_disksize >> 32);
++              if (disksize != raw_inode->i_size_high) {
++                      raw_inode->i_size_high = disksize;
++                      need_datasync = 1;
++              }
+               if (ei->i_disksize > 0x7fffffffULL) {
+                       struct super_block *sb = inode->i_sb;
+                       if (!EXT3_HAS_RO_COMPAT_FEATURE(sb,
+@@ -3120,6 +3129,8 @@ again:
+       ext3_clear_inode_state(inode, EXT3_STATE_NEW);
+       atomic_set(&ei->i_sync_tid, handle->h_transaction->t_tid);
++      if (need_datasync)
++              atomic_set(&ei->i_datasync_tid, handle->h_transaction->t_tid);
+ out_brelse:
+       brelse (bh);
+       ext3_std_error(inode->i_sb, err);
diff --git a/queue-3.0/fuse-fix-retrieve-length.patch b/queue-3.0/fuse-fix-retrieve-length.patch
new file mode 100644 (file)
index 0000000..9f42ff4
--- /dev/null
@@ -0,0 +1,29 @@
+From c9e67d483776d8d2a5f3f70491161b205930ffe1 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@suse.cz>
+Date: Tue, 4 Sep 2012 18:45:54 +0200
+Subject: fuse: fix retrieve length
+
+From: Miklos Szeredi <mszeredi@suse.cz>
+
+commit c9e67d483776d8d2a5f3f70491161b205930ffe1 upstream.
+
+In some cases fuse_retrieve() would return a short byte count if offset was
+non-zero.  The data returned was correct, though.
+
+Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/dev.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -1524,6 +1524,7 @@ static int fuse_retrieve(struct fuse_con
+               req->pages[req->num_pages] = page;
+               req->num_pages++;
++              offset = 0;
+               num -= this_num;
+               total_len += this_num;
+               index++;
diff --git a/queue-3.0/scsi-fix-device-not-ready-issue-on-mpt2sas.patch b/queue-3.0/scsi-fix-device-not-ready-issue-on-mpt2sas.patch
new file mode 100644 (file)
index 0000000..d357a4d
--- /dev/null
@@ -0,0 +1,108 @@
+From 14216561e164671ce147458653b1fea06a4ada1e Mon Sep 17 00:00:00 2001
+From: James Bottomley <JBottomley@Parallels.com>
+Date: Wed, 25 Jul 2012 23:55:55 +0400
+Subject: SCSI: Fix 'Device not ready' issue on mpt2sas
+
+From: James Bottomley <JBottomley@Parallels.com>
+
+commit 14216561e164671ce147458653b1fea06a4ada1e upstream.
+
+This is a particularly nasty SCSI ATA Translation Layer (SATL) problem.
+
+SAT-2 says (section 8.12.2)
+
+        if the device is in the stopped state as the result of
+        processing a START STOP UNIT command (see 9.11), then the SATL
+        shall terminate the TEST UNIT READY command with CHECK CONDITION
+        status with the sense key set to NOT READY and the additional
+        sense code of LOGICAL UNIT NOT READY, INITIALIZING COMMAND
+        REQUIRED;
+
+mpt2sas internal SATL seems to implement this.  The result is very confusing
+standby behaviour (using hdparm -y).  If you suspend a drive and then send
+another command, usually it wakes up.  However, if the next command is a TEST
+UNIT READY, the SATL sees that the drive is suspended and proceeds to follow
+the SATL rules for this, returning NOT READY to all subsequent commands.  This
+means that the ordering of TEST UNIT READY is crucial: if you send TUR and
+then a command, you get a NOT READY to both back.  If you send a command and
+then a TUR, you get GOOD status because the preceeding command woke the drive.
+
+This bit us badly because
+
+commit 85ef06d1d252f6a2e73b678591ab71caad4667bb
+Author: Tejun Heo <tj@kernel.org>
+Date:   Fri Jul 1 16:17:47 2011 +0200
+
+    block: flush MEDIA_CHANGE from drivers on close(2)
+
+Changed our ordering on TEST UNIT READY commands meaning that SATA drives
+connected to an mpt2sas now suspend and refuse to wake (because the mpt2sas
+SATL sees the suspend *before* the drives get awoken by the next ATA command)
+resulting in lots of failed commands.
+
+The standard is completely nuts forcing this inconsistent behaviour, but we
+have to work around it.
+
+The fix for this is twofold:
+
+   1. Set the allow_restart flag so we wake the drive when we see it has been
+      suspended
+
+   2. Return all TEST UNIT READY status directly to the mid layer without any
+      further error handling which prevents us causing error handling which
+      may offline the device just because of a media check TUR.
+
+Reported-by: Matthias Prager <linux@matthiasprager.de>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/scsi_error.c |   10 ++++++++++
+ drivers/scsi/scsi_scan.c  |   10 ++++++++++
+ 2 files changed, 20 insertions(+)
+
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -41,6 +41,8 @@
+ #include <trace/events/scsi.h>
++static void scsi_eh_done(struct scsi_cmnd *scmd);
++
+ #define SENSE_TIMEOUT         (10*HZ)
+ /*
+@@ -240,6 +242,14 @@ static int scsi_check_sense(struct scsi_
+       if (! scsi_command_normalize_sense(scmd, &sshdr))
+               return FAILED;  /* no valid sense data */
++      if (scmd->cmnd[0] == TEST_UNIT_READY && scmd->scsi_done != scsi_eh_done)
++              /*
++               * nasty: for mid-layer issued TURs, we need to return the
++               * actual sense data without any recovery attempt.  For eh
++               * issued ones, we need to try to recover and interpret
++               */
++              return SUCCESS;
++
+       if (scsi_sense_is_deferred(&sshdr))
+               return NEEDS_RETRY;
+--- a/drivers/scsi/scsi_scan.c
++++ b/drivers/scsi/scsi_scan.c
+@@ -776,6 +776,16 @@ static int scsi_add_lun(struct scsi_devi
+       sdev->model = (char *) (sdev->inquiry + 16);
+       sdev->rev = (char *) (sdev->inquiry + 32);
++      if (strncmp(sdev->vendor, "ATA     ", 8) == 0) {
++              /*
++               * sata emulation layer device.  This is a hack to work around
++               * the SATL power management specifications which state that
++               * when the SATL detects the device has gone into standby
++               * mode, it shall respond with NOT READY.
++               */
++              sdev->allow_restart = 1;
++      }
++
+       if (*bflags & BLIST_ISROM) {
+               sdev->type = TYPE_ROM;
+               sdev->removable = 1;
diff --git a/queue-3.0/scsi-megaraid_sas-move-poll_aen_lock-initializer.patch b/queue-3.0/scsi-megaraid_sas-move-poll_aen_lock-initializer.patch
new file mode 100644 (file)
index 0000000..f7b0a1c
--- /dev/null
@@ -0,0 +1,42 @@
+From bd8d6dd43a77bfd2b8fef5b094b9d6095e169dee Mon Sep 17 00:00:00 2001
+From: Kashyap Desai <Kashyap.Desai@lsi.com>
+Date: Tue, 17 Jul 2012 18:20:44 -0700
+Subject: SCSI: megaraid_sas: Move poll_aen_lock initializer
+
+From: Kashyap Desai <Kashyap.Desai@lsi.com>
+
+commit bd8d6dd43a77bfd2b8fef5b094b9d6095e169dee upstream.
+
+The following patch moves the poll_aen_lock initializer from
+megasas_probe_one() to megasas_init().  This prevents a crash when a user
+loads the driver and tries to issue a poll() system call on the ioctl
+interface with no adapters present.
+
+Signed-off-by: Kashyap Desai <Kashyap.Desai@lsi.com>
+Signed-off-by: Adam Radford <aradford@gmail.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/megaraid/megaraid_sas_base.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/scsi/megaraid/megaraid_sas_base.c
++++ b/drivers/scsi/megaraid/megaraid_sas_base.c
+@@ -4052,7 +4052,6 @@ megasas_probe_one(struct pci_dev *pdev,
+       spin_lock_init(&instance->cmd_pool_lock);
+       spin_lock_init(&instance->hba_lock);
+       spin_lock_init(&instance->completion_lock);
+-      spin_lock_init(&poll_aen_lock);
+       mutex_init(&instance->aen_mutex);
+       mutex_init(&instance->reset_mutex);
+@@ -5380,6 +5379,8 @@ static int __init megasas_init(void)
+       printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION,
+              MEGASAS_EXT_VERSION);
++      spin_lock_init(&poll_aen_lock);
++
+       support_poll_for_event = 2;
+       support_device_change = 1;
diff --git a/queue-3.0/scsi-mpt2sas-fix-for-driver-oops-when-loading-driver-with-max_queue_depth-command-line-option-to-a-very-small-value.patch b/queue-3.0/scsi-mpt2sas-fix-for-driver-oops-when-loading-driver-with-max_queue_depth-command-line-option-to-a-very-small-value.patch
new file mode 100644 (file)
index 0000000..2993e55
--- /dev/null
@@ -0,0 +1,60 @@
+From 338b131a3269881c7431234855c93c219b0979b6 Mon Sep 17 00:00:00 2001
+From: "sreekanth.reddy@lsi.com" <sreekanth.reddy@lsi.com>
+Date: Tue, 17 Jul 2012 15:57:05 +0530
+Subject: SCSI: mpt2sas: Fix for Driver oops, when loading driver with max_queue_depth command line option to a very small value
+
+From: "sreekanth.reddy@lsi.com" <sreekanth.reddy@lsi.com>
+
+commit 338b131a3269881c7431234855c93c219b0979b6 upstream.
+
+If the specified max_queue_depth setting is less than the
+expected number of internal commands, then driver will calculate
+the queue depth size to a negitive number. This negitive number
+is actually a very large number because variable is unsigned
+16bit integer. So, the driver will ask for a very large amount of
+memory for message frames and resulting into oops as memory
+allocation routines will not able to handle such a large request.
+
+So, in order to limit this kind of oops, The driver need to set
+the max_queue_depth to a scsi mid layer's can_queue value. Then
+the overall message frames required for IO is minimum of either
+(max_queue_depth plus internal commands) or the IOC global
+credits.
+
+Signed-off-by: Sreekanth Reddy <sreekanth.reddy@lsi.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/mpt2sas/mpt2sas_base.c |   13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
++++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
+@@ -2140,10 +2140,13 @@ _base_allocate_memory_pools(struct MPT2S
+       }
+       /* command line tunables  for max controller queue depth */
+-      if (max_queue_depth != -1)
+-              max_request_credit = (max_queue_depth < facts->RequestCredit)
+-                  ? max_queue_depth : facts->RequestCredit;
+-      else
++      if (max_queue_depth != -1 && max_queue_depth != 0) {
++              max_request_credit = min_t(u16, max_queue_depth +
++                      ioc->hi_priority_depth + ioc->internal_depth,
++                      facts->RequestCredit);
++              if (max_request_credit > MAX_HBA_QUEUE_DEPTH)
++                      max_request_credit =  MAX_HBA_QUEUE_DEPTH;
++      } else
+               max_request_credit = min_t(u16, facts->RequestCredit,
+                   MAX_HBA_QUEUE_DEPTH);
+@@ -2218,7 +2221,7 @@ _base_allocate_memory_pools(struct MPT2S
+       /* set the scsi host can_queue depth
+        * with some internal commands that could be outstanding
+        */
+-      ioc->shost->can_queue = ioc->scsiio_depth - (2);
++      ioc->shost->can_queue = ioc->scsiio_depth;
+       dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsi host: "
+           "can_queue depth (%d)\n", ioc->name, ioc->shost->can_queue));
index 9ea42081a415b28a9a36850dfad581b88992e4d9..7d9fa1c2fa38c89db9e7aea0a60ae77b461ae390 100644 (file)
@@ -33,3 +33,9 @@ usb-cdc-acm-fix-null-pointer-dereference.patch
 powerpc-fix-dscr-inheritance-in-copy_thread.patch
 powerpc-restore-correct-dscr-in-context-switch.patch
 remove-user-triggerable-bug-from-mpol_to_str.patch
+scsi-megaraid_sas-move-poll_aen_lock-initializer.patch
+scsi-mpt2sas-fix-for-driver-oops-when-loading-driver-with-max_queue_depth-command-line-option-to-a-very-small-value.patch
+scsi-fix-device-not-ready-issue-on-mpt2sas.patch
+udf-fix-data-corruption-for-files-in-icb.patch
+ext3-fix-fdatasync-for-files-with-only-i_size-changes.patch
+fuse-fix-retrieve-length.patch
diff --git a/queue-3.0/udf-fix-data-corruption-for-files-in-icb.patch b/queue-3.0/udf-fix-data-corruption-for-files-in-icb.patch
new file mode 100644 (file)
index 0000000..4edb072
--- /dev/null
@@ -0,0 +1,95 @@
+From 9c2fc0de1a6e638fe58c354a463f544f42a90a09 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Wed, 5 Sep 2012 15:48:23 +0200
+Subject: udf: Fix data corruption for files in ICB
+
+From: Jan Kara <jack@suse.cz>
+
+commit 9c2fc0de1a6e638fe58c354a463f544f42a90a09 upstream.
+
+When a file is stored in ICB (inode), we overwrite part of the file, and
+the page containing file's data is not in page cache, we end up corrupting
+file's data by overwriting them with zeros. The problem is we use
+simple_write_begin() which simply zeroes parts of the page which are not
+written to. The problem has been introduced by be021ee4 (udf: convert to
+new aops).
+
+Fix the problem by providing a ->write_begin function which makes the page
+properly uptodate.
+
+Reported-by: Ian Abbott <abbotti@mev.co.uk>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/udf/file.c |   35 +++++++++++++++++++++++++++++------
+ 1 file changed, 29 insertions(+), 6 deletions(-)
+
+--- a/fs/udf/file.c
++++ b/fs/udf/file.c
+@@ -39,20 +39,24 @@
+ #include "udf_i.h"
+ #include "udf_sb.h"
+-static int udf_adinicb_readpage(struct file *file, struct page *page)
++static void __udf_adinicb_readpage(struct page *page)
+ {
+       struct inode *inode = page->mapping->host;
+       char *kaddr;
+       struct udf_inode_info *iinfo = UDF_I(inode);
+-      BUG_ON(!PageLocked(page));
+-
+       kaddr = kmap(page);
+-      memset(kaddr, 0, PAGE_CACHE_SIZE);
+       memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, inode->i_size);
++      memset(kaddr + inode->i_size, 0, PAGE_CACHE_SIZE - inode->i_size);
+       flush_dcache_page(page);
+       SetPageUptodate(page);
+       kunmap(page);
++}
++
++static int udf_adinicb_readpage(struct file *file, struct page *page)
++{
++      BUG_ON(!PageLocked(page));
++      __udf_adinicb_readpage(page);
+       unlock_page(page);
+       return 0;
+@@ -77,6 +81,25 @@ static int udf_adinicb_writepage(struct
+       return 0;
+ }
++static int udf_adinicb_write_begin(struct file *file,
++                      struct address_space *mapping, loff_t pos,
++                      unsigned len, unsigned flags, struct page **pagep,
++                      void **fsdata)
++{
++      struct page *page;
++
++      if (WARN_ON_ONCE(pos >= PAGE_CACHE_SIZE))
++              return -EIO;
++      page = grab_cache_page_write_begin(mapping, 0, flags);
++      if (!page)
++              return -ENOMEM;
++      *pagep = page;
++
++      if (!PageUptodate(page) && len != PAGE_CACHE_SIZE)
++              __udf_adinicb_readpage(page);
++      return 0;
++}
++
+ static int udf_adinicb_write_end(struct file *file,
+                       struct address_space *mapping,
+                       loff_t pos, unsigned len, unsigned copied,
+@@ -98,8 +121,8 @@ static int udf_adinicb_write_end(struct
+ const struct address_space_operations udf_adinicb_aops = {
+       .readpage       = udf_adinicb_readpage,
+       .writepage      = udf_adinicb_writepage,
+-      .write_begin = simple_write_begin,
+-      .write_end = udf_adinicb_write_end,
++      .write_begin    = udf_adinicb_write_begin,
++      .write_end      = udf_adinicb_write_end,
+ };
+ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,