From patchwork Thu Nov 17 23:55:32 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 9486439 X-Mozilla-Keys: nonjunk Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on sandeen.net X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,RP_MATCHES_RCVD autolearn=ham autolearn_force=no version=3.4.0 X-Spam-HP: BAYES_00=-1.9,HEADER_FROM_DIFFERENT_DOMAINS=0.001, RP_MATCHES_RCVD=-0.1 X-Original-To: sandeen@sandeen.net Delivered-To: sandeen@sandeen.net Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by sandeen.net (Postfix) with ESMTP id 87DFB6F7BCA for ; Thu, 17 Nov 2016 17:56:33 -0600 (CST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752723AbcKQX5G (ORCPT ); Thu, 17 Nov 2016 18:57:06 -0500 Received: from ipmail06.adl2.internode.on.net ([150.101.137.129]:34021 "EHLO ipmail06.adl2.internode.on.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752747AbcKQX5F (ORCPT ); Thu, 17 Nov 2016 18:57:05 -0500 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoAzAAtDLlh5LIq7EGdsb2JhbABeHAEBBAEBCgEBgzcBAQEBAR+BWIZ0nDMBAQEBAQEGgRySVoxVVAECAQEBAQECBgEBAQEBAQEBN0WEaQYnLzMIGDE5AwcUGYhrrlQ9jAmFcoo5hRUFmkOQb5AkkVuBQxEMgnABC4JTKjSHeQEBAQ Received: from ppp121-44-138-187.lns20.syd7.internode.on.net (HELO dastard) ([121.44.138.187]) by ipmail06.adl2.internode.on.net with ESMTP; 18 Nov 2016 10:25:41 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1c7WWq-0008NP-Od for linux-xfs@vger.kernel.org; Fri, 18 Nov 2016 10:55:40 +1100 Received: from dave by disappointment with local (Exim 4.87) (envelope-from ) id 1c7WWr-00020E-Lr for linux-xfs@vger.kernel.org; Fri, 18 Nov 2016 10:55:41 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 1/4] xfs: factor rmap btree size into the indlen calculations Date: Fri, 18 Nov 2016 10:55:32 +1100 Message-Id: <1479426935-7112-2-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.8.0.rc3 In-Reply-To: <1479426935-7112-1-git-send-email-david@fromorbit.com> References: <20161117213224.GD28177@dastard> <1479426935-7112-1-git-send-email-david@fromorbit.com> Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: "Darrick J. Wong" When we're estimating the amount of space it's going to take to satisfy a delalloc reservation, we need to include the space that we might need to grow the rmapbt. This helps us to avoid running out of space later when _iomap_write_allocate needs more space than we reserved. Eryu Guan observed this happening on generic/224 when sunit/swidth were set. Reported-by: Eryu Guan Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_bmap.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 5c3c4dd14735..00188f559c8d 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -49,6 +49,7 @@ #include "xfs_rmap.h" #include "xfs_ag_resv.h" #include "xfs_refcount.h" +#include "xfs_rmap_btree.h" kmem_zone_t *xfs_bmap_free_item_zone; @@ -190,8 +191,12 @@ xfs_bmap_worst_indlen( int maxrecs; /* maximum record count at this level */ xfs_mount_t *mp; /* mount structure */ xfs_filblks_t rval; /* return value */ + xfs_filblks_t orig_len; mp = ip->i_mount; + + /* Calculate the worst-case size of the bmbt. */ + orig_len = len; maxrecs = mp->m_bmap_dmxr[0]; for (level = 0, rval = 0; level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK); @@ -199,12 +204,20 @@ xfs_bmap_worst_indlen( len += maxrecs - 1; do_div(len, maxrecs); rval += len; - if (len == 1) - return rval + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - + if (len == 1) { + rval += XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - level - 1; + break; + } if (level == 0) maxrecs = mp->m_bmap_dmxr[1]; } + + /* Calculate the worst-case size of the rmapbt. */ + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) + rval += 1 + xfs_rmapbt_calc_size(mp, orig_len) + + mp->m_rmap_maxlevels; + return rval; }