From: Greg Kroah-Hartman Date: Fri, 16 Mar 2018 14:08:26 +0000 (+0100) Subject: 4.15-stable patches X-Git-Tag: v3.18.100~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=be02cfa4e514553c4da7281cb33736708e7c1c89;p=thirdparty%2Fkernel%2Fstable-queue.git 4.15-stable patches added patches: gfs2-clean-up-lookup-fillup-_metapath.patch gfs2-fixes-to-implement-iomap-for-block_map-2.patch --- 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 index 00000000000..5fd92136d4b --- /dev/null +++ b/queue-4.15/gfs2-clean-up-lookup-fillup-_metapath.patch @@ -0,0 +1,161 @@ +From e8b43fe0c1e035a135be7ca3791d465fcb1b501e Mon Sep 17 00:00:00 2001 +From: Andreas Gruenbacher +Date: Fri, 8 Dec 2017 17:01:57 +0100 +Subject: gfs2: Clean up {lookup,fillup}_metapath + +From: Andreas Gruenbacher + +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 +Signed-off-by: Bob Peterson +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..5701b0e51f4 --- /dev/null +++ b/queue-4.15/gfs2-fixes-to-implement-iomap-for-block_map-2.patch @@ -0,0 +1,35 @@ +From 3b5da96e4585a2788da6a07619bda3518d76eb30 Mon Sep 17 00:00:00 2001 +From: Andreas Gruenbacher +Date: Mon, 5 Mar 2018 06:18:25 -0700 +Subject: gfs2: Fixes to "Implement iomap for block_map" (2) + +From: Andreas Gruenbacher + +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 +Signed-off-by: Bob Peterson +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-4.15/series b/queue-4.15/series index 0c544c58593..a23ed4fd16c 100644 --- a/queue-4.15/series +++ b/queue-4.15/series @@ -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