4.15-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Andreas Gruenbacher <agrue...@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 <agrue...@redhat.com>
Signed-off-by: Bob Peterson <rpete...@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gre...@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


Reply via email to