]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 8 Mar 2017 15:40:08 +0000 (16:40 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 8 Mar 2017 15:40:08 +0000 (16:40 +0100)
added patches:
block-loop-fix-race-between-i-o-and-set_status.patch
ext4-do-not-polute-the-extents-cache-while-shifting-extents.patch
ext4-fix-data-corruption-in-data-journal-mode.patch
ext4-fix-inline-data-error-paths.patch
ext4-fix-use-after-iput-when-fscrypt-contexts-are-inconsistent.patch
ext4-include-forgotten-start-block-on-fallocate-insert-range.patch
ext4-preserve-the-needs_recovery-flag-when-the-journal-is-aborted.patch
ext4-return-erofs-if-device-is-r-o-and-journal-replay-is-needed.patch
ext4-trim-allocation-requests-to-group-size.patch
jbd2-don-t-leak-modified-metadata-buffers-on-an-aborted-journal.patch
loop-fix-lo_flags_partscan-hang.patch
mei-remove-support-for-broken-parallel-read.patch
samples-seccomp-fix-64-bit-comparison-macros.patch

14 files changed:
queue-4.9/block-loop-fix-race-between-i-o-and-set_status.patch [new file with mode: 0644]
queue-4.9/ext4-do-not-polute-the-extents-cache-while-shifting-extents.patch [new file with mode: 0644]
queue-4.9/ext4-fix-data-corruption-in-data-journal-mode.patch [new file with mode: 0644]
queue-4.9/ext4-fix-inline-data-error-paths.patch [new file with mode: 0644]
queue-4.9/ext4-fix-use-after-iput-when-fscrypt-contexts-are-inconsistent.patch [new file with mode: 0644]
queue-4.9/ext4-include-forgotten-start-block-on-fallocate-insert-range.patch [new file with mode: 0644]
queue-4.9/ext4-preserve-the-needs_recovery-flag-when-the-journal-is-aborted.patch [new file with mode: 0644]
queue-4.9/ext4-return-erofs-if-device-is-r-o-and-journal-replay-is-needed.patch [new file with mode: 0644]
queue-4.9/ext4-trim-allocation-requests-to-group-size.patch [new file with mode: 0644]
queue-4.9/jbd2-don-t-leak-modified-metadata-buffers-on-an-aborted-journal.patch [new file with mode: 0644]
queue-4.9/loop-fix-lo_flags_partscan-hang.patch [new file with mode: 0644]
queue-4.9/mei-remove-support-for-broken-parallel-read.patch [new file with mode: 0644]
queue-4.9/samples-seccomp-fix-64-bit-comparison-macros.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/block-loop-fix-race-between-i-o-and-set_status.patch b/queue-4.9/block-loop-fix-race-between-i-o-and-set_status.patch
new file mode 100644 (file)
index 0000000..dd480eb
--- /dev/null
@@ -0,0 +1,100 @@
+From ecdd09597a57251323b0de50e3d45e69298c4a83 Mon Sep 17 00:00:00 2001
+From: Ming Lei <tom.leiming@gmail.com>
+Date: Sat, 11 Feb 2017 11:40:45 +0800
+Subject: block/loop: fix race between I/O and set_status
+
+From: Ming Lei <tom.leiming@gmail.com>
+
+commit ecdd09597a57251323b0de50e3d45e69298c4a83 upstream.
+
+Inside set_status, transfer need to setup again, so
+we have to drain IO before the transition, otherwise
+oops may be triggered like the following:
+
+       divide error: 0000 [#1] SMP KASAN
+       CPU: 0 PID: 2935 Comm: loop7 Not tainted 4.10.0-rc7+ #213
+       Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs
+       01/01/2011
+       task: ffff88006ba1e840 task.stack: ffff880067338000
+       RIP: 0010:transfer_xor+0x1d1/0x440 drivers/block/loop.c:110
+       RSP: 0018:ffff88006733f108 EFLAGS: 00010246
+       RAX: 0000000000000000 RBX: ffff8800688d7000 RCX: 0000000000000059
+       RDX: 0000000000000000 RSI: 1ffff1000d743f43 RDI: ffff880068891c08
+       RBP: ffff88006733f160 R08: ffff8800688d7001 R09: 0000000000000000
+       R10: 0000000000000000 R11: 0000000000000000 R12: ffff8800688d7000
+       R13: ffff880067b7d000 R14: dffffc0000000000 R15: 0000000000000000
+       FS:  0000000000000000(0000) GS:ffff88006d000000(0000)
+       knlGS:0000000000000000
+       CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+       CR2: 00000000006c17e0 CR3: 0000000066e3b000 CR4: 00000000001406f0
+       Call Trace:
+        lo_do_transfer drivers/block/loop.c:251 [inline]
+        lo_read_transfer drivers/block/loop.c:392 [inline]
+        do_req_filebacked drivers/block/loop.c:541 [inline]
+        loop_handle_cmd drivers/block/loop.c:1677 [inline]
+        loop_queue_work+0xda0/0x49b0 drivers/block/loop.c:1689
+        kthread_worker_fn+0x4c3/0xa30 kernel/kthread.c:630
+        kthread+0x326/0x3f0 kernel/kthread.c:227
+        ret_from_fork+0x31/0x40 arch/x86/entry/entry_64.S:430
+       Code: 03 83 e2 07 41 29 df 42 0f b6 04 30 4d 8d 44 24 01 38 d0 7f 08
+       84 c0 0f 85 62 02 00 00 44 89 f8 41 0f b6 48 ff 25 ff 01 00 00 99 <f7>
+       7d c8 48 63 d2 48 03 55 d0 48 89 d0 48 89 d7 48 c1 e8 03 83
+       RIP: transfer_xor+0x1d1/0x440 drivers/block/loop.c:110 RSP:
+       ffff88006733f108
+       ---[ end trace 0166f7bd3b0c0933 ]---
+
+Reported-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Ming Lei <tom.leiming@gmail.com>
+Tested-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Jens Axboe <axboe@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -1097,9 +1097,12 @@ loop_set_status(struct loop_device *lo,
+       if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE)
+               return -EINVAL;
++      /* I/O need to be drained during transfer transition */
++      blk_mq_freeze_queue(lo->lo_queue);
++
+       err = loop_release_xfer(lo);
+       if (err)
+-              return err;
++              goto exit;
+       if (info->lo_encrypt_type) {
+               unsigned int type = info->lo_encrypt_type;
+@@ -1114,12 +1117,14 @@ loop_set_status(struct loop_device *lo,
+       err = loop_init_xfer(lo, xfer, info);
+       if (err)
+-              return err;
++              goto exit;
+       if (lo->lo_offset != info->lo_offset ||
+           lo->lo_sizelimit != info->lo_sizelimit)
+-              if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit))
+-                      return -EFBIG;
++              if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) {
++                      err = -EFBIG;
++                      goto exit;
++              }
+       loop_config_discard(lo);
+@@ -1156,7 +1161,9 @@ loop_set_status(struct loop_device *lo,
+       /* update dio if lo_offset or transfer is changed */
+       __loop_update_dio(lo, lo->use_dio);
+-      return 0;
++ exit:
++      blk_mq_unfreeze_queue(lo->lo_queue);
++      return err;
+ }
+ static int
diff --git a/queue-4.9/ext4-do-not-polute-the-extents-cache-while-shifting-extents.patch b/queue-4.9/ext4-do-not-polute-the-extents-cache-while-shifting-extents.patch
new file mode 100644 (file)
index 0000000..5372ea7
--- /dev/null
@@ -0,0 +1,61 @@
+From 03e916fa8b5577d85471452a3d0c5738aa658dae Mon Sep 17 00:00:00 2001
+From: Roman Pen <roman.penyaev@profitbricks.com>
+Date: Sun, 8 Jan 2017 21:00:35 -0500
+Subject: ext4: do not polute the extents cache while shifting extents
+
+From: Roman Pen <roman.penyaev@profitbricks.com>
+
+commit 03e916fa8b5577d85471452a3d0c5738aa658dae upstream.
+
+Inside ext4_ext_shift_extents() function ext4_find_extent() is called
+without EXT4_EX_NOCACHE flag, which should prevent cache population.
+
+This leads to oudated offsets in the extents tree and wrong blocks
+afterwards.
+
+Patch fixes the problem providing EXT4_EX_NOCACHE flag for each
+ext4_find_extents() call inside ext4_ext_shift_extents function.
+
+Fixes: 331573febb6a2
+Signed-off-by: Roman Pen <roman.penyaev@profitbricks.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: Namjae Jeon <namjae.jeon@samsung.com>
+Cc: Andreas Dilger <adilger.kernel@dilger.ca>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/extents.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -5344,7 +5344,8 @@ ext4_ext_shift_extents(struct inode *ino
+       ext4_lblk_t stop, *iterator, ex_start, ex_end;
+       /* Let path point to the last extent */
+-      path = ext4_find_extent(inode, EXT_MAX_BLOCKS - 1, NULL, 0);
++      path = ext4_find_extent(inode, EXT_MAX_BLOCKS - 1, NULL,
++                              EXT4_EX_NOCACHE);
+       if (IS_ERR(path))
+               return PTR_ERR(path);
+@@ -5360,7 +5361,8 @@ ext4_ext_shift_extents(struct inode *ino
+        * sure the hole is big enough to accommodate the shift.
+       */
+       if (SHIFT == SHIFT_LEFT) {
+-              path = ext4_find_extent(inode, start - 1, &path, 0);
++              path = ext4_find_extent(inode, start - 1, &path,
++                                      EXT4_EX_NOCACHE);
+               if (IS_ERR(path))
+                       return PTR_ERR(path);
+               depth = path->p_depth;
+@@ -5398,7 +5400,8 @@ ext4_ext_shift_extents(struct inode *ino
+        * becomes NULL to indicate the end of the loop.
+        */
+       while (iterator && start <= stop) {
+-              path = ext4_find_extent(inode, *iterator, &path, 0);
++              path = ext4_find_extent(inode, *iterator, &path,
++                                      EXT4_EX_NOCACHE);
+               if (IS_ERR(path))
+                       return PTR_ERR(path);
+               depth = path->p_depth;
diff --git a/queue-4.9/ext4-fix-data-corruption-in-data-journal-mode.patch b/queue-4.9/ext4-fix-data-corruption-in-data-journal-mode.patch
new file mode 100644 (file)
index 0000000..418ba51
--- /dev/null
@@ -0,0 +1,73 @@
+From 3b136499e906460919f0d21a49db1aaccf0ae963 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Fri, 27 Jan 2017 14:35:38 -0500
+Subject: ext4: fix data corruption in data=journal mode
+
+From: Jan Kara <jack@suse.cz>
+
+commit 3b136499e906460919f0d21a49db1aaccf0ae963 upstream.
+
+ext4_journalled_write_end() did not propely handle all the cases when
+generic_perform_write() did not copy all the data into the target page
+and could mark buffers with uninitialized contents as uptodate and dirty
+leading to possible data corruption (which would be quickly fixed by
+generic_perform_write() retrying the write but still). Fix the problem
+by carefully handling the case when the page that is written to is not
+uptodate.
+
+Reported-by: Al Viro <viro@ZenIV.linux.org.uk>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/inode.c |   23 +++++++++++++----------
+ 1 file changed, 13 insertions(+), 10 deletions(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -1379,7 +1379,9 @@ errout:
+  * set the buffer to be dirty, since in data=journalled mode we need
+  * to call ext4_handle_dirty_metadata() instead.
+  */
+-static void zero_new_buffers(struct page *page, unsigned from, unsigned to)
++static void ext4_journalled_zero_new_buffers(handle_t *handle,
++                                          struct page *page,
++                                          unsigned from, unsigned to)
+ {
+       unsigned int block_start = 0, block_end;
+       struct buffer_head *head, *bh;
+@@ -1396,7 +1398,7 @@ static void zero_new_buffers(struct page
+                                       size = min(to, block_end) - start;
+                                       zero_user(page, start, size);
+-                                      set_buffer_uptodate(bh);
++                                      write_end_fn(handle, bh);
+                               }
+                               clear_buffer_new(bh);
+                       }
+@@ -1428,15 +1430,16 @@ static int ext4_journalled_write_end(str
+       if (ext4_has_inline_data(inode))
+               copied = ext4_write_inline_data_end(inode, pos, len,
+                                                   copied, page);
+-      else {
+-              if (copied < len) {
+-                      if (!PageUptodate(page))
+-                              copied = 0;
+-                      zero_new_buffers(page, from+copied, to);
+-              }
+-
++      else if (unlikely(copied < len) && !PageUptodate(page)) {
++              copied = 0;
++              ext4_journalled_zero_new_buffers(handle, page, from, to);
++      } else {
++              if (unlikely(copied < len))
++                      ext4_journalled_zero_new_buffers(handle, page,
++                                                       from + copied, to);
+               ret = ext4_walk_page_buffers(handle, page_buffers(page), from,
+-                                           to, &partial, write_end_fn);
++                                           from + copied, &partial,
++                                           write_end_fn);
+               if (!partial)
+                       SetPageUptodate(page);
+       }
diff --git a/queue-4.9/ext4-fix-inline-data-error-paths.patch b/queue-4.9/ext4-fix-inline-data-error-paths.patch
new file mode 100644 (file)
index 0000000..e8a4497
--- /dev/null
@@ -0,0 +1,83 @@
+From eb5efbcb762aee4b454b04f7115f73ccbcf8f0ef Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sat, 4 Feb 2017 23:04:00 -0500
+Subject: ext4: fix inline data error paths
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit eb5efbcb762aee4b454b04f7115f73ccbcf8f0ef upstream.
+
+The write_end() function must always unlock the page and drop its ref
+count, even on an error.
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/inline.c |    9 ++++++++-
+ fs/ext4/inode.c  |   20 +++++++++++++++-----
+ 2 files changed, 23 insertions(+), 6 deletions(-)
+
+--- a/fs/ext4/inline.c
++++ b/fs/ext4/inline.c
+@@ -933,8 +933,15 @@ int ext4_da_write_inline_data_end(struct
+                                 struct page *page)
+ {
+       int i_size_changed = 0;
++      int ret;
+-      copied = ext4_write_inline_data_end(inode, pos, len, copied, page);
++      ret = ext4_write_inline_data_end(inode, pos, len, copied, page);
++      if (ret < 0) {
++              unlock_page(page);
++              put_page(page);
++              return ret;
++      }
++      copied = ret;
+       /*
+        * No need to use i_size_read() here, the i_size
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -1324,8 +1324,11 @@ static int ext4_write_end(struct file *f
+       if (ext4_has_inline_data(inode)) {
+               ret = ext4_write_inline_data_end(inode, pos, len,
+                                                copied, page);
+-              if (ret < 0)
++              if (ret < 0) {
++                      unlock_page(page);
++                      put_page(page);
+                       goto errout;
++              }
+               copied = ret;
+       } else
+               copied = block_write_end(file, mapping, pos,
+@@ -1427,10 +1430,16 @@ static int ext4_journalled_write_end(str
+       BUG_ON(!ext4_handle_valid(handle));
+-      if (ext4_has_inline_data(inode))
+-              copied = ext4_write_inline_data_end(inode, pos, len,
+-                                                  copied, page);
+-      else if (unlikely(copied < len) && !PageUptodate(page)) {
++      if (ext4_has_inline_data(inode)) {
++              ret = ext4_write_inline_data_end(inode, pos, len,
++                                               copied, page);
++              if (ret < 0) {
++                      unlock_page(page);
++                      put_page(page);
++                      goto errout;
++              }
++              copied = ret;
++      } else if (unlikely(copied < len) && !PageUptodate(page)) {
+               copied = 0;
+               ext4_journalled_zero_new_buffers(handle, page, from, to);
+       } else {
+@@ -1465,6 +1474,7 @@ static int ext4_journalled_write_end(str
+                */
+               ext4_orphan_add(handle, inode);
++errout:
+       ret2 = ext4_journal_stop(handle);
+       if (!ret)
+               ret = ret2;
diff --git a/queue-4.9/ext4-fix-use-after-iput-when-fscrypt-contexts-are-inconsistent.patch b/queue-4.9/ext4-fix-use-after-iput-when-fscrypt-contexts-are-inconsistent.patch
new file mode 100644 (file)
index 0000000..cdb1218
--- /dev/null
@@ -0,0 +1,45 @@
+From dd01b690f8f4b1e414f89e5a9a5326bf720d6652 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Wed, 1 Feb 2017 21:07:11 -0500
+Subject: ext4: fix use-after-iput when fscrypt contexts are inconsistent
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit dd01b690f8f4b1e414f89e5a9a5326bf720d6652 upstream.
+
+In the case where the child's encryption context was inconsistent with
+its parent directory, we were using inode->i_sb and inode->i_ino after
+the inode had already been iput().  Fix this by doing the iput() in the
+correct places.
+
+Note: only ext4 had this bug, not f2fs and ubifs.
+
+Fixes: d9cdc9033181 ("ext4 crypto: enforce context consistency")
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/namei.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -1616,13 +1616,15 @@ static struct dentry *ext4_lookup(struct
+                   !fscrypt_has_permitted_context(dir, inode)) {
+                       int nokey = ext4_encrypted_inode(inode) &&
+                               !fscrypt_has_encryption_key(inode);
+-                      iput(inode);
+-                      if (nokey)
++                      if (nokey) {
++                              iput(inode);
+                               return ERR_PTR(-ENOKEY);
++                      }
+                       ext4_warning(inode->i_sb,
+                                    "Inconsistent encryption contexts: %lu/%lu",
+                                    (unsigned long) dir->i_ino,
+                                    (unsigned long) inode->i_ino);
++                      iput(inode);
+                       return ERR_PTR(-EPERM);
+               }
+       }
diff --git a/queue-4.9/ext4-include-forgotten-start-block-on-fallocate-insert-range.patch b/queue-4.9/ext4-include-forgotten-start-block-on-fallocate-insert-range.patch
new file mode 100644 (file)
index 0000000..cac1041
--- /dev/null
@@ -0,0 +1,113 @@
+From 2a9b8cba62c0741109c33a2be700ff3d7703a7c2 Mon Sep 17 00:00:00 2001
+From: Roman Pen <roman.penyaev@profitbricks.com>
+Date: Sun, 8 Jan 2017 20:59:35 -0500
+Subject: ext4: Include forgotten start block on fallocate insert range
+
+From: Roman Pen <roman.penyaev@profitbricks.com>
+
+commit 2a9b8cba62c0741109c33a2be700ff3d7703a7c2 upstream.
+
+While doing 'insert range' start block should be also shifted right.
+The bug can be easily reproduced by the following test:
+
+    ptr = malloc(4096);
+    assert(ptr);
+
+    fd = open("./ext4.file", O_CREAT | O_TRUNC | O_RDWR, 0600);
+    assert(fd >= 0);
+
+    rc = fallocate(fd, 0, 0, 8192);
+    assert(rc == 0);
+    for (i = 0; i < 2048; i++)
+            *((unsigned short *)ptr + i) = 0xbeef;
+    rc = pwrite(fd, ptr, 4096, 0);
+    assert(rc == 4096);
+    rc = pwrite(fd, ptr, 4096, 4096);
+    assert(rc == 4096);
+
+    for (block = 2; block < 1000; block++) {
+            rc = fallocate(fd, FALLOC_FL_INSERT_RANGE, 4096, 4096);
+            assert(rc == 0);
+
+            for (i = 0; i < 2048; i++)
+                    *((unsigned short *)ptr + i) = block;
+
+            rc = pwrite(fd, ptr, 4096, 4096);
+            assert(rc == 4096);
+    }
+
+Because start block is not included in the range the hole appears at
+the wrong offset (just after the desired offset) and the following
+pwrite() overwrites already existent block, keeping hole untouched.
+
+Simple way to verify wrong behaviour is to check zeroed blocks after
+the test:
+
+   $ hexdump ./ext4.file | grep '0000 0000'
+
+The root cause of the bug is a wrong range (start, stop], where start
+should be inclusive, i.e. [start, stop].
+
+This patch fixes the problem by including start into the range.  But
+not to break left shift (range collapse) stop points to the beginning
+of the a block, not to the end.
+
+The other not obvious change is an iterator check on validness in a
+main loop.  Because iterator is unsigned the following corner case
+should be considered with care: insert a block at 0 offset, when stop
+variables overflows and never becomes less than start, which is 0.
+To handle this special case iterator is set to NULL to indicate that
+end of the loop is reached.
+
+Fixes: 331573febb6a2
+Signed-off-by: Roman Pen <roman.penyaev@profitbricks.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: Namjae Jeon <namjae.jeon@samsung.com>
+Cc: Andreas Dilger <adilger.kernel@dilger.ca>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/extents.c |   18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -5353,8 +5353,7 @@ ext4_ext_shift_extents(struct inode *ino
+       if (!extent)
+               goto out;
+-      stop = le32_to_cpu(extent->ee_block) +
+-                      ext4_ext_get_actual_len(extent);
++      stop = le32_to_cpu(extent->ee_block);
+        /*
+        * In case of left shift, Don't start shifting extents until we make
+@@ -5393,8 +5392,12 @@ ext4_ext_shift_extents(struct inode *ino
+       else
+               iterator = &stop;
+-      /* Its safe to start updating extents */
+-      while (start < stop) {
++      /*
++       * Its safe to start updating extents.  Start and stop are unsigned, so
++       * in case of right shift if extent with 0 block is reached, iterator
++       * becomes NULL to indicate the end of the loop.
++       */
++      while (iterator && start <= stop) {
+               path = ext4_find_extent(inode, *iterator, &path, 0);
+               if (IS_ERR(path))
+                       return PTR_ERR(path);
+@@ -5422,8 +5425,11 @@ ext4_ext_shift_extents(struct inode *ino
+                                       ext4_ext_get_actual_len(extent);
+               } else {
+                       extent = EXT_FIRST_EXTENT(path[depth].p_hdr);
+-                      *iterator =  le32_to_cpu(extent->ee_block) > 0 ?
+-                              le32_to_cpu(extent->ee_block) - 1 : 0;
++                      if (le32_to_cpu(extent->ee_block) > 0)
++                              *iterator = le32_to_cpu(extent->ee_block) - 1;
++                      else
++                              /* Beginning is reached, end of the loop */
++                              iterator = NULL;
+                       /* Update path extent in case we need to stop */
+                       while (le32_to_cpu(extent->ee_block) < start)
+                               extent++;
diff --git a/queue-4.9/ext4-preserve-the-needs_recovery-flag-when-the-journal-is-aborted.patch b/queue-4.9/ext4-preserve-the-needs_recovery-flag-when-the-journal-is-aborted.patch
new file mode 100644 (file)
index 0000000..b649e13
--- /dev/null
@@ -0,0 +1,51 @@
+From 97abd7d4b5d9c48ec15c425485f054e1c15e591b Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sat, 4 Feb 2017 23:38:06 -0500
+Subject: ext4: preserve the needs_recovery flag when the journal is aborted
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 97abd7d4b5d9c48ec15c425485f054e1c15e591b upstream.
+
+If the journal is aborted, the needs_recovery feature flag should not
+be removed.  Otherwise, it's the journal might not get replayed and
+this could lead to more data getting lost.
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/super.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -825,6 +825,7 @@ static void ext4_put_super(struct super_
+ {
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       struct ext4_super_block *es = sbi->s_es;
++      int aborted = 0;
+       int i, err;
+       ext4_unregister_li_request(sb);
+@@ -834,9 +835,10 @@ static void ext4_put_super(struct super_
+       destroy_workqueue(sbi->rsv_conversion_wq);
+       if (sbi->s_journal) {
++              aborted = is_journal_aborted(sbi->s_journal);
+               err = jbd2_journal_destroy(sbi->s_journal);
+               sbi->s_journal = NULL;
+-              if (err < 0)
++              if ((err < 0) && !aborted)
+                       ext4_abort(sb, "Couldn't clean up the journal");
+       }
+@@ -847,7 +849,7 @@ static void ext4_put_super(struct super_
+       ext4_mb_release(sb);
+       ext4_ext_release(sb);
+-      if (!(sb->s_flags & MS_RDONLY)) {
++      if (!(sb->s_flags & MS_RDONLY) && !aborted) {
+               ext4_clear_feature_journal_needs_recovery(sb);
+               es->s_state = cpu_to_le16(sbi->s_mount_state);
+       }
diff --git a/queue-4.9/ext4-return-erofs-if-device-is-r-o-and-journal-replay-is-needed.patch b/queue-4.9/ext4-return-erofs-if-device-is-r-o-and-journal-replay-is-needed.patch
new file mode 100644 (file)
index 0000000..cc7a7a8
--- /dev/null
@@ -0,0 +1,32 @@
+From 4753d8a24d4588657bc0a4cd66d4e282dff15c8c Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sun, 5 Feb 2017 01:26:48 -0500
+Subject: ext4: return EROFS if device is r/o and journal replay is needed
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 4753d8a24d4588657bc0a4cd66d4e282dff15c8c upstream.
+
+If the file system requires journal recovery, and the device is
+read-ony, return EROFS to the mount system call.  This allows xfstests
+generic/050 to pass.
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/super.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -3913,7 +3913,8 @@ static int ext4_fill_super(struct super_
+        * root first: it may be modified in the journal!
+        */
+       if (!test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb)) {
+-              if (ext4_load_journal(sb, es, journal_devnum))
++              err = ext4_load_journal(sb, es, journal_devnum);
++              if (err)
+                       goto failed_mount3a;
+       } else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) &&
+                  ext4_has_feature_journal_needs_recovery(sb)) {
diff --git a/queue-4.9/ext4-trim-allocation-requests-to-group-size.patch b/queue-4.9/ext4-trim-allocation-requests-to-group-size.patch
new file mode 100644 (file)
index 0000000..8d43bd9
--- /dev/null
@@ -0,0 +1,39 @@
+From cd648b8a8fd5071d232242d5ee7ee3c0815776af Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Fri, 27 Jan 2017 14:34:30 -0500
+Subject: ext4: trim allocation requests to group size
+
+From: Jan Kara <jack@suse.cz>
+
+commit cd648b8a8fd5071d232242d5ee7ee3c0815776af upstream.
+
+If filesystem groups are artifically small (using parameter -g to
+mkfs.ext4), ext4_mb_normalize_request() can result in a request that is
+larger than a block group. Trim the request size to not confuse
+allocation code.
+
+Reported-by: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/mballoc.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -3123,6 +3123,13 @@ ext4_mb_normalize_request(struct ext4_al
+       if (ar->pright && start + size - 1 >= ar->lright)
+               size -= start + size - ar->lright;
++      /*
++       * Trim allocation request for filesystems with artificially small
++       * groups.
++       */
++      if (size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb))
++              size = EXT4_BLOCKS_PER_GROUP(ac->ac_sb);
++
+       end = start + size;
+       /* check we don't cross already preallocated blocks */
diff --git a/queue-4.9/jbd2-don-t-leak-modified-metadata-buffers-on-an-aborted-journal.patch b/queue-4.9/jbd2-don-t-leak-modified-metadata-buffers-on-an-aborted-journal.patch
new file mode 100644 (file)
index 0000000..b9776cf
--- /dev/null
@@ -0,0 +1,34 @@
+From e112666b4959b25a8552d63bc564e1059be703e8 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sat, 4 Feb 2017 23:14:19 -0500
+Subject: jbd2: don't leak modified metadata buffers on an aborted journal
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit e112666b4959b25a8552d63bc564e1059be703e8 upstream.
+
+If the journal has been aborted, we shouldn't mark the underlying
+buffer head as dirty, since that will cause the metadata block to get
+modified.  And if the journal has been aborted, we shouldn't allow
+this since it will almost certainly lead to a corrupted file system.
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/jbd2/transaction.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -1863,7 +1863,9 @@ static void __jbd2_journal_temp_unlink_b
+       __blist_del_buffer(list, jh);
+       jh->b_jlist = BJ_None;
+-      if (test_clear_buffer_jbddirty(bh))
++      if (transaction && is_journal_aborted(transaction->t_journal))
++              clear_buffer_jbddirty(bh);
++      else if (test_clear_buffer_jbddirty(bh))
+               mark_buffer_dirty(bh);  /* Expose it to the VM */
+ }
diff --git a/queue-4.9/loop-fix-lo_flags_partscan-hang.patch b/queue-4.9/loop-fix-lo_flags_partscan-hang.patch
new file mode 100644 (file)
index 0000000..411a03b
--- /dev/null
@@ -0,0 +1,55 @@
+From e02898b423802b1f3a3aaa7f16e896da069ba8f7 Mon Sep 17 00:00:00 2001
+From: Omar Sandoval <osandov@fb.com>
+Date: Wed, 1 Mar 2017 10:42:38 -0800
+Subject: loop: fix LO_FLAGS_PARTSCAN hang
+
+From: Omar Sandoval <osandov@fb.com>
+
+commit e02898b423802b1f3a3aaa7f16e896da069ba8f7 upstream.
+
+loop_reread_partitions() needs to do I/O, but we just froze the queue,
+so we end up waiting forever. This can easily be reproduced with losetup
+-P. Fix it by moving the reread to after we unfreeze the queue.
+
+Fixes: ecdd09597a57 ("block/loop: fix race between I/O and set_status")
+Reported-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Omar Sandoval <osandov@fb.com>
+Reviewed-by: Ming Lei <tom.leiming@gmail.com>
+Signed-off-by: Jens Axboe <axboe@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c |   15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -1142,13 +1142,6 @@ loop_set_status(struct loop_device *lo,
+            (info->lo_flags & LO_FLAGS_AUTOCLEAR))
+               lo->lo_flags ^= LO_FLAGS_AUTOCLEAR;
+-      if ((info->lo_flags & LO_FLAGS_PARTSCAN) &&
+-           !(lo->lo_flags & LO_FLAGS_PARTSCAN)) {
+-              lo->lo_flags |= LO_FLAGS_PARTSCAN;
+-              lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
+-              loop_reread_partitions(lo, lo->lo_device);
+-      }
+-
+       lo->lo_encrypt_key_size = info->lo_encrypt_key_size;
+       lo->lo_init[0] = info->lo_init[0];
+       lo->lo_init[1] = info->lo_init[1];
+@@ -1163,6 +1156,14 @@ loop_set_status(struct loop_device *lo,
+  exit:
+       blk_mq_unfreeze_queue(lo->lo_queue);
++
++      if (!err && (info->lo_flags & LO_FLAGS_PARTSCAN) &&
++           !(lo->lo_flags & LO_FLAGS_PARTSCAN)) {
++              lo->lo_flags |= LO_FLAGS_PARTSCAN;
++              lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
++              loop_reread_partitions(lo, lo->lo_device);
++      }
++
+       return err;
+ }
diff --git a/queue-4.9/mei-remove-support-for-broken-parallel-read.patch b/queue-4.9/mei-remove-support-for-broken-parallel-read.patch
new file mode 100644 (file)
index 0000000..4e02572
--- /dev/null
@@ -0,0 +1,84 @@
+From cb97fbbcac15982406e0c74cd5512a8b6fcf10b3 Mon Sep 17 00:00:00 2001
+From: Alexander Usyskin <alexander.usyskin@intel.com>
+Date: Wed, 8 Feb 2017 00:41:45 +0200
+Subject: mei: remove support for broken parallel read
+
+From: Alexander Usyskin <alexander.usyskin@intel.com>
+
+commit cb97fbbcac15982406e0c74cd5512a8b6fcf10b3 upstream.
+
+Parallel reads from multiple threads on a file descriptor
+are not well defined and racy. It is safer to return to original
+behavior and simply fail the additional read.
+The solution is to remove request for next read credit.
+
+Fixes: ff1586a7ea57 ("mei: enqueue consecutive reads")
+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/main.c |   48 ++++++++++++++++++++++++++----------------------
+ 1 file changed, 26 insertions(+), 22 deletions(-)
+
+--- a/drivers/misc/mei/main.c
++++ b/drivers/misc/mei/main.c
+@@ -182,32 +182,36 @@ static ssize_t mei_read(struct file *fil
+               goto out;
+       }
+-      if (rets == -EBUSY &&
+-          !mei_cl_enqueue_ctrl_wr_cb(cl, length, MEI_FOP_READ, file)) {
+-              rets = -ENOMEM;
+-              goto out;
++
++again:
++      mutex_unlock(&dev->device_lock);
++      if (wait_event_interruptible(cl->rx_wait,
++                                   !list_empty(&cl->rd_completed) ||
++                                   !mei_cl_is_connected(cl))) {
++              if (signal_pending(current))
++                      return -EINTR;
++              return -ERESTARTSYS;
+       }
++      mutex_lock(&dev->device_lock);
+-      do {
+-              mutex_unlock(&dev->device_lock);
++      if (!mei_cl_is_connected(cl)) {
++              rets = -ENODEV;
++              goto out;
++      }
+-              if (wait_event_interruptible(cl->rx_wait,
+-                                           (!list_empty(&cl->rd_completed)) ||
+-                                           (!mei_cl_is_connected(cl)))) {
+-
+-                      if (signal_pending(current))
+-                              return -EINTR;
+-                      return -ERESTARTSYS;
+-              }
+-
+-              mutex_lock(&dev->device_lock);
+-              if (!mei_cl_is_connected(cl)) {
+-                      rets = -ENODEV;
+-                      goto out;
+-              }
++      cb = mei_cl_read_cb(cl, file);
++      if (!cb) {
++              /*
++               * For amthif all the waiters are woken up,
++               * but only fp with matching cb->fp get the cb,
++               * the others have to return to wait on read.
++               */
++              if (cl == &dev->iamthif_cl)
++                      goto again;
+-              cb = mei_cl_read_cb(cl, file);
+-      } while (!cb);
++              rets = 0;
++              goto out;
++      }
+ copy_buffer:
+       /* now copy the data to user space */
diff --git a/queue-4.9/samples-seccomp-fix-64-bit-comparison-macros.patch b/queue-4.9/samples-seccomp-fix-64-bit-comparison-macros.patch
new file mode 100644 (file)
index 0000000..bcdd74e
--- /dev/null
@@ -0,0 +1,196 @@
+From 916cafdc95843fb9af5fd5f83ca499d75473d107 Mon Sep 17 00:00:00 2001
+From: Mathias Svensson <idolf@google.com>
+Date: Fri, 6 Jan 2017 13:32:39 -0800
+Subject: samples/seccomp: fix 64-bit comparison macros
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mathias Svensson <idolf@google.com>
+
+commit 916cafdc95843fb9af5fd5f83ca499d75473d107 upstream.
+
+There were some bugs in the JNE64 and JLT64 comparision macros. This fixes
+them, improves comments, and cleans up the file while we are at it.
+
+Reported-by: Stephen Röttger <sroettger@google.com>
+Signed-off-by: Mathias Svensson <idolf@google.com>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: James Morris <james.l.morris@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ samples/seccomp/bpf-helper.h |  125 ++++++++++++++++++++++++-------------------
+ 1 file changed, 72 insertions(+), 53 deletions(-)
+
+--- a/samples/seccomp/bpf-helper.h
++++ b/samples/seccomp/bpf-helper.h
+@@ -138,7 +138,7 @@ union arg64 {
+ #define ARG_32(idx) \
+       BPF_STMT(BPF_LD+BPF_W+BPF_ABS, LO_ARG(idx))
+-/* Loads hi into A and lo in X */
++/* Loads lo into M[0] and hi into M[1] and A */
+ #define ARG_64(idx) \
+       BPF_STMT(BPF_LD+BPF_W+BPF_ABS, LO_ARG(idx)), \
+       BPF_STMT(BPF_ST, 0), /* lo -> M[0] */ \
+@@ -153,88 +153,107 @@ union arg64 {
+       BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (value), 1, 0), \
+       jt
+-/* Checks the lo, then swaps to check the hi. A=lo,X=hi */
++#define JA32(value, jt) \
++      BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (value), 0, 1), \
++      jt
++
++#define JGE32(value, jt) \
++      BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 0, 1), \
++      jt
++
++#define JGT32(value, jt) \
++      BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 0, 1), \
++      jt
++
++#define JLE32(value, jt) \
++      BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 1, 0), \
++      jt
++
++#define JLT32(value, jt) \
++      BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 1, 0), \
++      jt
++
++/*
++ * All the JXX64 checks assume lo is saved in M[0] and hi is saved in both
++ * A and M[1]. This invariant is kept by restoring A if necessary.
++ */
+ #define JEQ64(lo, hi, jt) \
++      /* if (hi != arg.hi) goto NOMATCH; */ \
+       BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+       BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
++      /* if (lo != arg.lo) goto NOMATCH; */ \
+       BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (lo), 0, 2), \
+-      BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
++      BPF_STMT(BPF_LD+BPF_MEM, 1), \
+       jt, \
+-      BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
++      BPF_STMT(BPF_LD+BPF_MEM, 1)
+ #define JNE64(lo, hi, jt) \
+-      BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 5, 0), \
+-      BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
++      /* if (hi != arg.hi) goto MATCH; */ \
++      BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 3), \
++      BPF_STMT(BPF_LD+BPF_MEM, 0), \
++      /* if (lo != arg.lo) goto MATCH; */ \
+       BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (lo), 2, 0), \
+-      BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
++      BPF_STMT(BPF_LD+BPF_MEM, 1), \
+       jt, \
+-      BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+-
+-#define JA32(value, jt) \
+-      BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (value), 0, 1), \
+-      jt
++      BPF_STMT(BPF_LD+BPF_MEM, 1)
+ #define JA64(lo, hi, jt) \
++      /* if (hi & arg.hi) goto MATCH; */ \
+       BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (hi), 3, 0), \
+-      BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
++      BPF_STMT(BPF_LD+BPF_MEM, 0), \
++      /* if (lo & arg.lo) goto MATCH; */ \
+       BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (lo), 0, 2), \
+-      BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
++      BPF_STMT(BPF_LD+BPF_MEM, 1), \
+       jt, \
+-      BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+-
+-#define JGE32(value, jt) \
+-      BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 0, 1), \
+-      jt
++      BPF_STMT(BPF_LD+BPF_MEM, 1)
+-#define JLT32(value, jt) \
+-      BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 1, 0), \
+-      jt
+-
+-/* Shortcut checking if hi > arg.hi. */
+ #define JGE64(lo, hi, jt) \
++      /* if (hi > arg.hi) goto MATCH; */ \
+       BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 4, 0), \
++      /* if (hi != arg.hi) goto NOMATCH; */ \
+       BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+-      BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
++      BPF_STMT(BPF_LD+BPF_MEM, 0), \
++      /* if (lo >= arg.lo) goto MATCH; */ \
+       BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (lo), 0, 2), \
+-      BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
++      BPF_STMT(BPF_LD+BPF_MEM, 1), \
+       jt, \
+-      BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+-
+-#define JLT64(lo, hi, jt) \
+-      BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (hi), 0, 4), \
+-      BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+-      BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+-      BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 2, 0), \
+-      BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+-      jt, \
+-      BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+-
+-#define JGT32(value, jt) \
+-      BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 0, 1), \
+-      jt
+-
+-#define JLE32(value, jt) \
+-      BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 1, 0), \
+-      jt
++      BPF_STMT(BPF_LD+BPF_MEM, 1)
+-/* Check hi > args.hi first, then do the GE checking */
+ #define JGT64(lo, hi, jt) \
++      /* if (hi > arg.hi) goto MATCH; */ \
+       BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 4, 0), \
++      /* if (hi != arg.hi) goto NOMATCH; */ \
+       BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+-      BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
++      BPF_STMT(BPF_LD+BPF_MEM, 0), \
++      /* if (lo > arg.lo) goto MATCH; */ \
+       BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 0, 2), \
+-      BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
++      BPF_STMT(BPF_LD+BPF_MEM, 1), \
+       jt, \
+-      BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
++      BPF_STMT(BPF_LD+BPF_MEM, 1)
+ #define JLE64(lo, hi, jt) \
+-      BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 6, 0), \
+-      BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 3), \
+-      BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
++      /* if (hi < arg.hi) goto MATCH; */ \
++      BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (hi), 0, 4), \
++      /* if (hi != arg.hi) goto NOMATCH; */ \
++      BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
++      BPF_STMT(BPF_LD+BPF_MEM, 0), \
++      /* if (lo <= arg.lo) goto MATCH; */ \
+       BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 2, 0), \
+-      BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
++      BPF_STMT(BPF_LD+BPF_MEM, 1), \
++      jt, \
++      BPF_STMT(BPF_LD+BPF_MEM, 1)
++
++#define JLT64(lo, hi, jt) \
++      /* if (hi < arg.hi) goto MATCH; */ \
++      BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (hi), 0, 4), \
++      /* if (hi != arg.hi) goto NOMATCH; */ \
++      BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
++      BPF_STMT(BPF_LD+BPF_MEM, 0), \
++      /* if (lo < arg.lo) goto MATCH; */ \
++      BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (lo), 2, 0), \
++      BPF_STMT(BPF_LD+BPF_MEM, 1), \
+       jt, \
+-      BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
++      BPF_STMT(BPF_LD+BPF_MEM, 1)
+ #define LOAD_SYSCALL_NR \
+       BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
index b4b6967aeaa4fccdece8eb846a28db45e89ee392..bb86a407c460456f5195d8ba41a9618fb88f0c55 100644 (file)
@@ -62,3 +62,16 @@ scsi-aacraid-reorder-adapter-status-check.patch
 scsi-use-scsi_device_from_queue-for-scsi_dh.patch
 power-reset-at91-poweroff-timely-shutdown-lpddr-memories.patch
 fix-disable-sys_membarrier-when-nohz_full-is-enabled.patch
+jbd2-don-t-leak-modified-metadata-buffers-on-an-aborted-journal.patch
+block-loop-fix-race-between-i-o-and-set_status.patch
+loop-fix-lo_flags_partscan-hang.patch
+ext4-include-forgotten-start-block-on-fallocate-insert-range.patch
+ext4-do-not-polute-the-extents-cache-while-shifting-extents.patch
+ext4-trim-allocation-requests-to-group-size.patch
+ext4-fix-data-corruption-in-data-journal-mode.patch
+ext4-fix-use-after-iput-when-fscrypt-contexts-are-inconsistent.patch
+ext4-fix-inline-data-error-paths.patch
+ext4-preserve-the-needs_recovery-flag-when-the-journal-is-aborted.patch
+ext4-return-erofs-if-device-is-r-o-and-journal-replay-is-needed.patch
+samples-seccomp-fix-64-bit-comparison-macros.patch
+mei-remove-support-for-broken-parallel-read.patch