]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.17-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 23 Oct 2014 09:05:51 +0000 (17:05 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 23 Oct 2014 09:05:51 +0000 (17:05 +0800)
added patches:
documentation-lzo-document-part-of-the-encoding.patch
fixing-lease-renewal.patch
hid-wacom-remove-report_id-from-wacom_get_report-interface.patch
lzo-check-for-length-overrun-in-variable-length-encoding.patch
m68k-disable-restore-interrupts-in-hwreg_present-hwreg_write.patch
mei-bus-fix-possible-boundaries-violation.patch
nfs-fix-a-bogus-warning-in-nfs_generic_pgio.patch
nfs-fix-an-uninitialised-pointer-oops-in-the-writeback-error-path.patch
nfs-fix-duplicate-proc-entries.patch
nfsd4-reserve-adequate-space-for-lock-op.patch
nfsv4-fix-lock-recovery-when-create_session-setclientid_confirm-fails.patch
nfsv4-fix-open-lock-state-recovery-error-handling.patch
nfsv4.1-fix-an-nfsv4.1-state-renewal-regression.patch
nfsv4.1-pnfs-replace-broken-pnfs_put_lseg_async.patch
revert-lzo-properly-check-for-overruns.patch
tty-omap-serial-fix-division-by-zero.patch

17 files changed:
queue-3.17/documentation-lzo-document-part-of-the-encoding.patch [new file with mode: 0644]
queue-3.17/fixing-lease-renewal.patch [new file with mode: 0644]
queue-3.17/hid-wacom-remove-report_id-from-wacom_get_report-interface.patch [new file with mode: 0644]
queue-3.17/lzo-check-for-length-overrun-in-variable-length-encoding.patch [new file with mode: 0644]
queue-3.17/m68k-disable-restore-interrupts-in-hwreg_present-hwreg_write.patch [new file with mode: 0644]
queue-3.17/mei-bus-fix-possible-boundaries-violation.patch [new file with mode: 0644]
queue-3.17/nfs-fix-a-bogus-warning-in-nfs_generic_pgio.patch [new file with mode: 0644]
queue-3.17/nfs-fix-an-uninitialised-pointer-oops-in-the-writeback-error-path.patch [new file with mode: 0644]
queue-3.17/nfs-fix-duplicate-proc-entries.patch [new file with mode: 0644]
queue-3.17/nfsd4-reserve-adequate-space-for-lock-op.patch [new file with mode: 0644]
queue-3.17/nfsv4-fix-lock-recovery-when-create_session-setclientid_confirm-fails.patch [new file with mode: 0644]
queue-3.17/nfsv4-fix-open-lock-state-recovery-error-handling.patch [new file with mode: 0644]
queue-3.17/nfsv4.1-fix-an-nfsv4.1-state-renewal-regression.patch [new file with mode: 0644]
queue-3.17/nfsv4.1-pnfs-replace-broken-pnfs_put_lseg_async.patch [new file with mode: 0644]
queue-3.17/revert-lzo-properly-check-for-overruns.patch [new file with mode: 0644]
queue-3.17/series
queue-3.17/tty-omap-serial-fix-division-by-zero.patch [new file with mode: 0644]

diff --git a/queue-3.17/documentation-lzo-document-part-of-the-encoding.patch b/queue-3.17/documentation-lzo-document-part-of-the-encoding.patch
new file mode 100644 (file)
index 0000000..8e8866f
--- /dev/null
@@ -0,0 +1,189 @@
+From d98a0526434d27e261f622cf9d2e0028b5ff1a00 Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Sat, 27 Sep 2014 12:31:35 +0200
+Subject: Documentation: lzo: document part of the encoding
+
+From: Willy Tarreau <w@1wt.eu>
+
+commit d98a0526434d27e261f622cf9d2e0028b5ff1a00 upstream.
+
+Add a complete description of the LZO format as processed by the
+decompressor. I have not found a public specification of this format
+hence this analysis, which will be used to better understand the code.
+
+Cc: Willem Pinckaers <willem@lekkertech.net>
+Cc: "Don A. Bailey" <donb@securitymouse.com>
+Signed-off-by: Willy Tarreau <w@1wt.eu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ Documentation/lzo.txt |  164 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 164 insertions(+)
+
+--- /dev/null
++++ b/Documentation/lzo.txt
+@@ -0,0 +1,164 @@
++
++LZO stream format as understood by Linux's LZO decompressor
++===========================================================
++
++Introduction
++
++  This is not a specification. No specification seems to be publicly available
++  for the LZO stream format. This document describes what input format the LZO
++  decompressor as implemented in the Linux kernel understands. The file subject
++  of this analysis is lib/lzo/lzo1x_decompress_safe.c. No analysis was made on
++  the compressor nor on any other implementations though it seems likely that
++  the format matches the standard one. The purpose of this document is to
++  better understand what the code does in order to propose more efficient fixes
++  for future bug reports.
++
++Description
++
++  The stream is composed of a series of instructions, operands, and data. The
++  instructions consist in a few bits representing an opcode, and bits forming
++  the operands for the instruction, whose size and position depend on the
++  opcode and on the number of literals copied by previous instruction. The
++  operands are used to indicate :
++
++    - a distance when copying data from the dictionary (past output buffer)
++    - a length (number of bytes to copy from dictionary)
++    - the number of literals to copy, which is retained in variable "state"
++      as a piece of information for next instructions.
++
++  Optionally depending on the opcode and operands, extra data may follow. These
++  extra data can be a complement for the operand (eg: a length or a distance
++  encoded on larger values), or a literal to be copied to the output buffer.
++
++  The first byte of the block follows a different encoding from other bytes, it
++  seems to be optimized for literal use only, since there is no dictionary yet
++  prior to that byte.
++
++  Lengths are always encoded on a variable size starting with a small number
++  of bits in the operand. If the number of bits isn't enough to represent the
++  length, up to 255 may be added in increments by consuming more bytes with a
++  rate of at most 255 per extra byte (thus the compression ratio cannot exceed
++  around 255:1). The variable length encoding using #bits is always the same :
++
++       length = byte & ((1 << #bits) - 1)
++       if (!length) {
++               length = ((1 << #bits) - 1)
++               length += 255*(number of zero bytes)
++               length += first-non-zero-byte
++       }
++       length += constant (generally 2 or 3)
++
++  For references to the dictionary, distances are relative to the output
++  pointer. Distances are encoded using very few bits belonging to certain
++  ranges, resulting in multiple copy instructions using different encodings.
++  Certain encodings involve one extra byte, others involve two extra bytes
++  forming a little-endian 16-bit quantity (marked LE16 below).
++
++  After any instruction except the large literal copy, 0, 1, 2 or 3 literals
++  are copied before starting the next instruction. The number of literals that
++  were copied may change the meaning and behaviour of the next instruction. In
++  practice, only one instruction needs to know whether 0, less than 4, or more
++  literals were copied. This is the information stored in the <state> variable
++  in this implementation. This number of immediate literals to be copied is
++  generally encoded in the last two bits of the instruction but may also be
++  taken from the last two bits of an extra operand (eg: distance).
++
++  End of stream is declared when a block copy of distance 0 is seen. Only one
++  instruction may encode this distance (0001HLLL), it takes one LE16 operand
++  for the distance, thus requiring 3 bytes.
++
++  IMPORTANT NOTE : in the code some length checks are missing because certain
++  instructions are called under the assumption that a certain number of bytes
++  follow because it has already been garanteed before parsing the instructions.
++  They just have to "refill" this credit if they consume extra bytes. This is
++  an implementation design choice independant on the algorithm or encoding.
++
++Byte sequences
++
++  First byte encoding :
++
++      0..17   : follow regular instruction encoding, see below. It is worth
++                noting that codes 16 and 17 will represent a block copy from
++                the dictionary which is empty, and that they will always be
++                invalid at this place.
++
++      18..21  : copy 0..3 literals
++                state = (byte - 17) = 0..3  [ copy <state> literals ]
++                skip byte
++
++      22..255 : copy literal string
++                length = (byte - 17) = 4..238
++                state = 4 [ don't copy extra literals ]
++                skip byte
++
++  Instruction encoding :
++
++      0 0 0 0 X X X X  (0..15)
++        Depends on the number of literals copied by the last instruction.
++        If last instruction did not copy any literal (state == 0), this
++        encoding will be a copy of 4 or more literal, and must be interpreted
++        like this :
++
++           0 0 0 0 L L L L  (0..15)  : copy long literal string
++           length = 3 + (L ?: 15 + (zero_bytes * 255) + non_zero_byte)
++           state = 4  (no extra literals are copied)
++
++        If last instruction used to copy between 1 to 3 literals (encoded in
++        the instruction's opcode or distance), the instruction is a copy of a
++        2-byte block from the dictionary within a 1kB distance. It is worth
++        noting that this instruction provides little savings since it uses 2
++        bytes to encode a copy of 2 other bytes but it encodes the number of
++        following literals for free. It must be interpreted like this :
++
++           0 0 0 0 D D S S  (0..15)  : copy 2 bytes from <= 1kB distance
++           length = 2
++           state = S (copy S literals after this block)
++         Always followed by exactly one byte : H H H H H H H H
++           distance = (H << 2) + D + 1
++
++        If last instruction used to copy 4 or more literals (as detected by
++        state == 4), the instruction becomes a copy of a 3-byte block from the
++        dictionary from a 2..3kB distance, and must be interpreted like this :
++
++           0 0 0 0 D D S S  (0..15)  : copy 3 bytes from 2..3 kB distance
++           length = 3
++           state = S (copy S literals after this block)
++         Always followed by exactly one byte : H H H H H H H H
++           distance = (H << 2) + D + 2049
++
++      0 0 0 1 H L L L  (16..31)
++           Copy of a block within 16..48kB distance (preferably less than 10B)
++           length = 2 + (L ?: 7 + (zero_bytes * 255) + non_zero_byte)
++        Always followed by exactly one LE16 :  D D D D D D D D : D D D D D D S S
++           distance = 16384 + (H << 14) + D
++           state = S (copy S literals after this block)
++           End of stream is reached if distance == 16384
++
++      0 0 1 L L L L L  (32..63)
++           Copy of small block within 16kB distance (preferably less than 34B)
++           length = 2 + (L ?: 31 + (zero_bytes * 255) + non_zero_byte)
++        Always followed by exactly one LE16 :  D D D D D D D D : D D D D D D S S
++           distance = D + 1
++           state = S (copy S literals after this block)
++
++      0 1 L D D D S S  (64..127)
++           Copy 3-4 bytes from block within 2kB distance
++           state = S (copy S literals after this block)
++           length = 3 + L
++         Always followed by exactly one byte : H H H H H H H H
++           distance = (H << 3) + D + 1
++
++      1 L L D D D S S  (128..255)
++           Copy 5-8 bytes from block within 2kB distance
++           state = S (copy S literals after this block)
++           length = 5 + L
++         Always followed by exactly one byte : H H H H H H H H
++           distance = (H << 3) + D + 1
++
++Authors
++
++  This document was written by Willy Tarreau <w@1wt.eu> on 2014/07/19 during an
++  analysis of the decompression code available in Linux 3.16-rc5. The code is
++  tricky, it is possible that this document contains mistakes or that a few
++  corner cases were overlooked. In any case, please report any doubt, fix, or
++  proposed updates to the author(s) so that the document can be updated.
diff --git a/queue-3.17/fixing-lease-renewal.patch b/queue-3.17/fixing-lease-renewal.patch
new file mode 100644 (file)
index 0000000..7a311d4
--- /dev/null
@@ -0,0 +1,34 @@
+From 8faaa6d5d48b201527e0451296d9e71d23afb362 Mon Sep 17 00:00:00 2001
+From: Olga Kornievskaia <kolga@netapp.com>
+Date: Wed, 24 Sep 2014 18:11:28 -0400
+Subject: Fixing lease renewal
+
+From: Olga Kornievskaia <kolga@netapp.com>
+
+commit 8faaa6d5d48b201527e0451296d9e71d23afb362 upstream.
+
+Commit c9fdeb28 removed a 'continue' after checking if the lease needs
+to be renewed. However, if client hasn't moved, the code falls down to
+starting reboot recovery erroneously (ie., sends open reclaim and gets
+back stale_clientid error) before recovering from getting stale_clientid
+on the renew operation.
+
+Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
+Fixes: c9fdeb280b8c (NFS: Add basic migration support to state manager thread)
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/nfs4state.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/nfs/nfs4state.c
++++ b/fs/nfs/nfs4state.c
+@@ -2345,6 +2345,7 @@ static void nfs4_state_manager(struct nf
+                       status = nfs4_check_lease(clp);
+                       if (status < 0)
+                               goto out_error;
++                      continue;
+               }
+               if (test_and_clear_bit(NFS4CLNT_MOVED, &clp->cl_state)) {
diff --git a/queue-3.17/hid-wacom-remove-report_id-from-wacom_get_report-interface.patch b/queue-3.17/hid-wacom-remove-report_id-from-wacom_get_report-interface.patch
new file mode 100644 (file)
index 0000000..ee11b1d
--- /dev/null
@@ -0,0 +1,48 @@
+From c64d883476812783e0400d37028756151d103e5c Mon Sep 17 00:00:00 2001
+From: Ping Cheng <pinglinux@gmail.com>
+Date: Wed, 10 Sep 2014 12:41:04 -0700
+Subject: HID: wacom - remove report_id from wacom_get_report interface
+
+From: Ping Cheng <pinglinux@gmail.com>
+
+commit c64d883476812783e0400d37028756151d103e5c upstream.
+
+It is assigned in buf[0] anyway.
+
+Signed-off-by: Ping Cheng <pingc@wacom.com>
+Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/wacom_sys.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/hid/wacom_sys.c
++++ b/drivers/hid/wacom_sys.c
+@@ -23,13 +23,13 @@
+ #define WAC_CMD_ICON_BT_XFER  0x26
+ #define WAC_CMD_RETRIES               10
+-static int wacom_get_report(struct hid_device *hdev, u8 type, u8 id,
+-                          void *buf, size_t size, unsigned int retries)
++static int wacom_get_report(struct hid_device *hdev, u8 type, u8 *buf,
++                          size_t size, unsigned int retries)
+ {
+       int retval;
+       do {
+-              retval = hid_hw_raw_request(hdev, id, buf, size, type,
++              retval = hid_hw_raw_request(hdev, buf[0], buf, size, type,
+                               HID_REQ_GET_REPORT);
+       } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries);
+@@ -255,7 +255,7 @@ static int wacom_set_device_mode(struct
+                                        length, 1);
+               if (error >= 0)
+                       error = wacom_get_report(hdev, HID_FEATURE_REPORT,
+-                                               report_id, rep_data, length, 1);
++                                               rep_data, length, 1);
+       } while ((error < 0 || rep_data[1] != mode) && limit++ < WAC_MSG_RETRIES);
+       kfree(rep_data);
diff --git a/queue-3.17/lzo-check-for-length-overrun-in-variable-length-encoding.patch b/queue-3.17/lzo-check-for-length-overrun-in-variable-length-encoding.patch
new file mode 100644 (file)
index 0000000..75b91e7
--- /dev/null
@@ -0,0 +1,124 @@
+From 72cf90124e87d975d0b2114d930808c58b4c05e4 Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Sat, 27 Sep 2014 12:31:37 +0200
+Subject: lzo: check for length overrun in variable length encoding.
+
+From: Willy Tarreau <w@1wt.eu>
+
+commit 72cf90124e87d975d0b2114d930808c58b4c05e4 upstream.
+
+This fix ensures that we never meet an integer overflow while adding
+255 while parsing a variable length encoding. It works differently from
+commit 206a81c ("lzo: properly check for overruns") because instead of
+ensuring that we don't overrun the input, which is tricky to guarantee
+due to many assumptions in the code, it simply checks that the cumulated
+number of 255 read cannot overflow by bounding this number.
+
+The MAX_255_COUNT is the maximum number of times we can add 255 to a base
+count without overflowing an integer. The multiply will overflow when
+multiplying 255 by more than MAXINT/255. The sum will overflow earlier
+depending on the base count. Since the base count is taken from a u8
+and a few bits, it is safe to assume that it will always be lower than
+or equal to 2*255, thus we can always prevent any overflow by accepting
+two less 255 steps.
+
+This patch also reduces the CPU overhead and actually increases performance
+by 1.1% compared to the initial code, while the previous fix costs 3.1%
+(measured on x86_64).
+
+The fix needs to be backported to all currently supported stable kernels.
+
+Reported-by: Willem Pinckaers <willem@lekkertech.net>
+Cc: "Don A. Bailey" <donb@securitymouse.com>
+Signed-off-by: Willy Tarreau <w@1wt.eu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ lib/lzo/lzo1x_decompress_safe.c |   43 ++++++++++++++++++++++++++++++++++------
+ 1 file changed, 37 insertions(+), 6 deletions(-)
+
+--- a/lib/lzo/lzo1x_decompress_safe.c
++++ b/lib/lzo/lzo1x_decompress_safe.c
+@@ -25,6 +25,16 @@
+ #define NEED_OP(x)      if (!HAVE_OP(x)) goto output_overrun
+ #define TEST_LB(m_pos)  if ((m_pos) < out) goto lookbehind_overrun
++/* This MAX_255_COUNT is the maximum number of times we can add 255 to a base
++ * count without overflowing an integer. The multiply will overflow when
++ * multiplying 255 by more than MAXINT/255. The sum will overflow earlier
++ * depending on the base count. Since the base count is taken from a u8
++ * and a few bits, it is safe to assume that it will always be lower than
++ * or equal to 2*255, thus we can always prevent any overflow by accepting
++ * two less 255 steps. See Documentation/lzo.txt for more information.
++ */
++#define MAX_255_COUNT      ((((size_t)~0) / 255) - 2)
++
+ int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
+                         unsigned char *out, size_t *out_len)
+ {
+@@ -55,12 +65,19 @@ int lzo1x_decompress_safe(const unsigned
+               if (t < 16) {
+                       if (likely(state == 0)) {
+                               if (unlikely(t == 0)) {
++                                      size_t offset;
++                                      const unsigned char *ip_last = ip;
++
+                                       while (unlikely(*ip == 0)) {
+-                                              t += 255;
+                                               ip++;
+                                               NEED_IP(1);
+                                       }
+-                                      t += 15 + *ip++;
++                                      offset = ip - ip_last;
++                                      if (unlikely(offset > MAX_255_COUNT))
++                                              return LZO_E_ERROR;
++
++                                      offset = (offset << 8) - offset;
++                                      t += offset + 15 + *ip++;
+                               }
+                               t += 3;
+ copy_literal_run:
+@@ -116,12 +133,19 @@ copy_literal_run:
+               } else if (t >= 32) {
+                       t = (t & 31) + (3 - 1);
+                       if (unlikely(t == 2)) {
++                              size_t offset;
++                              const unsigned char *ip_last = ip;
++
+                               while (unlikely(*ip == 0)) {
+-                                      t += 255;
+                                       ip++;
+                                       NEED_IP(1);
+                               }
+-                              t += 31 + *ip++;
++                              offset = ip - ip_last;
++                              if (unlikely(offset > MAX_255_COUNT))
++                                      return LZO_E_ERROR;
++
++                              offset = (offset << 8) - offset;
++                              t += offset + 31 + *ip++;
+                               NEED_IP(2);
+                       }
+                       m_pos = op - 1;
+@@ -134,12 +158,19 @@ copy_literal_run:
+                       m_pos -= (t & 8) << 11;
+                       t = (t & 7) + (3 - 1);
+                       if (unlikely(t == 2)) {
++                              size_t offset;
++                              const unsigned char *ip_last = ip;
++
+                               while (unlikely(*ip == 0)) {
+-                                      t += 255;
+                                       ip++;
+                                       NEED_IP(1);
+                               }
+-                              t += 7 + *ip++;
++                              offset = ip - ip_last;
++                              if (unlikely(offset > MAX_255_COUNT))
++                                      return LZO_E_ERROR;
++
++                              offset = (offset << 8) - offset;
++                              t += offset + 7 + *ip++;
+                               NEED_IP(2);
+                       }
+                       next = get_unaligned_le16(ip);
diff --git a/queue-3.17/m68k-disable-restore-interrupts-in-hwreg_present-hwreg_write.patch b/queue-3.17/m68k-disable-restore-interrupts-in-hwreg_present-hwreg_write.patch
new file mode 100644 (file)
index 0000000..cfe1a15
--- /dev/null
@@ -0,0 +1,77 @@
+From e4dc601bf99ccd1c95b7e6eef1d3cf3c4b0d4961 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert@linux-m68k.org>
+Date: Sun, 28 Sep 2014 10:50:06 +0200
+Subject: m68k: Disable/restore interrupts in hwreg_present()/hwreg_write()
+
+From: Geert Uytterhoeven <geert@linux-m68k.org>
+
+commit e4dc601bf99ccd1c95b7e6eef1d3cf3c4b0d4961 upstream.
+
+hwreg_present() and hwreg_write() temporarily change the VBR register to
+another vector table. This table contains a valid bus error handler
+only, all other entries point to arbitrary addresses.
+
+If an interrupt comes in while the temporary table is active, the
+processor will start executing at such an arbitrary address, and the
+kernel will crash.
+
+While most callers run early, before interrupts are enabled, or
+explicitly disable interrupts, Finn Thain pointed out that macsonic has
+one callsite that doesn't, causing intermittent boot crashes.
+There's another unsafe callsite in hilkbd.
+
+Fix this for good by disabling and restoring interrupts inside
+hwreg_present() and hwreg_write().
+
+Explicitly disabling interrupts can be removed from the callsites later.
+
+Reported-by: Finn Thain <fthain@telegraphics.com.au>
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/m68k/mm/hwtest.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/m68k/mm/hwtest.c
++++ b/arch/m68k/mm/hwtest.c
+@@ -28,9 +28,11 @@
+ int hwreg_present( volatile void *regp )
+ {
+     int       ret = 0;
++    unsigned long flags;
+     long      save_sp, save_vbr;
+     long      tmp_vectors[3];
++    local_irq_save(flags);
+     __asm__ __volatile__
+       (       "movec  %/vbr,%2\n\t"
+               "movel  #Lberr1,%4@(8)\n\t"
+@@ -46,6 +48,7 @@ int hwreg_present( volatile void *regp )
+               : "=&d" (ret), "=&r" (save_sp), "=&r" (save_vbr)
+               : "a" (regp), "a" (tmp_vectors)
+                 );
++    local_irq_restore(flags);
+     return( ret );
+ }
+@@ -58,9 +61,11 @@ EXPORT_SYMBOL(hwreg_present);
+ int hwreg_write( volatile void *regp, unsigned short val )
+ {
+       int             ret;
++      unsigned long flags;
+       long    save_sp, save_vbr;
+       long    tmp_vectors[3];
++      local_irq_save(flags);
+       __asm__ __volatile__
+       (       "movec  %/vbr,%2\n\t"
+               "movel  #Lberr2,%4@(8)\n\t"
+@@ -78,6 +83,7 @@ int hwreg_write( volatile void *regp, un
+               : "=&d" (ret), "=&r" (save_sp), "=&r" (save_vbr)
+               : "a" (regp), "a" (tmp_vectors), "g" (val)
+       );
++      local_irq_restore(flags);
+       return( ret );
+ }
diff --git a/queue-3.17/mei-bus-fix-possible-boundaries-violation.patch b/queue-3.17/mei-bus-fix-possible-boundaries-violation.patch
new file mode 100644 (file)
index 0000000..5bb5a74
--- /dev/null
@@ -0,0 +1,33 @@
+From cfda2794b5afe7ce64ee9605c64bef0e56a48125 Mon Sep 17 00:00:00 2001
+From: Alexander Usyskin <alexander.usyskin@intel.com>
+Date: Mon, 25 Aug 2014 16:46:53 +0300
+Subject: mei: bus: fix possible boundaries violation
+
+From: Alexander Usyskin <alexander.usyskin@intel.com>
+
+commit cfda2794b5afe7ce64ee9605c64bef0e56a48125 upstream.
+
+function 'strncpy' will fill whole buffer 'id.name' of fixed size (32)
+with string value and will not leave place for NULL-terminator.
+Possible buffer boundaries violation in following string operations.
+Replace strncpy with strlcpy.
+
+Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
+Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/misc/mei/bus.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/misc/mei/bus.c
++++ b/drivers/misc/mei/bus.c
+@@ -70,7 +70,7 @@ static int mei_cl_device_probe(struct de
+       dev_dbg(dev, "Device probe\n");
+-      strncpy(id.name, dev_name(dev), sizeof(id.name));
++      strlcpy(id.name, dev_name(dev), sizeof(id.name));
+       return driver->probe(device, &id);
+ }
diff --git a/queue-3.17/nfs-fix-a-bogus-warning-in-nfs_generic_pgio.patch b/queue-3.17/nfs-fix-a-bogus-warning-in-nfs_generic_pgio.patch
new file mode 100644 (file)
index 0000000..d212885
--- /dev/null
@@ -0,0 +1,41 @@
+From b8fb9c30f25e45dab5d2cd310ab6913b6861d00f Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Mon, 13 Oct 2014 10:56:12 -0400
+Subject: NFS: Fix a bogus warning in nfs_generic_pgio
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+commit b8fb9c30f25e45dab5d2cd310ab6913b6861d00f upstream.
+
+It is OK for pageused == pagecount in the loop, as long as we don't add
+another entry to the *pages array. Move the test so that it only triggers
+in that case.
+
+Reported-by: Steve Dickson <SteveD@redhat.com>
+Fixes: bba5c1887a92 (nfs: disallow duplicate pages in pgio page vectors)
+Cc: Weston Andros Adamson <dros@primarydata.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/pagelist.c |    7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+--- a/fs/nfs/pagelist.c
++++ b/fs/nfs/pagelist.c
+@@ -744,12 +744,11 @@ int nfs_generic_pgio(struct nfs_pageio_d
+               nfs_list_remove_request(req);
+               nfs_list_add_request(req, &hdr->pages);
+-              if (WARN_ON_ONCE(pageused >= pagecount))
+-                      return nfs_pgio_error(desc, hdr);
+-
+               if (!last_page || last_page != req->wb_page) {
+-                      *pages++ = last_page = req->wb_page;
+                       pageused++;
++                      if (pageused > pagecount)
++                              break;
++                      *pages++ = last_page = req->wb_page;
+               }
+       }
+       if (WARN_ON_ONCE(pageused != pagecount))
diff --git a/queue-3.17/nfs-fix-an-uninitialised-pointer-oops-in-the-writeback-error-path.patch b/queue-3.17/nfs-fix-an-uninitialised-pointer-oops-in-the-writeback-error-path.patch
new file mode 100644 (file)
index 0000000..2158c01
--- /dev/null
@@ -0,0 +1,67 @@
+From 3caa0c6ed754d91b15266abf222498edbef982bd Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Mon, 13 Oct 2014 10:26:43 -0400
+Subject: NFS: Fix an uninitialised pointer Oops in the writeback error path
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+commit 3caa0c6ed754d91b15266abf222498edbef982bd upstream.
+
+SteveD reports the following Oops:
+ RIP: 0010:[<ffffffffa053461d>]  [<ffffffffa053461d>] __put_nfs_open_context+0x1d/0x100 [nfs]
+ RSP: 0018:ffff880fed687b90  EFLAGS: 00010286
+ RAX: 0000000000000024 RBX: 0000000000000000 RCX: 0000000000000006
+ RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
+ RBP: ffff880fed687bc0 R08: 0000000000000092 R09: 000000000000047a
+ R10: 0000000000000000 R11: ffff880fed6878d6 R12: ffff880fed687d20
+ R13: ffff880fed687d20 R14: 0000000000000070 R15: ffffea000aa33ec0
+ FS:  00007fce290f0740(0000) GS:ffff8807ffc60000(0000) knlGS:0000000000000000
+ CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 0000000000000070 CR3: 00000007f2e79000 CR4: 00000000000007e0
+ DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
+ Stack:
+  0000000000000000 ffff880036c5e510 ffff880fed687d20 ffff880fed687d20
+  ffff880036c5e200 ffffea000aa33ec0 ffff880fed687bd0 ffffffffa0534710
+  ffff880fed687be8 ffffffffa053d5f0 ffff880036c5e200 ffff880fed687c08
+ Call Trace:
+  [<ffffffffa0534710>] put_nfs_open_context+0x10/0x20 [nfs]
+  [<ffffffffa053d5f0>] nfs_pgio_data_destroy+0x20/0x40 [nfs]
+  [<ffffffffa053d672>] nfs_pgio_error+0x22/0x40 [nfs]
+  [<ffffffffa053d8f4>] nfs_generic_pgio+0x74/0x2e0 [nfs]
+  [<ffffffffa06b18c3>] pnfs_generic_pg_writepages+0x63/0x210 [nfsv4]
+  [<ffffffffa053d579>] nfs_pageio_doio+0x19/0x50 [nfs]
+  [<ffffffffa053eb84>] nfs_pageio_complete+0x24/0x30 [nfs]
+  [<ffffffffa053cb25>] nfs_direct_write_schedule_iovec+0x115/0x1f0 [nfs]
+  [<ffffffffa053675f>] ? nfs_get_lock_context+0x4f/0x120 [nfs]
+  [<ffffffffa053d252>] nfs_file_direct_write+0x262/0x420 [nfs]
+  [<ffffffffa0532d91>] nfs_file_write+0x131/0x1d0 [nfs]
+  [<ffffffffa0532c60>] ? nfs_need_sync_write.isra.17+0x40/0x40 [nfs]
+  [<ffffffff812127b8>] do_io_submit+0x3b8/0x840
+  [<ffffffff81212c50>] SyS_io_submit+0x10/0x20
+  [<ffffffff81610f29>] system_call_fastpath+0x16/0x1b
+
+This is due to the calls to nfs_pgio_error() in nfs_generic_pgio(), which
+happen before the nfs_pgio_header's open context is referenced in
+nfs_pgio_rpcsetup().
+
+Reported-by: Steve Dickson <SteveD@redhat.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/pagelist.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/nfs/pagelist.c
++++ b/fs/nfs/pagelist.c
+@@ -518,7 +518,8 @@ EXPORT_SYMBOL_GPL(nfs_pgio_header_free);
+  */
+ void nfs_pgio_data_destroy(struct nfs_pgio_header *hdr)
+ {
+-      put_nfs_open_context(hdr->args.context);
++      if (hdr->args.context)
++              put_nfs_open_context(hdr->args.context);
+       if (hdr->page_array.pagevec != hdr->page_array.page_array)
+               kfree(hdr->page_array.pagevec);
+ }
diff --git a/queue-3.17/nfs-fix-duplicate-proc-entries.patch b/queue-3.17/nfs-fix-duplicate-proc-entries.patch
new file mode 100644 (file)
index 0000000..2f468ae
--- /dev/null
@@ -0,0 +1,38 @@
+From 2f3169fb18f4643ac9a6a097a6a6c71f0b2cef75 Mon Sep 17 00:00:00 2001
+From: Fabian Frederick <fabf@skynet.be>
+Date: Wed, 24 Sep 2014 18:56:11 +0200
+Subject: nfs: fix duplicate proc entries
+
+From: Fabian Frederick <fabf@skynet.be>
+
+commit 2f3169fb18f4643ac9a6a097a6a6c71f0b2cef75 upstream.
+
+Commit 65b38851a174
+("NFS: Fix /proc/fs/nfsfs/servers and /proc/fs/nfsfs/volumes")
+
+updated the following function:
+static int nfs_volume_list_open(struct inode *inode, struct file *file)
+
+it used &nfs_server_list_ops instead of &nfs_volume_list_ops
+which means cat /proc/fs/nfsfs/volumes = /proc/fs/nfsfs/servers
+
+Signed-off-by: Fabian Frederick <fabf@skynet.be>
+Fixes: 65b38851a174 (NFS: Fix /proc/fs/nfsfs/servers and...)
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/client.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/nfs/client.c
++++ b/fs/nfs/client.c
+@@ -1318,7 +1318,7 @@ static int nfs_server_list_show(struct s
+  */
+ static int nfs_volume_list_open(struct inode *inode, struct file *file)
+ {
+-      return seq_open_net(inode, file, &nfs_server_list_ops,
++      return seq_open_net(inode, file, &nfs_volume_list_ops,
+                          sizeof(struct seq_net_private));
+ }
diff --git a/queue-3.17/nfsd4-reserve-adequate-space-for-lock-op.patch b/queue-3.17/nfsd4-reserve-adequate-space-for-lock-op.patch
new file mode 100644 (file)
index 0000000..21f4f6d
--- /dev/null
@@ -0,0 +1,46 @@
+From f7b43d0c992c3ec3e8d9285c3fb5e1e0eb0d031a Mon Sep 17 00:00:00 2001
+From: "J. Bruce Fields" <bfields@redhat.com>
+Date: Tue, 12 Aug 2014 11:41:40 -0400
+Subject: nfsd4: reserve adequate space for LOCK op
+
+From: "J. Bruce Fields" <bfields@redhat.com>
+
+commit f7b43d0c992c3ec3e8d9285c3fb5e1e0eb0d031a upstream.
+
+As of  8c7424cff6 "nfsd4: don't try to encode conflicting owner if low
+on space", we permit the server to process a LOCK operation even if
+there might not be space to return the conflicting lockowner, because
+we've made returning the conflicting lockowner optional.
+
+However, the rpc server still wants to know the most we might possibly
+return, so we need to take into account the possible conflicting
+lockowner in the svc_reserve_space() call here.
+
+Symptoms were log messages like "RPC request reserved 88 but used 108".
+
+Fixes: 8c7424cff6 "nfsd4: don't try to encode conflicting owner if low on space"
+Reported-by: Kinglong Mee <kinglongmee@gmail.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfsd/nfs4xdr.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/fs/nfsd/nfs4xdr.c
++++ b/fs/nfsd/nfs4xdr.c
+@@ -1670,6 +1670,14 @@ nfsd4_decode_compound(struct nfsd4_compo
+                       readbytes += nfsd4_max_reply(argp->rqstp, op);
+               } else
+                       max_reply += nfsd4_max_reply(argp->rqstp, op);
++              /*
++               * OP_LOCK may return a conflicting lock.  (Special case
++               * because it will just skip encoding this if it runs
++               * out of xdr buffer space, and it is the only operation
++               * that behaves this way.)
++               */
++              if (op->opnum == OP_LOCK)
++                      max_reply += NFS4_OPAQUE_LIMIT;
+               if (op->status) {
+                       argp->opcnt = i+1;
diff --git a/queue-3.17/nfsv4-fix-lock-recovery-when-create_session-setclientid_confirm-fails.patch b/queue-3.17/nfsv4-fix-lock-recovery-when-create_session-setclientid_confirm-fails.patch
new file mode 100644 (file)
index 0000000..90e8bed
--- /dev/null
@@ -0,0 +1,35 @@
+From a4339b7b686b4acc8b6de2b07d7bacbe3ae44b83 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Sat, 27 Sep 2014 17:02:26 -0400
+Subject: NFSv4: Fix lock recovery when CREATE_SESSION/SETCLIENTID_CONFIRM fails
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+commit a4339b7b686b4acc8b6de2b07d7bacbe3ae44b83 upstream.
+
+If a NFSv4.x server returns NFS4ERR_STALE_CLIENTID in response to a
+CREATE_SESSION or SETCLIENTID_CONFIRM in order to tell us that it rebooted
+a second time, then the client will currently take this to mean that it must
+declare all locks to be stale, and hence ineligible for reboot recovery.
+
+RFC3530 and RFC5661 both suggest that the client should instead rely on the
+server to respond to inelegible open share, lock and delegation reclaim
+requests with NFS4ERR_NO_GRACE in this situation.
+
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/nfs4state.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/fs/nfs/nfs4state.c
++++ b/fs/nfs/nfs4state.c
+@@ -1761,7 +1761,6 @@ static int nfs4_handle_reclaim_lease_err
+               break;
+       case -NFS4ERR_STALE_CLIENTID:
+               clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
+-              nfs4_state_clear_reclaim_reboot(clp);
+               nfs4_state_start_reclaim_reboot(clp);
+               break;
+       case -NFS4ERR_CLID_INUSE:
diff --git a/queue-3.17/nfsv4-fix-open-lock-state-recovery-error-handling.patch b/queue-3.17/nfsv4-fix-open-lock-state-recovery-error-handling.patch
new file mode 100644 (file)
index 0000000..a4c0c32
--- /dev/null
@@ -0,0 +1,71 @@
+From df817ba35736db2d62b07de6f050a4db53492ad8 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Sat, 27 Sep 2014 17:41:51 -0400
+Subject: NFSv4: fix open/lock state recovery error handling
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+commit df817ba35736db2d62b07de6f050a4db53492ad8 upstream.
+
+The current open/lock state recovery unfortunately does not handle errors
+such as NFS4ERR_CONN_NOT_BOUND_TO_SESSION correctly. Instead of looping,
+just proceeds as if the state manager is finished recovering.
+This patch ensures that we loop back, handle higher priority errors
+and complete the open/lock state recovery.
+
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/nfs4state.c |   16 ++++++----------
+ 1 file changed, 6 insertions(+), 10 deletions(-)
+
+--- a/fs/nfs/nfs4state.c
++++ b/fs/nfs/nfs4state.c
+@@ -1705,7 +1705,8 @@ restart:
+                       if (status < 0) {
+                               set_bit(ops->owner_flag_bit, &sp->so_flags);
+                               nfs4_put_state_owner(sp);
+-                              return nfs4_recovery_handle_error(clp, status);
++                              status = nfs4_recovery_handle_error(clp, status);
++                              return (status != 0) ? status : -EAGAIN;
+                       }
+                       nfs4_put_state_owner(sp);
+@@ -1714,7 +1715,7 @@ restart:
+               spin_unlock(&clp->cl_lock);
+       }
+       rcu_read_unlock();
+-      return status;
++      return 0;
+ }
+ static int nfs4_check_lease(struct nfs_client *clp)
+@@ -2366,14 +2367,11 @@ static void nfs4_state_manager(struct nf
+                       section = "reclaim reboot";
+                       status = nfs4_do_reclaim(clp,
+                               clp->cl_mvops->reboot_recovery_ops);
+-                      if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) ||
+-                          test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state))
+-                              continue;
+-                      nfs4_state_end_reclaim_reboot(clp);
+-                      if (test_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state))
++                      if (status == -EAGAIN)
+                               continue;
+                       if (status < 0)
+                               goto out_error;
++                      nfs4_state_end_reclaim_reboot(clp);
+               }
+               /* Now recover expired state... */
+@@ -2381,9 +2379,7 @@ static void nfs4_state_manager(struct nf
+                       section = "reclaim nograce";
+                       status = nfs4_do_reclaim(clp,
+                               clp->cl_mvops->nograce_recovery_ops);
+-                      if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) ||
+-                          test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state) ||
+-                          test_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state))
++                      if (status == -EAGAIN)
+                               continue;
+                       if (status < 0)
+                               goto out_error;
diff --git a/queue-3.17/nfsv4.1-fix-an-nfsv4.1-state-renewal-regression.patch b/queue-3.17/nfsv4.1-fix-an-nfsv4.1-state-renewal-regression.patch
new file mode 100644 (file)
index 0000000..5b20ff4
--- /dev/null
@@ -0,0 +1,91 @@
+From d1f456b0b9545f1606a54cd17c20775f159bd2ce Mon Sep 17 00:00:00 2001
+From: Andy Adamson <andros@netapp.com>
+Date: Mon, 29 Sep 2014 12:31:57 -0400
+Subject: NFSv4.1: Fix an NFSv4.1 state renewal regression
+
+From: Andy Adamson <andros@netapp.com>
+
+commit d1f456b0b9545f1606a54cd17c20775f159bd2ce upstream.
+
+Commit 2f60ea6b8ced ("NFSv4: The NFSv4.0 client must send RENEW calls if it holds a delegation") set the NFS4_RENEW_TIMEOUT flag in nfs4_renew_state, and does
+not put an nfs41_proc_async_sequence call, the NFSv4.1 lease renewal heartbeat
+call, on the wire to renew the NFSv4.1 state if the flag was not set.
+
+The NFS4_RENEW_TIMEOUT flag is set when "now" is after the last renewal
+(cl_last_renewal) plus the lease time divided by 3. This is arbitrary and
+sometimes does the following:
+
+In normal operation, the only way a future state renewal call is put on the
+wire is via a call to nfs4_schedule_state_renewal, which schedules a
+nfs4_renew_state workqueue task. nfs4_renew_state determines if the
+NFS4_RENEW_TIMEOUT should be set, and the calls nfs41_proc_async_sequence,
+which only gets sent if the NFS4_RENEW_TIMEOUT flag is set.
+Then the nfs41_proc_async_sequence rpc_release function schedules
+another state remewal via nfs4_schedule_state_renewal.
+
+Without this change we can get into a state where an application stops
+accessing the NFSv4.1 share, state renewal calls stop due to the
+NFS4_RENEW_TIMEOUT flag _not_ being set. The only way to recover
+from this situation is with a clientid re-establishment, once the application
+resumes and the server has timed out the lease and so returns
+NFS4ERR_BAD_SESSION on the subsequent SEQUENCE operation.
+
+An example application:
+open, lock, write a file.
+
+sleep for 6 * lease (could be less)
+
+ulock, close.
+
+In the above example with NFSv4.1 delegations enabled, without this change,
+there are no OP_SEQUENCE state renewal calls during the sleep, and the
+clientid is recovered due to lease expiration on the close.
+
+This issue does not occur with NFSv4.1 delegations disabled, nor with
+NFSv4.0, with or without delegations enabled.
+
+Signed-off-by: Andy Adamson <andros@netapp.com>
+Link: http://lkml.kernel.org/r/1411486536-23401-1-git-send-email-andros@netapp.com
+Fixes: 2f60ea6b8ced (NFSv4: The NFSv4.0 client must send RENEW calls...)
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/nfs4proc.c   |    2 +-
+ fs/nfs/nfs4renewd.c |   12 ++++++++++--
+ 2 files changed, 11 insertions(+), 3 deletions(-)
+
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -7353,7 +7353,7 @@ static int nfs41_proc_async_sequence(str
+       int ret = 0;
+       if ((renew_flags & NFS4_RENEW_TIMEOUT) == 0)
+-              return 0;
++              return -EAGAIN;
+       task = _nfs41_proc_sequence(clp, cred, false);
+       if (IS_ERR(task))
+               ret = PTR_ERR(task);
+--- a/fs/nfs/nfs4renewd.c
++++ b/fs/nfs/nfs4renewd.c
+@@ -88,10 +88,18 @@ nfs4_renew_state(struct work_struct *wor
+                       }
+                       nfs_expire_all_delegations(clp);
+               } else {
++                      int ret;
++
+                       /* Queue an asynchronous RENEW. */
+-                      ops->sched_state_renewal(clp, cred, renew_flags);
++                      ret = ops->sched_state_renewal(clp, cred, renew_flags);
+                       put_rpccred(cred);
+-                      goto out_exp;
++                      switch (ret) {
++                      default:
++                              goto out_exp;
++                      case -EAGAIN:
++                      case -ENOMEM:
++                              break;
++                      }
+               }
+       } else {
+               dprintk("%s: failed to call renewd. Reason: lease not expired \n",
diff --git a/queue-3.17/nfsv4.1-pnfs-replace-broken-pnfs_put_lseg_async.patch b/queue-3.17/nfsv4.1-pnfs-replace-broken-pnfs_put_lseg_async.patch
new file mode 100644 (file)
index 0000000..3980bf4
--- /dev/null
@@ -0,0 +1,112 @@
+From 6543f803670530f6aa93790d9fa116d8395a537d Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Wed, 8 Oct 2014 16:39:12 -0400
+Subject: NFSv4.1/pnfs: replace broken pnfs_put_lseg_async
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+commit 6543f803670530f6aa93790d9fa116d8395a537d upstream.
+
+You cannot call pnfs_put_lseg_async() more than once per lseg, so it
+is really an inappropriate way to deal with a refcount issue.
+
+Instead, replace it with a function that decrements the refcount, and
+puts the final 'free' operation (which is incompatible with locks) on
+the workqueue.
+
+Cc: Weston Andros Adamson <dros@primarydata.com>
+Fixes: e6cf82d1830f: pnfs: add pnfs_put_lseg_async
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/filelayout/filelayout.c |    2 +-
+ fs/nfs/pnfs.c                  |   33 +++++++++++++++++++++++++++------
+ fs/nfs/pnfs.h                  |    6 +-----
+ 3 files changed, 29 insertions(+), 12 deletions(-)
+
+--- a/fs/nfs/filelayout/filelayout.c
++++ b/fs/nfs/filelayout/filelayout.c
+@@ -1031,7 +1031,7 @@ filelayout_clear_request_commit(struct n
+       }
+ out:
+       nfs_request_remove_commit_list(req, cinfo);
+-      pnfs_put_lseg_async(freeme);
++      pnfs_put_lseg_locked(freeme);
+ }
+ static void
+--- a/fs/nfs/pnfs.c
++++ b/fs/nfs/pnfs.c
+@@ -361,22 +361,43 @@ pnfs_put_lseg(struct pnfs_layout_segment
+ }
+ EXPORT_SYMBOL_GPL(pnfs_put_lseg);
+-static void pnfs_put_lseg_async_work(struct work_struct *work)
++static void pnfs_free_lseg_async_work(struct work_struct *work)
+ {
+       struct pnfs_layout_segment *lseg;
++      struct pnfs_layout_hdr *lo;
+       lseg = container_of(work, struct pnfs_layout_segment, pls_work);
++      lo = lseg->pls_layout;
+-      pnfs_put_lseg(lseg);
++      pnfs_free_lseg(lseg);
++      pnfs_put_layout_hdr(lo);
+ }
+-void
+-pnfs_put_lseg_async(struct pnfs_layout_segment *lseg)
++static void pnfs_free_lseg_async(struct pnfs_layout_segment *lseg)
+ {
+-      INIT_WORK(&lseg->pls_work, pnfs_put_lseg_async_work);
++      INIT_WORK(&lseg->pls_work, pnfs_free_lseg_async_work);
+       schedule_work(&lseg->pls_work);
+ }
+-EXPORT_SYMBOL_GPL(pnfs_put_lseg_async);
++
++void
++pnfs_put_lseg_locked(struct pnfs_layout_segment *lseg)
++{
++      if (!lseg)
++              return;
++
++      assert_spin_locked(&lseg->pls_layout->plh_inode->i_lock);
++
++      dprintk("%s: lseg %p ref %d valid %d\n", __func__, lseg,
++              atomic_read(&lseg->pls_refcount),
++              test_bit(NFS_LSEG_VALID, &lseg->pls_flags));
++      if (atomic_dec_and_test(&lseg->pls_refcount)) {
++              struct pnfs_layout_hdr *lo = lseg->pls_layout;
++              pnfs_get_layout_hdr(lo);
++              pnfs_layout_remove_lseg(lo, lseg);
++              pnfs_free_lseg_async(lseg);
++      }
++}
++EXPORT_SYMBOL_GPL(pnfs_put_lseg_locked);
+ static u64
+ end_offset(u64 start, u64 len)
+--- a/fs/nfs/pnfs.h
++++ b/fs/nfs/pnfs.h
+@@ -183,7 +183,7 @@ extern int nfs4_proc_layoutreturn(struct
+ /* pnfs.c */
+ void pnfs_get_layout_hdr(struct pnfs_layout_hdr *lo);
+ void pnfs_put_lseg(struct pnfs_layout_segment *lseg);
+-void pnfs_put_lseg_async(struct pnfs_layout_segment *lseg);
++void pnfs_put_lseg_locked(struct pnfs_layout_segment *lseg);
+ void set_pnfs_layoutdriver(struct nfs_server *, const struct nfs_fh *, u32);
+ void unset_pnfs_layoutdriver(struct nfs_server *);
+@@ -422,10 +422,6 @@ static inline void pnfs_put_lseg(struct
+ {
+ }
+-static inline void pnfs_put_lseg_async(struct pnfs_layout_segment *lseg)
+-{
+-}
+-
+ static inline int pnfs_return_layout(struct inode *ino)
+ {
+       return 0;
diff --git a/queue-3.17/revert-lzo-properly-check-for-overruns.patch b/queue-3.17/revert-lzo-properly-check-for-overruns.patch
new file mode 100644 (file)
index 0000000..00937da
--- /dev/null
@@ -0,0 +1,181 @@
+From af958a38a60c7ca3d8a39c918c1baa2ff7b6b233 Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Sat, 27 Sep 2014 12:31:36 +0200
+Subject: Revert "lzo: properly check for overruns"
+
+From: Willy Tarreau <w@1wt.eu>
+
+commit af958a38a60c7ca3d8a39c918c1baa2ff7b6b233 upstream.
+
+This reverts commit 206a81c ("lzo: properly check for overruns").
+
+As analysed by Willem Pinckaers, this fix is still incomplete on
+certain rare corner cases, and it is easier to restart from the
+original code.
+
+Reported-by: Willem Pinckaers <willem@lekkertech.net>
+Cc: "Don A. Bailey" <donb@securitymouse.com>
+Signed-off-by: Willy Tarreau <w@1wt.eu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ lib/lzo/lzo1x_decompress_safe.c |   62 +++++++++++++---------------------------
+ 1 file changed, 21 insertions(+), 41 deletions(-)
+
+--- a/lib/lzo/lzo1x_decompress_safe.c
++++ b/lib/lzo/lzo1x_decompress_safe.c
+@@ -19,31 +19,11 @@
+ #include <linux/lzo.h>
+ #include "lzodefs.h"
+-#define HAVE_IP(t, x)                                 \
+-      (((size_t)(ip_end - ip) >= (size_t)(t + x)) &&  \
+-       (((t + x) >= t) && ((t + x) >= x)))
+-
+-#define HAVE_OP(t, x)                                 \
+-      (((size_t)(op_end - op) >= (size_t)(t + x)) &&  \
+-       (((t + x) >= t) && ((t + x) >= x)))
+-
+-#define NEED_IP(t, x)                                 \
+-      do {                                            \
+-              if (!HAVE_IP(t, x))                     \
+-                      goto input_overrun;             \
+-      } while (0)
+-
+-#define NEED_OP(t, x)                                 \
+-      do {                                            \
+-              if (!HAVE_OP(t, x))                     \
+-                      goto output_overrun;            \
+-      } while (0)
+-
+-#define TEST_LB(m_pos)                                        \
+-      do {                                            \
+-              if ((m_pos) < out)                      \
+-                      goto lookbehind_overrun;        \
+-      } while (0)
++#define HAVE_IP(x)      ((size_t)(ip_end - ip) >= (size_t)(x))
++#define HAVE_OP(x)      ((size_t)(op_end - op) >= (size_t)(x))
++#define NEED_IP(x)      if (!HAVE_IP(x)) goto input_overrun
++#define NEED_OP(x)      if (!HAVE_OP(x)) goto output_overrun
++#define TEST_LB(m_pos)  if ((m_pos) < out) goto lookbehind_overrun
+ int lzo1x_decompress_safe(const unsigned char *in, size_t in_len,
+                         unsigned char *out, size_t *out_len)
+@@ -78,14 +58,14 @@ int lzo1x_decompress_safe(const unsigned
+                                       while (unlikely(*ip == 0)) {
+                                               t += 255;
+                                               ip++;
+-                                              NEED_IP(1, 0);
++                                              NEED_IP(1);
+                                       }
+                                       t += 15 + *ip++;
+                               }
+                               t += 3;
+ copy_literal_run:
+ #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+-                              if (likely(HAVE_IP(t, 15) && HAVE_OP(t, 15))) {
++                              if (likely(HAVE_IP(t + 15) && HAVE_OP(t + 15))) {
+                                       const unsigned char *ie = ip + t;
+                                       unsigned char *oe = op + t;
+                                       do {
+@@ -101,8 +81,8 @@ copy_literal_run:
+                               } else
+ #endif
+                               {
+-                                      NEED_OP(t, 0);
+-                                      NEED_IP(t, 3);
++                                      NEED_OP(t);
++                                      NEED_IP(t + 3);
+                                       do {
+                                               *op++ = *ip++;
+                                       } while (--t > 0);
+@@ -115,7 +95,7 @@ copy_literal_run:
+                               m_pos -= t >> 2;
+                               m_pos -= *ip++ << 2;
+                               TEST_LB(m_pos);
+-                              NEED_OP(2, 0);
++                              NEED_OP(2);
+                               op[0] = m_pos[0];
+                               op[1] = m_pos[1];
+                               op += 2;
+@@ -139,10 +119,10 @@ copy_literal_run:
+                               while (unlikely(*ip == 0)) {
+                                       t += 255;
+                                       ip++;
+-                                      NEED_IP(1, 0);
++                                      NEED_IP(1);
+                               }
+                               t += 31 + *ip++;
+-                              NEED_IP(2, 0);
++                              NEED_IP(2);
+                       }
+                       m_pos = op - 1;
+                       next = get_unaligned_le16(ip);
+@@ -157,10 +137,10 @@ copy_literal_run:
+                               while (unlikely(*ip == 0)) {
+                                       t += 255;
+                                       ip++;
+-                                      NEED_IP(1, 0);
++                                      NEED_IP(1);
+                               }
+                               t += 7 + *ip++;
+-                              NEED_IP(2, 0);
++                              NEED_IP(2);
+                       }
+                       next = get_unaligned_le16(ip);
+                       ip += 2;
+@@ -174,7 +154,7 @@ copy_literal_run:
+ #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+               if (op - m_pos >= 8) {
+                       unsigned char *oe = op + t;
+-                      if (likely(HAVE_OP(t, 15))) {
++                      if (likely(HAVE_OP(t + 15))) {
+                               do {
+                                       COPY8(op, m_pos);
+                                       op += 8;
+@@ -184,7 +164,7 @@ copy_literal_run:
+                                       m_pos += 8;
+                               } while (op < oe);
+                               op = oe;
+-                              if (HAVE_IP(6, 0)) {
++                              if (HAVE_IP(6)) {
+                                       state = next;
+                                       COPY4(op, ip);
+                                       op += next;
+@@ -192,7 +172,7 @@ copy_literal_run:
+                                       continue;
+                               }
+                       } else {
+-                              NEED_OP(t, 0);
++                              NEED_OP(t);
+                               do {
+                                       *op++ = *m_pos++;
+                               } while (op < oe);
+@@ -201,7 +181,7 @@ copy_literal_run:
+ #endif
+               {
+                       unsigned char *oe = op + t;
+-                      NEED_OP(t, 0);
++                      NEED_OP(t);
+                       op[0] = m_pos[0];
+                       op[1] = m_pos[1];
+                       op += 2;
+@@ -214,15 +194,15 @@ match_next:
+               state = next;
+               t = next;
+ #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+-              if (likely(HAVE_IP(6, 0) && HAVE_OP(4, 0))) {
++              if (likely(HAVE_IP(6) && HAVE_OP(4))) {
+                       COPY4(op, ip);
+                       op += t;
+                       ip += t;
+               } else
+ #endif
+               {
+-                      NEED_IP(t, 3);
+-                      NEED_OP(t, 0);
++                      NEED_IP(t + 3);
++                      NEED_OP(t);
+                       while (t > 0) {
+                               *op++ = *ip++;
+                               t--;
index 5c259dd868dbbf1730ecbde6e274fbc72abfc2d9..cfd5c2ec2c0e209c1661eae5323bc26fc7e61972 100644 (file)
@@ -23,6 +23,7 @@ x86-intel-quark-switch-off-cr4.pge-so-tlb-flush-uses-cr3-instead.patch
 spi-dw-mid-respect-8-bit-mode.patch
 spi-rockchip-fix-bug-that-cause-the-failure-to-read-data-in-dma-mode.patch
 spi-dw-mid-check-that-dma-was-inited-before-exit.patch
+hid-wacom-remove-report_id-from-wacom_get_report-interface.patch
 hid-wacom-fix-timeout-on-probe-for-some-wacoms.patch
 hid-rmi-check-sanity-of-the-incoming-report.patch
 mpc85xx_edac-make-l2-interrupt-shared-too.patch
@@ -47,3 +48,18 @@ drivers-hv-vmbus-cleanup-vmbus_close_internal.patch
 drivers-hv-vmbus-cleanup-vmbus_establish_gpadl.patch
 drivers-hv-vmbus-fix-a-bug-in-vmbus_open.patch
 drivers-hv-vmbus-cleanup-hv_post_message.patch
+mei-bus-fix-possible-boundaries-violation.patch
+m68k-disable-restore-interrupts-in-hwreg_present-hwreg_write.patch
+fixing-lease-renewal.patch
+documentation-lzo-document-part-of-the-encoding.patch
+revert-lzo-properly-check-for-overruns.patch
+lzo-check-for-length-overrun-in-variable-length-encoding.patch
+tty-omap-serial-fix-division-by-zero.patch
+nfs-fix-duplicate-proc-entries.patch
+nfsv4-fix-lock-recovery-when-create_session-setclientid_confirm-fails.patch
+nfsv4-fix-open-lock-state-recovery-error-handling.patch
+nfsv4.1-fix-an-nfsv4.1-state-renewal-regression.patch
+nfsd4-reserve-adequate-space-for-lock-op.patch
+nfs-fix-an-uninitialised-pointer-oops-in-the-writeback-error-path.patch
+nfs-fix-a-bogus-warning-in-nfs_generic_pgio.patch
+nfsv4.1-pnfs-replace-broken-pnfs_put_lseg_async.patch
diff --git a/queue-3.17/tty-omap-serial-fix-division-by-zero.patch b/queue-3.17/tty-omap-serial-fix-division-by-zero.patch
new file mode 100644 (file)
index 0000000..d7dbd9b
--- /dev/null
@@ -0,0 +1,58 @@
+From dc3187564e61260f49eceb21a4e7eb5e4428e90a Mon Sep 17 00:00:00 2001
+From: Frans Klaver <frans.klaver@xsens.com>
+Date: Thu, 25 Sep 2014 11:19:51 +0200
+Subject: tty: omap-serial: fix division by zero
+
+From: Frans Klaver <frans.klaver@xsens.com>
+
+commit dc3187564e61260f49eceb21a4e7eb5e4428e90a upstream.
+
+If the chosen baud rate is large enough (e.g. 3.5 megabaud), the
+calculated n values in serial_omap_is_baud_mode16() may become 0. This
+causes a division by zero when calculating the difference between
+calculated and desired baud rates. To prevent this, cap the n13 and n16
+values on 1.
+
+Division by zero in kernel.
+[<c00132e0>] (unwind_backtrace) from [<c00112ec>] (show_stack+0x10/0x14)
+[<c00112ec>] (show_stack) from [<c01ed7bc>] (Ldiv0+0x8/0x10)
+[<c01ed7bc>] (Ldiv0) from [<c023805c>] (serial_omap_baud_is_mode16+0x4c/0x68)
+[<c023805c>] (serial_omap_baud_is_mode16) from [<c02396b4>] (serial_omap_set_termios+0x90/0x8d8)
+[<c02396b4>] (serial_omap_set_termios) from [<c0230a0c>] (uart_change_speed+0xa4/0xa8)
+[<c0230a0c>] (uart_change_speed) from [<c0231798>] (uart_set_termios+0xa0/0x1fc)
+[<c0231798>] (uart_set_termios) from [<c022bb44>] (tty_set_termios+0x248/0x2c0)
+[<c022bb44>] (tty_set_termios) from [<c022c17c>] (set_termios+0x248/0x29c)
+[<c022c17c>] (set_termios) from [<c022c3e4>] (tty_mode_ioctl+0x1c8/0x4e8)
+[<c022c3e4>] (tty_mode_ioctl) from [<c0227e70>] (tty_ioctl+0xa94/0xb18)
+[<c0227e70>] (tty_ioctl) from [<c00cf45c>] (do_vfs_ioctl+0x4a0/0x560)
+[<c00cf45c>] (do_vfs_ioctl) from [<c00cf568>] (SyS_ioctl+0x4c/0x74)
+[<c00cf568>] (SyS_ioctl) from [<c000e480>] (ret_fast_syscall+0x0/0x30)
+
+Signed-off-by: Frans Klaver <frans.klaver@xsens.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/omap-serial.c |   12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/tty/serial/omap-serial.c
++++ b/drivers/tty/serial/omap-serial.c
+@@ -254,8 +254,16 @@ serial_omap_baud_is_mode16(struct uart_p
+ {
+       unsigned int n13 = port->uartclk / (13 * baud);
+       unsigned int n16 = port->uartclk / (16 * baud);
+-      int baudAbsDiff13 = baud - (port->uartclk / (13 * n13));
+-      int baudAbsDiff16 = baud - (port->uartclk / (16 * n16));
++      int baudAbsDiff13;
++      int baudAbsDiff16;
++
++      if (n13 == 0)
++              n13 = 1;
++      if (n16 == 0)
++              n16 = 1;
++
++      baudAbsDiff13 = baud - (port->uartclk / (13 * n13));
++      baudAbsDiff16 = baud - (port->uartclk / (16 * n16));
+       if (baudAbsDiff13 < 0)
+               baudAbsDiff13 = -baudAbsDiff13;
+       if (baudAbsDiff16 < 0)