--- /dev/null
+From 7253b85cc62d6ff84143d96fe6cd54f73736f4d7 Mon Sep 17 00:00:00 2001
+From: Simon Horman <horms@verge.net.au>
+Date: Fri, 28 Sep 2012 02:12:45 +0100
+Subject: ARM: 7541/1: Add ARM ERRATA 775420 workaround
+
+From: Simon Horman <horms@verge.net.au>
+
+commit 7253b85cc62d6ff84143d96fe6cd54f73736f4d7 upstream.
+
+arm: Add ARM ERRATA 775420 workaround
+
+Workaround for the 775420 Cortex-A9 (r2p2, r2p6,r2p8,r2p10,r3p0) erratum.
+In case a date cache maintenance operation aborts with MMU exception, it
+might cause the processor to deadlock. This workaround puts DSB before
+executing ISB if an abort may occur on cache maintenance.
+
+Based on work by Kouei Abe and feedback from Catalin Marinas.
+
+Signed-off-by: Kouei Abe <kouei.abe.cp@rms.renesas.com>
+[ horms@verge.net.au: Changed to implementation
+ suggested by catalin.marinas@arm.com ]
+Acked-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/Kconfig | 10 ++++++++++
+ arch/arm/mm/cache-v7.S | 3 +++
+ 2 files changed, 13 insertions(+)
+
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1413,6 +1413,16 @@ config PL310_ERRATA_769419
+ on systems with an outer cache, the store buffer is drained
+ explicitly.
+
++config ARM_ERRATA_775420
++ bool "ARM errata: A data cache maintenance operation which aborts, might lead to deadlock"
++ depends on CPU_V7
++ help
++ This option enables the workaround for the 775420 Cortex-A9 (r2p2,
++ r2p6,r2p8,r2p10,r3p0) erratum. In case a date cache maintenance
++ operation aborts with MMU exception, it might cause the processor
++ to deadlock. This workaround puts DSB before executing ISB if
++ an abort may occur on cache maintenance.
++
+ endmenu
+
+ source "arch/arm/common/Kconfig"
+--- a/arch/arm/mm/cache-v7.S
++++ b/arch/arm/mm/cache-v7.S
+@@ -211,6 +211,9 @@ ENTRY(v7_coherent_user_range)
+ * isn't mapped, fail with -EFAULT.
+ */
+ 9001:
++#ifdef CONFIG_ARM_ERRATA_775420
++ dsb
++#endif
+ mov r0, #-EFAULT
+ mov pc, lr
+ UNWIND(.fnend )
--- /dev/null
+From 9d7d6e363b06934221b81a859d509844c97380df Mon Sep 17 00:00:00 2001
+From: Colin Cross <ccross@android.com>
+Date: Mon, 8 Oct 2012 14:01:12 -0700
+Subject: ARM: OMAP: counter: add locking to read_persistent_clock
+
+From: Colin Cross <ccross@android.com>
+
+commit 9d7d6e363b06934221b81a859d509844c97380df upstream.
+
+read_persistent_clock uses a global variable, use a spinlock to
+ensure non-atomic updates to the variable don't overlap and cause
+time to move backwards.
+
+Signed-off-by: Colin Cross <ccross@android.com>
+Signed-off-by: R Sricharan <r.sricharan@ti.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/plat-omap/counter_32k.c | 21 ++++++++++++++-------
+ 1 file changed, 14 insertions(+), 7 deletions(-)
+
+--- a/arch/arm/plat-omap/counter_32k.c
++++ b/arch/arm/plat-omap/counter_32k.c
+@@ -55,22 +55,29 @@ static u32 notrace omap_32k_read_sched_c
+ * nsecs and adds to a monotonically increasing timespec.
+ */
+ static struct timespec persistent_ts;
+-static cycles_t cycles, last_cycles;
++static cycles_t cycles;
+ static unsigned int persistent_mult, persistent_shift;
++static DEFINE_SPINLOCK(read_persistent_clock_lock);
++
+ static void omap_read_persistent_clock(struct timespec *ts)
+ {
+ unsigned long long nsecs;
+- cycles_t delta;
+- struct timespec *tsp = &persistent_ts;
++ cycles_t last_cycles;
++ unsigned long flags;
++
++ spin_lock_irqsave(&read_persistent_clock_lock, flags);
+
+ last_cycles = cycles;
+ cycles = sync32k_cnt_reg ? __raw_readl(sync32k_cnt_reg) : 0;
+- delta = cycles - last_cycles;
+
+- nsecs = clocksource_cyc2ns(delta, persistent_mult, persistent_shift);
++ nsecs = clocksource_cyc2ns(cycles - last_cycles,
++ persistent_mult, persistent_shift);
++
++ timespec_add_ns(&persistent_ts, nsecs);
++
++ *ts = persistent_ts;
+
+- timespec_add_ns(tsp, nsecs);
+- *ts = *tsp;
++ spin_unlock_irqrestore(&read_persistent_clock_lock, flags);
+ }
+
+ /**
--- /dev/null
+From 790198f74c9d1b46b6a89504361b1a844670d050 Mon Sep 17 00:00:00 2001
+From: Stefan Richter <stefanr@s5r6.in-berlin.de>
+Date: Sat, 6 Oct 2012 14:12:56 +0200
+Subject: firewire: cdev: fix user memory corruption (i386 userland on amd64 kernel)
+
+From: Stefan Richter <stefanr@s5r6.in-berlin.de>
+
+commit 790198f74c9d1b46b6a89504361b1a844670d050 upstream.
+
+Fix two bugs of the /dev/fw* character device concerning the
+FW_CDEV_IOC_GET_INFO ioctl with nonzero fw_cdev_get_info.bus_reset.
+(Practically all /dev/fw* clients issue this ioctl right after opening
+the device.)
+
+Both bugs are caused by sizeof(struct fw_cdev_event_bus_reset) being 36
+without natural alignment and 40 with natural alignment.
+
+ 1) Memory corruption, affecting i386 userland on amd64 kernel:
+ Userland reserves a 36 bytes large buffer, kernel writes 40 bytes.
+ This has been first found and reported against libraw1394 if
+ compiled with gcc 4.7 which happens to order libraw1394's stack such
+ that the bug became visible as data corruption.
+
+ 2) Information leak, affecting all kernel architectures except i386:
+ 4 bytes of random kernel stack data were leaked to userspace.
+
+Hence limit the respective copy_to_user() to the 32-bit aligned size of
+struct fw_cdev_event_bus_reset.
+
+Reported-by: Simon Kirby <sim@hostway.ca>
+Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/firewire/core-cdev.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/firewire/core-cdev.c
++++ b/drivers/firewire/core-cdev.c
+@@ -473,8 +473,8 @@ static int ioctl_get_info(struct client
+ client->bus_reset_closure = a->bus_reset_closure;
+ if (a->bus_reset != 0) {
+ fill_bus_reset_event(&bus_reset, client);
+- ret = copy_to_user(u64_to_uptr(a->bus_reset),
+- &bus_reset, sizeof(bus_reset));
++ /* unaligned size of bus_reset is 36 bytes */
++ ret = copy_to_user(u64_to_uptr(a->bus_reset), &bus_reset, 36);
+ }
+ if (ret == 0 && list_empty(&client->link))
+ list_add_tail(&client->link, &client->device->client_list);
--- /dev/null
+From 38b11bae6ba02da352340aff12ee25755977b222 Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Sun, 30 Sep 2012 12:20:02 -0700
+Subject: iscsi-target: Add explicit set of cache_dynamic_acls=1 for TPG demo-mode
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit 38b11bae6ba02da352340aff12ee25755977b222 upstream.
+
+We've had reports in the past about this specific case, so it's time to
+go ahead and explicitly set cache_dynamic_acls=1 for generate_node_acls=1
+(TPG demo-mode) operation.
+
+During normal generate_node_acls=0 operation with explicit NodeACLs ->
+se_node_acl memory is persistent to the configfs group located at
+/sys/kernel/config/target/$TARGETNAME/$TPGT/acls/$INITIATORNAME, so in
+the generate_node_acls=1 case we want the reservation logic to reference
+existing per initiator IQN se_node_acl memory (not to generate a new
+se_node_acl), so go ahead and always set cache_dynamic_acls=1 when
+TPG demo-mode is enabled.
+
+Reported-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/iscsi/iscsi_target_tpg.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/target/iscsi/iscsi_target_tpg.c
++++ b/drivers/target/iscsi/iscsi_target_tpg.c
+@@ -677,6 +677,12 @@ int iscsit_ta_generate_node_acls(
+ pr_debug("iSCSI_TPG[%hu] - Generate Initiator Portal Group ACLs: %s\n",
+ tpg->tpgt, (a->generate_node_acls) ? "Enabled" : "Disabled");
+
++ if (flag == 1 && a->cache_dynamic_acls == 0) {
++ pr_debug("Explicitly setting cache_dynamic_acls=1 when "
++ "generate_node_acls=1\n");
++ a->cache_dynamic_acls = 1;
++ }
++
+ return 0;
+ }
+
+@@ -716,6 +722,12 @@ int iscsit_ta_cache_dynamic_acls(
+ return -EINVAL;
+ }
+
++ if (a->generate_node_acls == 1 && flag == 0) {
++ pr_debug("Skipping cache_dynamic_acls=0 when"
++ " generate_node_acls=1\n");
++ return 0;
++ }
++
+ a->cache_dynamic_acls = flag;
+ pr_debug("iSCSI_TPG[%hu] - Cache Dynamic Initiator Portal Group"
+ " ACLs %s\n", tpg->tpgt, (a->cache_dynamic_acls) ?
--- /dev/null
+From cf0eb28d3ba60098865bf7dbcbfdd6b1cc483e3b Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Wed, 3 Oct 2012 15:42:48 -0700
+Subject: iscsi-target: Bump defaults for nopin_timeout + nopin_response_timeout values
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit cf0eb28d3ba60098865bf7dbcbfdd6b1cc483e3b upstream.
+
+This patch increases the default for nopin_timeout to 15 seconds (wait
+between sending a new NopIN ping) and nopin_response_timeout to 30 seconds
+(wait for NopOUT response before failing the connection) in order to avoid
+false positives by iSCSI Initiators who are not always able (under load) to
+respond to NopIN echo PING requests within the current 5 second window.
+
+False positives have been observed recently using Open-iSCSI code on v3.3.x
+with heavy large-block READ workloads over small MTU 1 Gb/sec ports, and
+increasing these values to more reasonable defaults significantly reduces
+the possibility of false positive NopIN response timeout events under
+this specific workload.
+
+Historically these have been set low to initiate connection recovery as
+soon as possible if we don't hear a ping back, but for modern v3.x code
+on 1 -> 10 Gb/sec ports these new defaults make alot more sense.
+
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Andy Grover <agrover@redhat.com>
+Cc: Mike Christie <michaelc@cs.wisc.edu>
+Cc: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/iscsi/iscsi_target_core.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/target/iscsi/iscsi_target_core.h
++++ b/drivers/target/iscsi/iscsi_target_core.h
+@@ -25,10 +25,10 @@
+ #define NA_DATAOUT_TIMEOUT_RETRIES 5
+ #define NA_DATAOUT_TIMEOUT_RETRIES_MAX 15
+ #define NA_DATAOUT_TIMEOUT_RETRIES_MIN 1
+-#define NA_NOPIN_TIMEOUT 5
++#define NA_NOPIN_TIMEOUT 15
+ #define NA_NOPIN_TIMEOUT_MAX 60
+ #define NA_NOPIN_TIMEOUT_MIN 3
+-#define NA_NOPIN_RESPONSE_TIMEOUT 5
++#define NA_NOPIN_RESPONSE_TIMEOUT 30
+ #define NA_NOPIN_RESPONSE_TIMEOUT_MAX 60
+ #define NA_NOPIN_RESPONSE_TIMEOUT_MIN 3
+ #define NA_RANDOM_DATAIN_PDU_OFFSETS 0
--- /dev/null
+From f25590f39d543272f7ae7b00d533359c8d7ff331 Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Sat, 22 Sep 2012 17:21:06 -0700
+Subject: iscsi-target: Correctly set 0xffffffff field within ISCSI_OP_REJECT PDU
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit f25590f39d543272f7ae7b00d533359c8d7ff331 upstream.
+
+This patch adds a missing iscsi_reject->ffffffff assignment within
+iscsit_send_reject() code to properly follow RFC-3720 Section 10.17
+Bytes 16 -> 19 for the PDU format definition of ISCSI_OP_REJECT.
+
+We've not seen any initiators care about this bytes in practice, but
+as Ronnie reported this was causing trouble with wireshark packet
+decoding lets go ahead and fix this up now.
+
+Reported-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/iscsi/iscsi_target.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/target/iscsi/iscsi_target.c
++++ b/drivers/target/iscsi/iscsi_target.c
+@@ -3424,6 +3424,7 @@ static int iscsit_send_reject(
+ hdr->opcode = ISCSI_OP_REJECT;
+ hdr->flags |= ISCSI_FLAG_CMD_FINAL;
+ hton24(hdr->dlength, ISCSI_HDR_LEN);
++ hdr->ffffffff = 0xffffffff;
+ cmd->stat_sn = conn->stat_sn++;
+ hdr->statsn = cpu_to_be32(cmd->stat_sn);
+ hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
--- /dev/null
+From 904753da183566c71211d23c169a80184648c121 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@infradead.org>
+Date: Wed, 26 Sep 2012 08:00:37 -0400
+Subject: iscsit: remove incorrect unlock in iscsit_build_sendtargets_resp
+
+From: Christoph Hellwig <hch@infradead.org>
+
+commit 904753da183566c71211d23c169a80184648c121 upstream.
+
+Fix a potential multiple spin-unlock -> deadlock scenario during the
+overflow check within iscsit_build_sendtargets_resp() as found by
+sparse static checking.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/iscsi/iscsi_target.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/target/iscsi/iscsi_target.c
++++ b/drivers/target/iscsi/iscsi_target.c
+@@ -3271,7 +3271,6 @@ static int iscsit_build_sendtargets_resp
+ len += 1;
+
+ if ((len + payload_len) > buffer_len) {
+- spin_unlock(&tiqn->tiqn_tpg_lock);
+ end_of_buf = 1;
+ goto eob;
+ }
--- /dev/null
+From bc977749e967daa56de1922cf4cb38525631c51c Mon Sep 17 00:00:00 2001
+From: Lukas Czerner <lczerner@redhat.com>
+Date: Thu, 16 Aug 2012 16:38:45 +0200
+Subject: SCSI: scsi_debug: Fix off-by-one bug when unmapping region
+
+From: Lukas Czerner <lczerner@redhat.com>
+
+commit bc977749e967daa56de1922cf4cb38525631c51c upstream.
+
+Currently it is possible to unmap one more block than user requested to
+due to the off-by-one error in unmap_region(). This is probably due to
+the fact that the end variable despite its name actually points to the
+last block to unmap + 1. However in the condition it is handled as the
+last block of the region to unmap.
+
+The bug was not previously spotted probably due to the fact that the
+region was not zeroed, which has changed with commit
+be1dd78de5686c062bb3103f9e86d444a10ed783. With that commit we were able
+to corrupt the ext4 file system on 256M scsi_debug device with LBPRZ
+enabled using fstrim.
+
+Since the 'end' semantic is the same in several functions there this
+commit just fixes the condition to use the 'end' variable correctly in
+that context.
+
+Reported-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Lukas Czerner <lczerner@redhat.com>
+Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Douglas Gilbert <dgilbert@interlog.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/scsi_debug.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -2054,7 +2054,7 @@ static void unmap_region(sector_t lba, u
+ block = lba + alignment;
+ rem = do_div(block, granularity);
+
+- if (rem == 0 && lba + granularity <= end && block < map_size) {
++ if (rem == 0 && lba + granularity < end && block < map_size) {
+ clear_bit(block, map_storep);
+ if (scsi_debug_lbprz)
+ memset(fake_storep +
--- /dev/null
+From 5c1b10ab7f93d24f29b5630286e323d1c5802d5c Mon Sep 17 00:00:00 2001
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Tue, 2 Oct 2012 11:03:31 -0700
+Subject: SCSI: storvsc: Account for in-transit packets in the RESET path
+
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+
+commit 5c1b10ab7f93d24f29b5630286e323d1c5802d5c upstream.
+
+Properly account for I/O in transit before returning from the RESET call.
+In the absense of this patch, we could have a situation where the host may
+respond to a command that was issued prior to the issuance of the RESET
+command at some arbitrary time after responding to the RESET command.
+Currently, the host does not do anything with the RESET command.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/storvsc_drv.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/scsi/storvsc_drv.c
++++ b/drivers/scsi/storvsc_drv.c
+@@ -1221,7 +1221,12 @@ static int storvsc_host_reset_handler(st
+ /*
+ * At this point, all outstanding requests in the adapter
+ * should have been flushed out and return to us
++ * There is a potential race here where the host may be in
++ * the process of responding when we return from here.
++ * Just wait for all in-transit packets to be accounted for
++ * before we return from here.
+ */
++ storvsc_wait_to_drain(stor_device);
+
+ return SUCCESS;
+ }
--- /dev/null
+From 2e9c9dfde00a6466441e93033cf2c37f720bdacf Mon Sep 17 00:00:00 2001
+From: "Richard W.M. Jones" <rjones@redhat.com>
+Date: Tue, 2 Oct 2012 17:25:46 +0200
+Subject: SCSI: virtio-scsi: initialize scatterlist structure
+
+From: "Richard W.M. Jones" <rjones@redhat.com>
+
+commit 2e9c9dfde00a6466441e93033cf2c37f720bdacf upstream.
+
+The sg struct is used without being initialized, which breaks
+when CONFIG_DEBUG_SG is enabled.
+
+Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/virtio_scsi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/scsi/virtio_scsi.c
++++ b/drivers/scsi/virtio_scsi.c
+@@ -219,7 +219,7 @@ static int virtscsi_kick_event(struct vi
+ struct scatterlist sg;
+ unsigned long flags;
+
+- sg_set_buf(&sg, &event_node->event, sizeof(struct virtio_scsi_event));
++ sg_init_one(&sg, &event_node->event, sizeof(struct virtio_scsi_event));
+
+ spin_lock_irqsave(&vscsi->event_vq.vq_lock, flags);
+
alsa-hda-fix-memory-leaks-at-error-path-in-patch_cirrus.c.patch
mips-kgdb-fix-recursive-page-fault-with-config_kprobes.patch
tmpfs-ceph-gfs2-isofs-reiserfs-xfs-fix-fh_len-checking.patch
+iscsi-target-correctly-set-0xffffffff-field-within-iscsi_op_reject-pdu.patch
+iscsit-remove-incorrect-unlock-in-iscsit_build_sendtargets_resp.patch
+iscsi-target-add-explicit-set-of-cache_dynamic_acls-1-for-tpg-demo-mode.patch
+iscsi-target-bump-defaults-for-nopin_timeout-nopin_response_timeout-values.patch
+scsi-storvsc-account-for-in-transit-packets-in-the-reset-path.patch
+scsi-scsi_debug-fix-off-by-one-bug-when-unmapping-region.patch
+scsi-virtio-scsi-initialize-scatterlist-structure.patch
+arm-7541-1-add-arm-errata-775420-workaround.patch
+arm-omap-counter-add-locking-to-read_persistent_clock.patch
+firewire-cdev-fix-user-memory-corruption-i386-userland-on-amd64-kernel.patch
+sunrpc-ensure-that-the-tcp-socket-is-closed-when-in-close_wait.patch
--- /dev/null
+From a519fc7a70d1a918574bb826cc6905b87b482eb9 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Wed, 12 Sep 2012 16:49:15 -0400
+Subject: SUNRPC: Ensure that the TCP socket is closed when in CLOSE_WAIT
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+commit a519fc7a70d1a918574bb826cc6905b87b482eb9 upstream.
+
+Instead of doing a shutdown() call, we need to do an actual close().
+Ditto if/when the server is sending us junk RPC headers.
+
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Tested-by: Simon Kirby <sim@hostway.ca>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/sunrpc/xprtsock.c | 21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+--- a/net/sunrpc/xprtsock.c
++++ b/net/sunrpc/xprtsock.c
+@@ -1025,6 +1025,16 @@ static void xs_udp_data_ready(struct soc
+ read_unlock_bh(&sk->sk_callback_lock);
+ }
+
++/*
++ * Helper function to force a TCP close if the server is sending
++ * junk and/or it has put us in CLOSE_WAIT
++ */
++static void xs_tcp_force_close(struct rpc_xprt *xprt)
++{
++ set_bit(XPRT_CONNECTION_CLOSE, &xprt->state);
++ xprt_force_disconnect(xprt);
++}
++
+ static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_reader *desc)
+ {
+ struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
+@@ -1051,7 +1061,7 @@ static inline void xs_tcp_read_fraghdr(s
+ /* Sanity check of the record length */
+ if (unlikely(transport->tcp_reclen < 8)) {
+ dprintk("RPC: invalid TCP record fragment length\n");
+- xprt_force_disconnect(xprt);
++ xs_tcp_force_close(xprt);
+ return;
+ }
+ dprintk("RPC: reading TCP record fragment of length %d\n",
+@@ -1132,7 +1142,7 @@ static inline void xs_tcp_read_calldir(s
+ break;
+ default:
+ dprintk("RPC: invalid request message type\n");
+- xprt_force_disconnect(&transport->xprt);
++ xs_tcp_force_close(&transport->xprt);
+ }
+ xs_tcp_check_fraghdr(transport);
+ }
+@@ -1455,6 +1465,8 @@ static void xs_tcp_cancel_linger_timeout
+ static void xs_sock_mark_closed(struct rpc_xprt *xprt)
+ {
+ smp_mb__before_clear_bit();
++ clear_bit(XPRT_CONNECTION_ABORT, &xprt->state);
++ clear_bit(XPRT_CONNECTION_CLOSE, &xprt->state);
+ clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
+ clear_bit(XPRT_CLOSING, &xprt->state);
+ smp_mb__after_clear_bit();
+@@ -1512,8 +1524,8 @@ static void xs_tcp_state_change(struct s
+ break;
+ case TCP_CLOSE_WAIT:
+ /* The server initiated a shutdown of the socket */
+- xprt_force_disconnect(xprt);
+ xprt->connect_cookie++;
++ xs_tcp_force_close(xprt);
+ case TCP_CLOSING:
+ /*
+ * If the server closed down the connection, make sure that
+@@ -2199,8 +2211,7 @@ static void xs_tcp_setup_socket(struct w
+ /* We're probably in TIME_WAIT. Get rid of existing socket,
+ * and retry
+ */
+- set_bit(XPRT_CONNECTION_CLOSE, &xprt->state);
+- xprt_force_disconnect(xprt);
++ xs_tcp_force_close(xprt);
+ break;
+ case -ECONNREFUSED:
+ case -ECONNRESET: