From patchwork Wed Oct 7 04:57:23 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 7342061 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id CAF42BEEA4 for ; Wed, 7 Oct 2015 04:57:32 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D7C2B2066D for ; Wed, 7 Oct 2015 04:57:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BB58D20504 for ; Wed, 7 Oct 2015 04:57:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751631AbbJGE53 (ORCPT ); Wed, 7 Oct 2015 00:57:29 -0400 Received: from aserp1040.oracle.com ([141.146.126.69]:35891 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752475AbbJGE53 (ORCPT ); Wed, 7 Oct 2015 00:57:29 -0400 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974vQAm006435 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:57:27 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974vQKH022559 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:57:26 GMT Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974vQ8k003221; Wed, 7 Oct 2015 04:57:26 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:57:26 -0700 Subject: [PATCH 21/58] xfs: teach rmap_alloc how to deal with our larger rmap btree From: "Darrick J. Wong" To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:57:23 -0700 Message-ID: <20151007045723.30457.72844.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Source-IP: aserv0021.oracle.com [141.146.126.233] Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Since reflink will require the rmapbt to mirror bmbt entries exactly, the xfs_rmap_alloc function is only necessary to handle rmaps for bmbt blocks and AG btrees. Therefore, enhancing the function (and its extent merging code) to handle the larger rmap records can be done simply. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_rmap.c | 50 +++++++++++++++++++++++++++++++--------- fs/xfs/libxfs/xfs_rmap_btree.h | 1 + 2 files changed, 40 insertions(+), 11 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index d1b6c82..bc25f9c 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -145,16 +145,34 @@ out_error: } /* - * When we allocate a new block, the first thing we do is add a reference to the - * extent in the rmap btree. This takes the form of a [agbno, length, owner] - * record. Newly inserted extents should never overlap with an existing extent - * in the rmap btree. Hence the insertion is a relatively trivial exercise, - * involving checking for adjacent records and merging if the new extent is - * contiguous and has the same owner. - * - * Note that we have no MAXEXTLEN limits here when merging as the length in the - * record has the full 32 bits available and hence a single record can track the - * entire space in the AG. + * A mergeable rmap should have the same owner, cannot be unwritten, and + * must be a bmbt rmap if we're asking about a bmbt rmap. + */ +static bool +is_mergeable_rmap( + struct xfs_rmap_irec *irec, + uint64_t owner, + uint64_t offset) +{ + if (irec->rm_owner == XFS_RMAP_OWN_NULL) + return false; + if (irec->rm_owner != owner) + return false; + if (XFS_RMAP_IS_UNWRITTEN(irec->rm_blockcount)) + return false; + if (XFS_RMAP_IS_ATTR_FORK(offset) ^ + XFS_RMAP_IS_ATTR_FORK(irec->rm_offset)) + return false; + if (XFS_RMAP_IS_BMBT(offset) ^ XFS_RMAP_IS_BMBT(irec->rm_offset)) + return false; + return true; +} + +/* + * When we allocate a new block, the first thing we do is add a reference to + * the extent in the rmap btree. This takes the form of a [agbno, length, + * owner, offset] record. Flags are encoded in the high bits of the offset + * field. */ int xfs_rmap_alloc( @@ -172,6 +190,8 @@ xfs_rmap_alloc( int have_gt; int error = 0; int i; + uint64_t owner; + uint64_t offset; if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) return 0; @@ -179,12 +199,14 @@ xfs_rmap_alloc( trace_xfs_rmap_alloc_extent(mp, agno, bno, len, oinfo); cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); + xfs_owner_info_unpack(oinfo, &owner, &offset); + ASSERT(XFS_RMAP_NON_INODE_OWNER(owner) || XFS_RMAP_IS_BMBT(offset)); /* * For the initial lookup, look for and exact match or the left-adjacent * record for our insertion point. This will also give us the record for * start block contiguity tests. */ - error = xfs_rmap_lookup_le(cur, bno, len, owner, &i); + error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, &i); if (error) goto out_error; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); @@ -196,8 +218,11 @@ xfs_rmap_alloc( //printk("rmalloc ag %d bno 0x%x/0x%x/0x%llx, ltrec 0x%x/0x%x/0x%llx\n", // agno, bno, len, owner, ltrec.rm_startblock, // ltrec.rm_blockcount, ltrec.rm_owner); + if (!is_mergeable_rmap(<rec, owner, offset)) + ltrec.rm_owner = XFS_RMAP_OWN_NULL; XFS_WANT_CORRUPTED_GOTO(mp, + ltrec.rm_owner == XFS_RMAP_OWN_NULL || ltrec.rm_startblock + ltrec.rm_blockcount <= bno, out_error); /* @@ -221,6 +246,8 @@ xfs_rmap_alloc( } else { gtrec.rm_owner = XFS_RMAP_OWN_NULL; } + if (!is_mergeable_rmap(>rec, owner, offset)) + gtrec.rm_owner = XFS_RMAP_OWN_NULL; /* * Note: cursor currently points one record to the right of ltrec, even @@ -291,6 +318,7 @@ xfs_rmap_alloc( cur->bc_rec.r.rm_startblock = bno; cur->bc_rec.r.rm_blockcount = len; cur->bc_rec.r.rm_owner = owner; + cur->bc_rec.r.rm_offset = offset; error = xfs_btree_insert(cur, &i); if (error) goto out_error; diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h index a5c97f8..0dfc151 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.h +++ b/fs/xfs/libxfs/xfs_rmap_btree.h @@ -58,6 +58,7 @@ int xfs_rmap_lookup_eq(struct xfs_btree_cur *cur, xfs_agblock_t bno, int xfs_rmap_get_rec(struct xfs_btree_cur *cur, struct xfs_rmap_irec *irec, int *stat); +/* functions for updating the rmapbt for bmbt blocks and AG btree blocks */ int xfs_rmap_alloc(struct xfs_trans *tp, struct xfs_buf *agbp, xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, struct xfs_owner_info *oinfo);