]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 16 Mar 2018 14:08:26 +0000 (15:08 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 16 Mar 2018 14:08:26 +0000 (15:08 +0100)
added patches:
gfs2-clean-up-lookup-fillup-_metapath.patch
gfs2-fixes-to-implement-iomap-for-block_map-2.patch

queue-4.15/gfs2-clean-up-lookup-fillup-_metapath.patch [new file with mode: 0644]
queue-4.15/gfs2-fixes-to-implement-iomap-for-block_map-2.patch [new file with mode: 0644]
queue-4.15/series

diff --git a/queue-4.15/gfs2-clean-up-lookup-fillup-_metapath.patch b/queue-4.15/gfs2-clean-up-lookup-fillup-_metapath.patch
new file mode 100644 (file)
index 0000000..5fd9213
--- /dev/null
@@ -0,0 +1,161 @@
+From e8b43fe0c1e035a135be7ca3791d465fcb1b501e Mon Sep 17 00:00:00 2001
+From: Andreas Gruenbacher <agruenba@redhat.com>
+Date: Fri, 8 Dec 2017 17:01:57 +0100
+Subject: gfs2: Clean up {lookup,fillup}_metapath
+
+From: Andreas Gruenbacher <agruenba@redhat.com>
+
+commit e8b43fe0c1e035a135be7ca3791d465fcb1b501e upstream.
+
+Split out the entire lookup loop from lookup_metapath and
+fillup_metapath.  Make both functions return the actual height in
+mp->mp_aheight, and return 0 on success.  Handle lookup errors properly
+in trunc_dealloc.
+
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Bob Peterson <rpeterso@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/gfs2/bmap.c |   74 +++++++++++++++++++++++----------------------------------
+ 1 file changed, 30 insertions(+), 44 deletions(-)
+
+--- a/fs/gfs2/bmap.c
++++ b/fs/gfs2/bmap.c
+@@ -305,21 +305,22 @@ static void gfs2_metapath_ra(struct gfs2
+       }
+ }
+-/**
+- * lookup_mp_height - helper function for lookup_metapath
+- * @ip: the inode
+- * @mp: the metapath
+- * @h: the height which needs looking up
+- */
+-static int lookup_mp_height(struct gfs2_inode *ip, struct metapath *mp, int h)
++static int __fillup_metapath(struct gfs2_inode *ip, struct metapath *mp,
++                           unsigned int x, unsigned int h)
+ {
+-      __be64 *ptr = metapointer(h, mp);
+-      u64 dblock = be64_to_cpu(*ptr);
+-
+-      if (!dblock)
+-              return h + 1;
++      for (; x < h; x++) {
++              __be64 *ptr = metapointer(x, mp);
++              u64 dblock = be64_to_cpu(*ptr);
++              int ret;
+-      return gfs2_meta_indirect_buffer(ip, h + 1, dblock, &mp->mp_bh[h + 1]);
++              if (!dblock)
++                      break;
++              ret = gfs2_meta_indirect_buffer(ip, x + 1, dblock, &mp->mp_bh[x + 1]);
++              if (ret)
++                      return ret;
++      }
++      mp->mp_aheight = x + 1;
++      return 0;
+ }
+ /**
+@@ -336,25 +337,12 @@ static int lookup_mp_height(struct gfs2_
+  * at which it found the unallocated block. Blocks which are found are
+  * added to the mp->mp_bh[] list.
+  *
+- * Returns: error or height of metadata tree
++ * Returns: error
+  */
+ static int lookup_metapath(struct gfs2_inode *ip, struct metapath *mp)
+ {
+-      unsigned int end_of_metadata = ip->i_height - 1;
+-      unsigned int x;
+-      int ret;
+-
+-      for (x = 0; x < end_of_metadata; x++) {
+-              ret = lookup_mp_height(ip, mp, x);
+-              if (ret)
+-                      goto out;
+-      }
+-
+-      ret = ip->i_height;
+-out:
+-      mp->mp_aheight = ret;
+-      return ret;
++      return __fillup_metapath(ip, mp, 0, ip->i_height - 1);
+ }
+ /**
+@@ -365,25 +353,21 @@ out:
+  *
+  * Similar to lookup_metapath, but does lookups for a range of heights
+  *
+- * Returns: error or height of metadata tree
++ * Returns: error
+  */
+ static int fillup_metapath(struct gfs2_inode *ip, struct metapath *mp, int h)
+ {
+-      unsigned int start_h = h - 1;
+-      int ret;
++      unsigned int x = 0;
+       if (h) {
+               /* find the first buffer we need to look up. */
+-              while (start_h > 0 && mp->mp_bh[start_h] == NULL)
+-                      start_h--;
+-              for (; start_h < h; start_h++) {
+-                      ret = lookup_mp_height(ip, mp, start_h);
+-                      if (ret)
+-                              return ret;
++              for (x = h - 1; x > 0; x--) {
++                      if (mp->mp_bh[x])
++                              break;
+               }
+       }
+-      return ip->i_height;
++      return __fillup_metapath(ip, mp, x, h);
+ }
+ static inline void release_metapath(struct metapath *mp)
+@@ -790,7 +774,7 @@ int gfs2_iomap_begin(struct inode *inode
+               goto do_alloc;
+       ret = lookup_metapath(ip, &mp);
+-      if (ret < 0)
++      if (ret)
+               goto out_release;
+       if (mp.mp_aheight != ip->i_height)
+@@ -1339,7 +1323,9 @@ static int trunc_dealloc(struct gfs2_ino
+       mp.mp_bh[0] = dibh;
+       ret = lookup_metapath(ip, &mp);
+-      if (ret == ip->i_height)
++      if (ret)
++              goto out_metapath;
++      if (mp.mp_aheight == ip->i_height)
+               state = DEALLOC_MP_FULL; /* We have a complete metapath */
+       else
+               state = DEALLOC_FILL_MP; /* deal with partial metapath */
+@@ -1435,16 +1421,16 @@ static int trunc_dealloc(struct gfs2_ino
+               case DEALLOC_FILL_MP:
+                       /* Fill the buffers out to the current height. */
+                       ret = fillup_metapath(ip, &mp, mp_h);
+-                      if (ret < 0)
++                      if (ret)
+                               goto out;
+                       /* If buffers found for the entire strip height */
+-                      if ((ret == ip->i_height) && (mp_h == strip_h)) {
++                      if (mp.mp_aheight - 1 == strip_h) {
+                               state = DEALLOC_MP_FULL;
+                               break;
+                       }
+-                      if (ret < ip->i_height) /* We have a partial height */
+-                              mp_h = ret - 1;
++                      if (mp.mp_aheight < ip->i_height) /* We have a partial height */
++                              mp_h = mp.mp_aheight - 1;
+                       /* If we find a non-null block pointer, crawl a bit
+                          higher up in the metapath and try again, otherwise
diff --git a/queue-4.15/gfs2-fixes-to-implement-iomap-for-block_map-2.patch b/queue-4.15/gfs2-fixes-to-implement-iomap-for-block_map-2.patch
new file mode 100644 (file)
index 0000000..5701b0e
--- /dev/null
@@ -0,0 +1,35 @@
+From 3b5da96e4585a2788da6a07619bda3518d76eb30 Mon Sep 17 00:00:00 2001
+From: Andreas Gruenbacher <agruenba@redhat.com>
+Date: Mon, 5 Mar 2018 06:18:25 -0700
+Subject: gfs2: Fixes to "Implement iomap for block_map" (2)
+
+From: Andreas Gruenbacher <agruenba@redhat.com>
+
+commit 3b5da96e4585a2788da6a07619bda3518d76eb30 upstream.
+
+It turns out that commit 3229c18c0d6b2 'Fixes to "Implement iomap for
+block_map"' introduced another bug in gfs2_iomap_begin that can cause
+gfs2_block_map to set bh->b_size of an actual buffer to 0.  This can
+lead to arbitrary incorrect behavior including crashes or disk
+corruption.  Revert the incorrect part of that commit.
+
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Bob Peterson <rpeterso@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/gfs2/bmap.c |    3 ---
+ 1 file changed, 3 deletions(-)
+
+--- a/fs/gfs2/bmap.c
++++ b/fs/gfs2/bmap.c
+@@ -811,9 +811,6 @@ do_alloc:
+                       iomap->length = hole_size(inode, lblock, &mp);
+               else
+                       iomap->length = size - pos;
+-      } else {
+-              if (height <= ip->i_height)
+-                      iomap->length = hole_size(inode, lblock, &mp);
+       }
+       goto out_release;
+ }
index 0c544c58593d4ab4bfcda461ba3de2f3e25420ac..a23ed4fd16cd71a4a526f52d9770e8395fb3eef0 100644 (file)
@@ -23,3 +23,5 @@ serial-core-mark-port-as-initialized-in-autoconfig.patch
 earlycon-add-reg-offset-to-physical-address-before-mapping.patch
 dm-mpath-fix-passing-integrity-data.patch
 revert-btrfs-use-proper-endianness-accessors-for.patch
+gfs2-clean-up-lookup-fillup-_metapath.patch
+gfs2-fixes-to-implement-iomap-for-block_map-2.patch