--- /dev/null
+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);
--- /dev/null
+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);
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
--- /dev/null
+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)
--- /dev/null
+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);
+
--- /dev/null
+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)
+ {
--- /dev/null
+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);
--- /dev/null
+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';
--- /dev/null
+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
--- /dev/null
+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;
++ }
++
+ }
+
+ /*
--- /dev/null
+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;
--- /dev/null
+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;
+