The previous attempt to fix for metadata read-ahead during truncate was
incorrect: for files with a height > 2 (1006989312 bytes with a block
size of 4096 bytes), read-ahead requests were not being issued for some
of the indirect blocks discovered while walking the metadata tree,
leading to significant slow-downs when deleting large files.  Fix that.

In addition, only issue read-ahead requests in the first pass through
the meta-data tree, while deallocating data blocks.

Fixes: c3ce5aa9b0 ("gfs2: Fix metadata read-ahead during truncate")
Cc: sta...@vger.kernel.org # v4.16+
Signed-off-by: Andreas Gruenbacher <agrue...@redhat.com>
---
 fs/gfs2/bmap.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 5f3ea07ef5e2..38d88fcb6988 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -1908,10 +1908,16 @@ static int punch_hole(struct gfs2_inode *ip, u64 
offset, u64 length)
                        if (ret < 0)
                                goto out;
 
-                       /* issue read-ahead on metadata */
-                       if (mp.mp_aheight > 1) {
-                               for (; ret > 1; ret--) {
-                                       metapointer_range(&mp, mp.mp_aheight - 
ret,
+                       /* On the first pass, issue read-ahead on metadata. */
+                       if (mp.mp_aheight > 1 && strip_h == ip->i_height - 1) {
+                               unsigned int height = mp.mp_aheight - 1;
+
+                               /* No read-ahead for data blocks. */
+                               if (mp.mp_aheight - 1 == strip_h)
+                                       height--;
+
+                               for (; height >= mp.mp_aheight - ret; height--) 
{
+                                       metapointer_range(&mp, height,
                                                          start_list, 
start_aligned,
                                                          end_list, end_aligned,
                                                          &start, &end);
-- 
2.19.1.546.g028f9c799.dirty

Reply via email to