]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.0 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Tue, 22 Nov 2011 21:49:07 +0000 (13:49 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 22 Nov 2011 21:49:07 +0000 (13:49 -0800)
added patches:
drm-i915-always-set-fdi-composite-sync-bit.patch
drm-i915-fix-ivb-cursor-support.patch
xfs-avoid-direct-i-o-write-vs-buffered-i-o-race.patch
xfs-dont-serialise-direct-io-reads-on-page-cache.patch
xfs-fix-buffer-flushing-during-unmount.patch
xfs-fix-error-handling-for-synchronous-writes.patch
xfs-fix-possible-memory-corruption-in-xfs_readlink.patch
xfs-fix-write_inode-return-values.patch
xfs-fix-xfs_mark_inode_dirty-during-umount.patch
xfs-return-eio-when-xfs_vn_getattr-failed.patch
xfs-use-doalloc-flag-in-xfs_qm_dqattach_one.patch

12 files changed:
queue-3.0/drm-i915-always-set-fdi-composite-sync-bit.patch [new file with mode: 0644]
queue-3.0/drm-i915-fix-ivb-cursor-support.patch [new file with mode: 0644]
queue-3.0/series
queue-3.0/xfs-avoid-direct-i-o-write-vs-buffered-i-o-race.patch [new file with mode: 0644]
queue-3.0/xfs-dont-serialise-direct-io-reads-on-page-cache.patch [new file with mode: 0644]
queue-3.0/xfs-fix-buffer-flushing-during-unmount.patch [new file with mode: 0644]
queue-3.0/xfs-fix-error-handling-for-synchronous-writes.patch [new file with mode: 0644]
queue-3.0/xfs-fix-possible-memory-corruption-in-xfs_readlink.patch [new file with mode: 0644]
queue-3.0/xfs-fix-write_inode-return-values.patch [new file with mode: 0644]
queue-3.0/xfs-fix-xfs_mark_inode_dirty-during-umount.patch [new file with mode: 0644]
queue-3.0/xfs-return-eio-when-xfs_vn_getattr-failed.patch [new file with mode: 0644]
queue-3.0/xfs-use-doalloc-flag-in-xfs_qm_dqattach_one.patch [new file with mode: 0644]

diff --git a/queue-3.0/drm-i915-always-set-fdi-composite-sync-bit.patch b/queue-3.0/drm-i915-always-set-fdi-composite-sync-bit.patch
new file mode 100644 (file)
index 0000000..7c51f07
--- /dev/null
@@ -0,0 +1,52 @@
+From c4f9c4c2b3f1831e932e04db992cf6fe92c2a95a Mon Sep 17 00:00:00 2001
+From: Jesse Barnes <jbarnes@virtuousgeek.org>
+Date: Mon, 10 Oct 2011 14:28:52 -0700
+Subject: drm/i915: always set FDI composite sync bit
+
+From: Jesse Barnes <jbarnes@virtuousgeek.org>
+
+commit c4f9c4c2b3f1831e932e04db992cf6fe92c2a95a upstream.
+
+It's needed for 3 pipe support as well as just regular functionality
+(e.g. DisplayPort).
+
+Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
+Tested-by: Adam Jackson <ajax@redhat.com>
+Tested-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
+Signed-off-by: Keith Packard <keithp@keithp.com>
+Signed-off-by: Robert Hooker <robert.hooker@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/i915/i915_reg.h      |    1 +
+ drivers/gpu/drm/i915/intel_display.c |    2 ++
+ 2 files changed, 3 insertions(+)
+
+--- a/drivers/gpu/drm/i915/i915_reg.h
++++ b/drivers/gpu/drm/i915/i915_reg.h
+@@ -3141,6 +3141,7 @@
+ #define  FDI_LINK_TRAIN_NONE_IVB            (3<<8)
+ /* both Tx and Rx */
++#define  FDI_COMPOSITE_SYNC           (1<<11)
+ #define  FDI_LINK_TRAIN_AUTO          (1<<10)
+ #define  FDI_SCRAMBLING_ENABLE          (0<<7)
+ #define  FDI_SCRAMBLING_DISABLE         (1<<7)
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -2340,6 +2340,7 @@ static void ivb_manual_fdi_link_train(st
+       temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
+       temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
+       temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
++      temp |= FDI_COMPOSITE_SYNC;
+       I915_WRITE(reg, temp | FDI_TX_ENABLE);
+       reg = FDI_RX_CTL(pipe);
+@@ -2347,6 +2348,7 @@ static void ivb_manual_fdi_link_train(st
+       temp &= ~FDI_LINK_TRAIN_AUTO;
+       temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
+       temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
++      temp |= FDI_COMPOSITE_SYNC;
+       I915_WRITE(reg, temp | FDI_RX_ENABLE);
+       POSTING_READ(reg);
diff --git a/queue-3.0/drm-i915-fix-ivb-cursor-support.patch b/queue-3.0/drm-i915-fix-ivb-cursor-support.patch
new file mode 100644 (file)
index 0000000..2cec42b
--- /dev/null
@@ -0,0 +1,101 @@
+From 65a21cd65316145f9302594be8e69074369e1050 Mon Sep 17 00:00:00 2001
+From: Jesse Barnes <jbarnes@virtuousgeek.org>
+Date: Wed, 12 Oct 2011 11:10:21 -0700
+Subject: drm/i915: fix IVB cursor support
+
+From: Jesse Barnes <jbarnes@virtuousgeek.org>
+
+commit 65a21cd65316145f9302594be8e69074369e1050 upstream.
+
+The cursor regs have moved around, add the offsets and new macros for
+getting at them.
+
+Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
+Tested-By: Eugeni Dodonov <eugeni.dodonov@intel.com>
+Reviewed-By: Eugeni Dodonov <eugeni.dodonov@intel.com>
+Signed-off-by: Keith Packard <keithp@keithp.com>
+Signed-off-by: Robert Hooker <robert.hooker@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/i915/i915_reg.h      |    8 +++++++
+ drivers/gpu/drm/i915/intel_display.c |   40 ++++++++++++++++++++++++++++++-----
+ 2 files changed, 43 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/i915/i915_reg.h
++++ b/drivers/gpu/drm/i915/i915_reg.h
+@@ -2544,10 +2544,18 @@
+ #define _CURBBASE             0x700c4
+ #define _CURBPOS                      0x700c8
++#define _CURBCNTR_IVB         0x71080
++#define _CURBBASE_IVB         0x71084
++#define _CURBPOS_IVB          0x71088
++
+ #define CURCNTR(pipe) _PIPE(pipe, _CURACNTR, _CURBCNTR)
+ #define CURBASE(pipe) _PIPE(pipe, _CURABASE, _CURBBASE)
+ #define CURPOS(pipe) _PIPE(pipe, _CURAPOS, _CURBPOS)
++#define CURCNTR_IVB(pipe) _PIPE(pipe, _CURACNTR, _CURBCNTR_IVB)
++#define CURBASE_IVB(pipe) _PIPE(pipe, _CURABASE, _CURBBASE_IVB)
++#define CURPOS_IVB(pipe) _PIPE(pipe, _CURAPOS, _CURBPOS_IVB)
++
+ /* Display A control */
+ #define _DSPACNTR                0x70180
+ #define   DISPLAY_PLANE_ENABLE                        (1<<31)
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -5334,6 +5334,31 @@ static void i9xx_update_cursor(struct dr
+       I915_WRITE(CURBASE(pipe), base);
+ }
++static void ivb_update_cursor(struct drm_crtc *crtc, u32 base)
++{
++      struct drm_device *dev = crtc->dev;
++      struct drm_i915_private *dev_priv = dev->dev_private;
++      struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
++      int pipe = intel_crtc->pipe;
++      bool visible = base != 0;
++
++      if (intel_crtc->cursor_visible != visible) {
++              uint32_t cntl = I915_READ(CURCNTR_IVB(pipe));
++              if (base) {
++                      cntl &= ~CURSOR_MODE;
++                      cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
++              } else {
++                      cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
++                      cntl |= CURSOR_MODE_DISABLE;
++              }
++              I915_WRITE(CURCNTR_IVB(pipe), cntl);
++
++              intel_crtc->cursor_visible = visible;
++      }
++      /* and commit changes on next vblank */
++      I915_WRITE(CURBASE_IVB(pipe), base);
++}
++
+ /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */
+ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
+                                    bool on)
+@@ -5381,11 +5406,16 @@ static void intel_crtc_update_cursor(str
+       if (!visible && !intel_crtc->cursor_visible)
+               return;
+-      I915_WRITE(CURPOS(pipe), pos);
+-      if (IS_845G(dev) || IS_I865G(dev))
+-              i845_update_cursor(crtc, base);
+-      else
+-              i9xx_update_cursor(crtc, base);
++      if (IS_IVYBRIDGE(dev)) {
++              I915_WRITE(CURPOS_IVB(pipe), pos);
++              ivb_update_cursor(crtc, base);
++      } else {
++              I915_WRITE(CURPOS(pipe), pos);
++              if (IS_845G(dev) || IS_I865G(dev))
++                      i845_update_cursor(crtc, base);
++              else
++                      i9xx_update_cursor(crtc, base);
++      }
+       if (visible)
+               intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj);
index f9541451804e24b5801ff0ecdb55e6a8c3d0b4ee..1d34a4b3d3ce776b0cf9a2387193fa7f081d9f71 100644 (file)
@@ -40,3 +40,14 @@ usb-storage-accept-8020i-protocol-commands-longer-than-12-bytes.patch
 usb-ehci-fix-hub-tt-scheduling-issue-with-iso-transfer.patch
 usb-add-quirk-for-logitech-c600-web-cam.patch
 usb-quirks-adding-more-quirky-webcams-to-avoid-squeaky-audio.patch
+xfs-fix-error-handling-for-synchronous-writes.patch
+xfs-fix-xfs_mark_inode_dirty-during-umount.patch
+xfs-dont-serialise-direct-io-reads-on-page-cache.patch
+xfs-avoid-direct-i-o-write-vs-buffered-i-o-race.patch
+xfs-return-eio-when-xfs_vn_getattr-failed.patch
+xfs-fix-buffer-flushing-during-unmount.patch
+xfs-fix-possible-memory-corruption-in-xfs_readlink.patch
+xfs-use-doalloc-flag-in-xfs_qm_dqattach_one.patch
+xfs-fix-write_inode-return-values.patch
+drm-i915-fix-ivb-cursor-support.patch
+drm-i915-always-set-fdi-composite-sync-bit.patch
diff --git a/queue-3.0/xfs-avoid-direct-i-o-write-vs-buffered-i-o-race.patch b/queue-3.0/xfs-avoid-direct-i-o-write-vs-buffered-i-o-race.patch
new file mode 100644 (file)
index 0000000..c17c917
--- /dev/null
@@ -0,0 +1,73 @@
+From hch@infradead.org  Tue Nov 22 13:36:45 2011
+From: Christoph Hellwig <hch@infradead.org>
+Date: Sat, 19 Nov 2011 13:13:41 -0500
+Subject: xfs: avoid direct I/O write vs buffered I/O race
+To: stable@vger.kernel.org
+Cc: xfs@oss.sgi.com, Alex Elder <aelder@sgi.com>
+Message-ID: <20111119181544.434721480@bombadil.infradead.org>
+
+From: Christoph Hellwig <hch@infradead.org>
+
+commit c58cb165bd44de8aaee9755a144136ae743be116 upstream.
+
+Currently a buffered reader or writer can add pages to the pagecache
+while we are waiting for the iolock in xfs_file_dio_aio_write.  Prevent
+this by re-checking mapping->nrpages after we got the iolock, and if
+nessecary upgrade the lock to exclusive mode.  To simplify this a bit
+only take the ilock inside of xfs_file_aio_write_checks.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Signed-off-by: Alex Elder <aelder@sgi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/xfs/linux-2.6/xfs_file.c |   17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+--- a/fs/xfs/linux-2.6/xfs_file.c
++++ b/fs/xfs/linux-2.6/xfs_file.c
+@@ -669,6 +669,7 @@ xfs_file_aio_write_checks(
+       xfs_fsize_t             new_size;
+       int                     error = 0;
++      xfs_rw_ilock(ip, XFS_ILOCK_EXCL);
+       error = generic_write_checks(file, pos, count, S_ISBLK(inode->i_mode));
+       if (error) {
+               xfs_rw_iunlock(ip, XFS_ILOCK_EXCL | *iolock);
+@@ -760,14 +761,24 @@ xfs_file_dio_aio_write(
+               *iolock = XFS_IOLOCK_EXCL;
+       else
+               *iolock = XFS_IOLOCK_SHARED;
+-      xfs_rw_ilock(ip, XFS_ILOCK_EXCL | *iolock);
++      xfs_rw_ilock(ip, *iolock);
+       ret = xfs_file_aio_write_checks(file, &pos, &count, iolock);
+       if (ret)
+               return ret;
++      /*
++       * Recheck if there are cached pages that need invalidate after we got
++       * the iolock to protect against other threads adding new pages while
++       * we were waiting for the iolock.
++       */
++      if (mapping->nrpages && *iolock == XFS_IOLOCK_SHARED) {
++              xfs_rw_iunlock(ip, *iolock);
++              *iolock = XFS_IOLOCK_EXCL;
++              xfs_rw_ilock(ip, *iolock);
++      }
++
+       if (mapping->nrpages) {
+-              WARN_ON(*iolock != XFS_IOLOCK_EXCL);
+               ret = -xfs_flushinval_pages(ip, (pos & PAGE_CACHE_MASK), -1,
+                                                       FI_REMAPF_LOCKED);
+               if (ret)
+@@ -812,7 +823,7 @@ xfs_file_buffered_aio_write(
+       size_t                  count = ocount;
+       *iolock = XFS_IOLOCK_EXCL;
+-      xfs_rw_ilock(ip, XFS_ILOCK_EXCL | *iolock);
++      xfs_rw_ilock(ip, *iolock);
+       ret = xfs_file_aio_write_checks(file, &pos, &count, iolock);
+       if (ret)
diff --git a/queue-3.0/xfs-dont-serialise-direct-io-reads-on-page-cache.patch b/queue-3.0/xfs-dont-serialise-direct-io-reads-on-page-cache.patch
new file mode 100644 (file)
index 0000000..6956c6e
--- /dev/null
@@ -0,0 +1,67 @@
+From hch@infradead.org  Tue Nov 22 13:35:52 2011
+From: Dave Chinner <dchinner@redhat.com>
+Date: Sat, 19 Nov 2011 13:13:40 -0500
+Subject: xfs: dont serialise direct IO reads on page cache
+To: stable@vger.kernel.org
+Cc: xfs@oss.sgi.com, Dave Chinner <dchinner@redhat.com>, Alex Elder <aelder@sgi.com>
+Message-ID: <20111119181544.111984285@bombadil.infradead.org>
+
+From: Dave Chinner <dchinner@redhat.com>
+
+commit 0c38a2512df272b14ef4238b476a2e4f70da1479 upstream.
+
+There is no need to grab the i_mutex of the IO lock in exclusive
+mode if we don't need to invalidate the page cache. Taking these
+locks on every direct IO effective serialises them as taking the IO
+lock in exclusive mode has to wait for all shared holders to drop
+the lock. That only happens when IO is complete, so effective it
+prevents dispatch of concurrent direct IO reads to the same inode.
+
+Fix this by taking the IO lock shared to check the page cache state,
+and only then drop it and take the IO lock exclusively if there is
+work to be done. Hence for the normal direct IO case, no exclusive
+locking will occur.
+
+Signed-off-by: Dave Chinner <dchinner@redhat.com>
+Tested-by: Joern Engel <joern@logfs.org>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Alex Elder <aelder@sgi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/xfs/linux-2.6/xfs_file.c |   17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+--- a/fs/xfs/linux-2.6/xfs_file.c
++++ b/fs/xfs/linux-2.6/xfs_file.c
+@@ -309,7 +309,19 @@ xfs_file_aio_read(
+       if (XFS_FORCED_SHUTDOWN(mp))
+               return -EIO;
+-      if (unlikely(ioflags & IO_ISDIRECT)) {
++      /*
++       * Locking is a bit tricky here. If we take an exclusive lock
++       * for direct IO, we effectively serialise all new concurrent
++       * read IO to this file and block it behind IO that is currently in
++       * progress because IO in progress holds the IO lock shared. We only
++       * need to hold the lock exclusive to blow away the page cache, so
++       * only take lock exclusively if the page cache needs invalidation.
++       * This allows the normal direct IO case of no page cache pages to
++       * proceeed concurrently without serialisation.
++       */
++      xfs_rw_ilock(ip, XFS_IOLOCK_SHARED);
++      if ((ioflags & IO_ISDIRECT) && inode->i_mapping->nrpages) {
++              xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED);
+               xfs_rw_ilock(ip, XFS_IOLOCK_EXCL);
+               if (inode->i_mapping->nrpages) {
+@@ -322,8 +334,7 @@ xfs_file_aio_read(
+                       }
+               }
+               xfs_rw_ilock_demote(ip, XFS_IOLOCK_EXCL);
+-      } else
+-              xfs_rw_ilock(ip, XFS_IOLOCK_SHARED);
++      }
+       trace_xfs_file_read(ip, size, iocb->ki_pos, ioflags);
diff --git a/queue-3.0/xfs-fix-buffer-flushing-during-unmount.patch b/queue-3.0/xfs-fix-buffer-flushing-during-unmount.patch
new file mode 100644 (file)
index 0000000..30464ea
--- /dev/null
@@ -0,0 +1,103 @@
+From hch@infradead.org  Tue Nov 22 13:38:03 2011
+From: Christoph Hellwig <hch@infradead.org>
+Date: Sat, 19 Nov 2011 13:13:43 -0500
+Subject: [PATCH 7/9] [PATCH 7/9] xfs: fix buffer flushing during unmount
+To: stable@vger.kernel.org
+Cc: xfs@oss.sgi.com, Alex Elder <aelder@sgi.com>
+Message-ID: <20111119181544.971499446@bombadil.infradead.org>
+
+From: Christoph Hellwig <hch@infradead.org>
+
+commit 87c7bec7fc3377b3873eb3a0f4b603981ea16ebb upstream.
+
+The code to flush buffers in the umount code is a bit iffy: we first
+flush all delwri buffers out, but then might be able to queue up a
+new one when logging the sb counts.  On a normal shutdown that one
+would get flushed out when doing the synchronous superblock write in
+xfs_unmountfs_writesb, but we skip that one if the filesystem has
+been shut down.
+
+Fix this by moving the delwri list flushing until just before unmounting
+the log, and while we're at it also remove the superflous delwri list
+and buffer lru flusing for the rt and log device that can never have
+cached or delwri buffers.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reported-by: Amit Sahrawat <amit.sahrawat83@gmail.com>
+Tested-by: Amit Sahrawat <amit.sahrawat83@gmail.com>
+Signed-off-by: Alex Elder <aelder@sgi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ fs/xfs/linux-2.6/xfs_buf.h |    1 -
+ fs/xfs/xfs_mount.c         |   29 ++++++++++-------------------
+ 2 files changed, 10 insertions(+), 20 deletions(-)
+
+--- a/fs/xfs/linux-2.6/xfs_buf.h
++++ b/fs/xfs/linux-2.6/xfs_buf.h
+@@ -346,7 +346,6 @@ extern struct list_head *xfs_get_buftarg
+ #define xfs_getsize_buftarg(buftarg)  block_size((buftarg)->bt_bdev)
+ #define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev)
+-#define xfs_binval(buftarg)           xfs_flush_buftarg(buftarg, 1)
+ #define XFS_bflush(buftarg)           xfs_flush_buftarg(buftarg, 1)
+ #endif        /* __XFS_BUF_H__ */
+--- a/fs/xfs/xfs_mount.c
++++ b/fs/xfs/xfs_mount.c
+@@ -44,9 +44,6 @@
+ #include "xfs_trace.h"
+-STATIC void   xfs_unmountfs_wait(xfs_mount_t *);
+-
+-
+ #ifdef HAVE_PERCPU_SB
+ STATIC void   xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t,
+                                               int);
+@@ -1507,11 +1504,6 @@ xfs_unmountfs(
+        */
+       xfs_log_force(mp, XFS_LOG_SYNC);
+-      xfs_binval(mp->m_ddev_targp);
+-      if (mp->m_rtdev_targp) {
+-              xfs_binval(mp->m_rtdev_targp);
+-      }
+-
+       /*
+        * Unreserve any blocks we have so that when we unmount we don't account
+        * the reserved free space as used. This is really only necessary for
+@@ -1537,7 +1529,16 @@ xfs_unmountfs(
+               xfs_warn(mp, "Unable to update superblock counters. "
+                               "Freespace may not be correct on next mount.");
+       xfs_unmountfs_writesb(mp);
+-      xfs_unmountfs_wait(mp);                 /* wait for async bufs */
++
++      /*
++       * Make sure all buffers have been flushed and completed before
++       * unmounting the log.
++       */
++      error = xfs_flush_buftarg(mp->m_ddev_targp, 1);
++      if (error)
++              xfs_warn(mp, "%d busy buffers during unmount.", error);
++      xfs_wait_buftarg(mp->m_ddev_targp);
++
+       xfs_log_unmount_write(mp);
+       xfs_log_unmount(mp);
+       xfs_uuid_unmount(mp);
+@@ -1548,16 +1549,6 @@ xfs_unmountfs(
+       xfs_free_perag(mp);
+ }
+-STATIC void
+-xfs_unmountfs_wait(xfs_mount_t *mp)
+-{
+-      if (mp->m_logdev_targp != mp->m_ddev_targp)
+-              xfs_wait_buftarg(mp->m_logdev_targp);
+-      if (mp->m_rtdev_targp)
+-              xfs_wait_buftarg(mp->m_rtdev_targp);
+-      xfs_wait_buftarg(mp->m_ddev_targp);
+-}
+-
+ int
+ xfs_fs_writable(xfs_mount_t *mp)
+ {
diff --git a/queue-3.0/xfs-fix-error-handling-for-synchronous-writes.patch b/queue-3.0/xfs-fix-error-handling-for-synchronous-writes.patch
new file mode 100644 (file)
index 0000000..fc407e5
--- /dev/null
@@ -0,0 +1,42 @@
+From hch@infradead.org  Tue Nov 22 13:29:58 2011
+From: Christoph Hellwig <hch@infradead.org>
+Date: Sat, 19 Nov 2011 13:13:37 -0500
+Subject: xfs: fix error handling for synchronous writes
+To: stable@vger.kernel.org
+Cc: xfs@oss.sgi.com, Ajeet Yadav <ajeet.yadav.77@gmail.com>, Alex Elder <aelder@sgi.com>
+Message-ID: <20111119181543.361506649@bombadil.infradead.org>
+
+From: Christoph Hellwig <hch@infradead.org>
+
+If removed storage while synchronous buffer write underway,
+"xfslogd" hangs.
+
+Detailed log http://oss.sgi.com/archives/xfs/2011-07/msg00740.html
+
+Related work bfc60177f8ab509bc225becbb58f7e53a0e33e81
+"xfs: fix error handling for synchronous writes"
+
+Given that xfs_bwrite actually does the shutdown already after
+waiting for the b_iodone completion and given that we actually
+found that calling xfs_force_shutdown from inside
+xfs_buf_iodone_callbacks was a major contributor the problem
+it better to drop this call.
+
+Signed-off-by: Ajeet Yadav <ajeet.yadav.77@gmail.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Alex Elder <aelder@sgi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ fs/xfs/xfs_buf_item.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/fs/xfs/xfs_buf_item.c
++++ b/fs/xfs/xfs_buf_item.c
+@@ -1023,7 +1023,6 @@ xfs_buf_iodone_callbacks(
+       XFS_BUF_UNDELAYWRITE(bp);
+       trace_xfs_buf_error_relse(bp, _RET_IP_);
+-      xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
+ do_callbacks:
+       xfs_buf_do_callbacks(bp);
diff --git a/queue-3.0/xfs-fix-possible-memory-corruption-in-xfs_readlink.patch b/queue-3.0/xfs-fix-possible-memory-corruption-in-xfs_readlink.patch
new file mode 100644 (file)
index 0000000..98bbd84
--- /dev/null
@@ -0,0 +1,71 @@
+From hch@infradead.org  Tue Nov 22 13:38:33 2011
+From: Carlos Maiolino <cmaiolino@redhat.com>
+Date: Sat, 19 Nov 2011 13:13:44 -0500
+Subject: xfs: Fix possible memory corruption in xfs_readlink
+To: stable@vger.kernel.org
+Cc: xfs@oss.sgi.com, Alex Elder <aelder@sgi.com>, Carlos Maiolino <cmaiolino@redhat.com>
+Message-ID: <20111119181545.235475776@bombadil.infradead.org>
+
+From: Carlos Maiolino <cmaiolino@redhat.com>
+
+commit b52a360b2aa1c59ba9970fb0f52bbb093fcc7a24 upstream.
+
+Fixes a possible memory corruption when the link is larger than
+MAXPATHLEN and XFS_DEBUG is not enabled. This also remove the
+S_ISLNK assert, since the inode mode is checked previously in
+xfs_readlink_by_handle() and via VFS.
+
+Updated to address concerns raised by Ben Hutchings about the loose
+attention paid to 32- vs 64-bit values, and the lack of handling a
+potentially negative pathlen value:
+ - Changed type of "pathlen" to be xfs_fsize_t, to match that of
+   ip->i_d.di_size
+ - Added checking for a negative pathlen to the too-long pathlen
+   test, and generalized the message that gets reported in that case
+   to reflect the change
+As a result, if a negative pathlen were encountered, this function
+would return EFSCORRUPTED (and would fail an assertion for a debug
+build)--just as would a too-long pathlen.
+
+Signed-off-by: Alex Elder <aelder@sgi.com>
+Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ fs/xfs/xfs_vnodeops.c |   14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+--- a/fs/xfs/xfs_vnodeops.c
++++ b/fs/xfs/xfs_vnodeops.c
+@@ -535,7 +535,7 @@ xfs_readlink(
+       char            *link)
+ {
+       xfs_mount_t     *mp = ip->i_mount;
+-      int             pathlen;
++      xfs_fsize_t     pathlen;
+       int             error = 0;
+       trace_xfs_readlink(ip);
+@@ -545,13 +545,19 @@ xfs_readlink(
+       xfs_ilock(ip, XFS_ILOCK_SHARED);
+-      ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFLNK);
+-      ASSERT(ip->i_d.di_size <= MAXPATHLEN);
+-
+       pathlen = ip->i_d.di_size;
+       if (!pathlen)
+               goto out;
++      if (pathlen < 0 || pathlen > MAXPATHLEN) {
++              xfs_alert(mp, "%s: inode (%llu) bad symlink length (%lld)",
++                       __func__, (unsigned long long) ip->i_ino,
++                       (long long) pathlen);
++              ASSERT(0);
++              return XFS_ERROR(EFSCORRUPTED);
++      }
++
++
+       if (ip->i_df.if_flags & XFS_IFINLINE) {
+               memcpy(link, ip->i_df.if_u1.if_data, pathlen);
+               link[pathlen] = '\0';
diff --git a/queue-3.0/xfs-fix-write_inode-return-values.patch b/queue-3.0/xfs-fix-write_inode-return-values.patch
new file mode 100644 (file)
index 0000000..762bf5c
--- /dev/null
@@ -0,0 +1,94 @@
+From hch@infradead.org  Tue Nov 22 13:31:47 2011
+From: Christoph Hellwig <hch@infradead.org>
+Date: Sat, 19 Nov 2011 13:13:39 -0500
+Subject: xfs: fix ->write_inode return values
+To: stable@vger.kernel.org
+Cc: xfs@oss.sgi.com, Alex Elder <aelder@sgi.com>
+Message-ID: <20111119181543.809288814@bombadil.infradead.org>
+
+From: Christoph Hellwig <hch@infradead.org>
+
+patch 58d84c4ee0389ddeb86238d5d8359a982c9f7a5b upstream.
+
+Currently we always redirty an inode that was attempted to be written out
+synchronously but has been cleaned by an AIL pushed internall, which is
+rather bogus.  Fix that by doing the i_update_core check early on and
+return 0 for it.  Also include async calls for it, as doing any work for
+those is just as pointless.  While we're at it also fix the sign for the
+EIO return in case of a filesystem shutdown, and fix the completely
+non-sensical locking around xfs_log_inode.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Signed-off-by: Alex Elder <aelder@sgi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ fs/xfs/linux-2.6/xfs_super.c |   34 +++++++++-------------------------
+ 1 file changed, 9 insertions(+), 25 deletions(-)
+
+--- a/fs/xfs/linux-2.6/xfs_super.c
++++ b/fs/xfs/linux-2.6/xfs_super.c
+@@ -878,33 +878,17 @@ xfs_log_inode(
+       struct xfs_trans        *tp;
+       int                     error;
+-      xfs_iunlock(ip, XFS_ILOCK_SHARED);
+       tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
+       error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0);
+-
+       if (error) {
+               xfs_trans_cancel(tp, 0);
+-              /* we need to return with the lock hold shared */
+-              xfs_ilock(ip, XFS_ILOCK_SHARED);
+               return error;
+       }
+       xfs_ilock(ip, XFS_ILOCK_EXCL);
+-
+-      /*
+-       * Note - it's possible that we might have pushed ourselves out of the
+-       * way during trans_reserve which would flush the inode.  But there's
+-       * no guarantee that the inode buffer has actually gone out yet (it's
+-       * delwri).  Plus the buffer could be pinned anyway if it's part of
+-       * an inode in another recent transaction.  So we play it safe and
+-       * fire off the transaction anyway.
+-       */
+-      xfs_trans_ijoin(tp, ip);
++      xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL);
+       xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+-      error = xfs_trans_commit(tp, 0);
+-      xfs_ilock_demote(ip, XFS_ILOCK_EXCL);
+-
+-      return error;
++      return xfs_trans_commit(tp, 0);
+ }
+ STATIC int
+@@ -919,7 +903,9 @@ xfs_fs_write_inode(
+       trace_xfs_write_inode(ip);
+       if (XFS_FORCED_SHUTDOWN(mp))
+-              return XFS_ERROR(EIO);
++              return -XFS_ERROR(EIO);
++      if (!ip->i_update_core)
++              return 0;
+       if (wbc->sync_mode == WB_SYNC_ALL) {
+               /*
+@@ -930,12 +916,10 @@ xfs_fs_write_inode(
+                * of synchronous log foces dramatically.
+                */
+               xfs_ioend_wait(ip);
+-              xfs_ilock(ip, XFS_ILOCK_SHARED);
+-              if (ip->i_update_core) {
+-                      error = xfs_log_inode(ip);
+-                      if (error)
+-                              goto out_unlock;
+-              }
++              error = xfs_log_inode(ip);
++              if (error)
++                      goto out;
++              return 0;
+       } else {
+               /*
+                * We make this non-blocking if the inode is contended, return
diff --git a/queue-3.0/xfs-fix-xfs_mark_inode_dirty-during-umount.patch b/queue-3.0/xfs-fix-xfs_mark_inode_dirty-during-umount.patch
new file mode 100644 (file)
index 0000000..728e05a
--- /dev/null
@@ -0,0 +1,71 @@
+From hch@infradead.org  Tue Nov 22 13:31:23 2011
+From: Christoph Hellwig <hch@infradead.org>
+Date: Sat, 19 Nov 2011 13:13:38 -0500
+Subject: xfs: fix xfs_mark_inode_dirty during umount
+To: stable@vger.kernel.org
+Cc: xfs@oss.sgi.com, Alex Elder <aelder@sgi.com>
+Message-ID: <20111119181543.605305176@bombadil.infradead.org>
+
+From: Christoph Hellwig <hch@infradead.org>
+
+commit 866e4ed77448a0c311e1b055eb72ea05423fd799 upstream.
+
+During umount we do not add a dirty inode to the lru and wait for it to
+become clean first, but force writeback of data and metadata with
+I_WILL_FREE set.  Currently there is no way for XFS to detect that the
+inode has been redirtied for metadata operations, as we skip the
+mark_inode_dirty call during teardown.  Fix this by setting i_update_core
+nanually in that case, so that the inode gets flushed during inode reclaim.
+
+Alternatively we could enable calling mark_inode_dirty for inodes in
+I_WILL_FREE state, and let the VFS dirty tracking handle this.  I decided
+against this as we will get better I/O patterns from reclaim compared to
+the synchronous writeout in write_inode_now, and always marking the inode
+dirty in some way from xfs_mark_inode_dirty is a better safetly net in
+either case.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Signed-off-by: Alex Elder <aelder@sgi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ fs/xfs/linux-2.6/xfs_iops.c |   14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+--- a/fs/xfs/linux-2.6/xfs_iops.c
++++ b/fs/xfs/linux-2.6/xfs_iops.c
+@@ -69,9 +69,8 @@ xfs_synchronize_times(
+ }
+ /*
+- * If the linux inode is valid, mark it dirty.
+- * Used when committing a dirty inode into a transaction so that
+- * the inode will get written back by the linux code
++ * If the linux inode is valid, mark it dirty, else mark the dirty state
++ * in the XFS inode to make sure we pick it up when reclaiming the inode.
+  */
+ void
+ xfs_mark_inode_dirty_sync(
+@@ -81,6 +80,10 @@ xfs_mark_inode_dirty_sync(
+       if (!(inode->i_state & (I_WILL_FREE|I_FREEING)))
+               mark_inode_dirty_sync(inode);
++      else {
++              barrier();
++              ip->i_update_core = 1;
++      }
+ }
+ void
+@@ -91,6 +94,11 @@ xfs_mark_inode_dirty(
+       if (!(inode->i_state & (I_WILL_FREE|I_FREEING)))
+               mark_inode_dirty(inode);
++      else {
++              barrier();
++              ip->i_update_core = 1;
++      }
++
+ }
+ /*
diff --git a/queue-3.0/xfs-return-eio-when-xfs_vn_getattr-failed.patch b/queue-3.0/xfs-return-eio-when-xfs_vn_getattr-failed.patch
new file mode 100644 (file)
index 0000000..bf5e2d2
--- /dev/null
@@ -0,0 +1,40 @@
+From hch@infradead.org  Tue Nov 22 13:37:09 2011
+From: Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>
+Date: Sat, 19 Nov 2011 13:13:42 -0500
+Subject: xfs: Return -EIO when xfs_vn_getattr() failed
+To: stable@vger.kernel.org
+Cc: xfs@oss.sgi.com, Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>, Alex Elder <aelder@sgi.com>
+Message-ID: <20111119181544.706389934@bombadil.infradead.org>
+
+From: Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>
+
+commit ed32201e65e15f3e6955cb84cbb544b08f81e5a5 upstream.
+
+An attribute of inode can be fetched via xfs_vn_getattr() in XFS.
+Currently it returns EIO, not negative value, when it failed.  As a
+result, the system call returns not negative value even though an
+error occured. The stat(2), ls and mv commands cannot handle this
+error and do not work correctly.
+
+This patch fixes this bug, and returns -EIO, not EIO when an error
+is detected in xfs_vn_getattr().
+
+Signed-off-by: Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Alex Elder <aelder@sgi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ fs/xfs/linux-2.6/xfs_iops.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/xfs/linux-2.6/xfs_iops.c
++++ b/fs/xfs/linux-2.6/xfs_iops.c
+@@ -464,7 +464,7 @@ xfs_vn_getattr(
+       trace_xfs_getattr(ip);
+       if (XFS_FORCED_SHUTDOWN(mp))
+-              return XFS_ERROR(EIO);
++              return -XFS_ERROR(EIO);
+       stat->size = XFS_ISIZE(ip);
+       stat->dev = inode->i_sb->s_dev;
diff --git a/queue-3.0/xfs-use-doalloc-flag-in-xfs_qm_dqattach_one.patch b/queue-3.0/xfs-use-doalloc-flag-in-xfs_qm_dqattach_one.patch
new file mode 100644 (file)
index 0000000..4002cee
--- /dev/null
@@ -0,0 +1,51 @@
+From hch@infradead.org  Tue Nov 22 13:39:12 2011
+From: Christoph Hellwig <hch@infradead.org>
+Date: Sat, 19 Nov 2011 13:13:45 -0500
+Subject: xfs: use doalloc flag in xfs_qm_dqattach_one()
+To: stable@vger.kernel.org
+Cc: xfs@oss.sgi.com, Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>, Alex Elder <aelder@sgi.com>, Ben Myers <bpm@sgi.com>
+Message-ID: <20111119181545.413417685@bombadil.infradead.org>
+
+From: Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>
+
+commit db3e74b582915d66e10b0c73a62763418f54c340 upstream
+
+The doalloc arg in xfs_qm_dqattach_one() is a flag that indicates
+whether a new area to handle quota information will be allocated
+if needed. Originally, it was passed to xfs_qm_dqget(), but has
+been removed by the following commit (probably by mistake):
+
+       commit 8e9b6e7fa4544ea8a0e030c8987b918509c8ff47
+       Author: Christoph Hellwig <hch@lst.de>
+       Date:   Sun Feb 8 21:51:42 2009 +0100
+
+       xfs: remove the unused XFS_QMOPT_DQLOCK flag
+
+As the result, xfs_qm_dqget() called from xfs_qm_dqattach_one()
+never allocates the new area even if it is needed.
+
+This patch gives the doalloc arg to xfs_qm_dqget() in
+xfs_qm_dqattach_one() to fix this problem.
+
+Signed-off-by: Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>
+Cc: Alex Elder <aelder@sgi.com>
+Cc: Christoph Hellwig <hch@infradead.org>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Ben Myers <bpm@sgi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ fs/xfs/quota/xfs_qm.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/xfs/quota/xfs_qm.c
++++ b/fs/xfs/quota/xfs_qm.c
+@@ -714,7 +714,8 @@ xfs_qm_dqattach_one(
+        * disk and we didn't ask it to allocate;
+        * ESRCH if quotas got turned off suddenly.
+        */
+-      error = xfs_qm_dqget(ip->i_mount, ip, id, type, XFS_QMOPT_DOWARN, &dqp);
++      error = xfs_qm_dqget(ip->i_mount, ip, id, type,
++                           doalloc | XFS_QMOPT_DOWARN, &dqp);
+       if (error)
+               return error;