From patchwork Sat Jan 21 08:01:32 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 9529855 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 11CB66020B for ; Sat, 21 Jan 2017 08:01:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 012AD283B9 for ; Sat, 21 Jan 2017 08:01:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EA28328695; Sat, 21 Jan 2017 08:01:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5F3BF283B9 for ; Sat, 21 Jan 2017 08:01:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751057AbdAUIBf (ORCPT ); Sat, 21 Jan 2017 03:01:35 -0500 Received: from aserp1040.oracle.com ([141.146.126.69]:19338 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750888AbdAUIBf (ORCPT ); Sat, 21 Jan 2017 03:01:35 -0500 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id v0L81Xoa012326 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sat, 21 Jan 2017 08:01:34 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.14.4/8.14.4) with ESMTP id v0L81XMF017705 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sat, 21 Jan 2017 08:01:33 GMT Received: from abhmp0009.oracle.com (abhmp0009.oracle.com [141.146.116.15]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id v0L81Xha005923; Sat, 21 Jan 2017 08:01:33 GMT Received: from localhost (/24.21.211.40) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sat, 21 Jan 2017 00:01:33 -0800 Subject: [PATCH 12/55] xfs: getfsmap should fall back to rtbitmap when rtrmapbt not present From: "Darrick J. Wong" To: darrick.wong@oracle.com Cc: linux-xfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Date: Sat, 21 Jan 2017 00:01:32 -0800 Message-ID: <148498569216.15323.10718959099721377354.stgit@birch.djwong.org> In-Reply-To: <148498561504.15323.8531512066874274553.stgit@birch.djwong.org> References: <148498561504.15323.8531512066874274553.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Source-IP: userv0022.oracle.com [156.151.31.74] Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Use the realtime bitmap to return freespace information when the rtrmapbt isn't present. Note that the rtrmapbt fsmap implementation will show up later with the rtrmapbt patchset. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_fsmap.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_rtalloc.h | 2 + 2 files changed, 135 insertions(+) -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" 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/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c index 4e364f8..ba5544b 100644 --- a/fs/xfs/xfs_fsmap.c +++ b/fs/xfs/xfs_fsmap.c @@ -40,6 +40,7 @@ #include "xfs_refcount.h" #include "xfs_refcount_btree.h" #include "xfs_alloc_btree.h" +#include "xfs_rtalloc.h" /* Convert an xfs_fsmap to an fsmap. */ void @@ -398,6 +399,29 @@ xfs_getfsmap_rtdev_helper( return xfs_getfsmap_helper(mp, info, rec, rec_daddr); } +/* Transform a rtbitmap "record" into a fsmap */ +STATIC int +xfs_getfsmap_rtdev_rtbitmap_helper( + struct xfs_mount *mp, + xfs_rtblock_t start, + xfs_rtblock_t end, + void *priv) +{ + struct xfs_getfsmap_info *info = priv; + struct xfs_rmap_irec irec; + xfs_daddr_t rec_daddr; + + rec_daddr = XFS_FSB_TO_BB(mp, start); + + irec.rm_startblock = start; + irec.rm_blockcount = end - start + 1; + irec.rm_owner = XFS_RMAP_OWN_NULL; /* "free" */ + irec.rm_offset = 0; + irec.rm_flags = 0; + + return xfs_getfsmap_helper(mp, info, &irec, rec_daddr); +} + /* Transform a bnobt irec into a fsmap */ STATIC int xfs_getfsmap_datadev_bnobt_helper( @@ -496,6 +520,108 @@ xfs_getfsmap_logdev( return xfs_getfsmap_rtdev_helper(&cur, &rmap, info); } +/* Execute a getfsmap query against the realtime data device (rtbitmap). */ +STATIC int +xfs_getfsmap_rtdev_rtbitmap( + struct xfs_trans *tp, + struct xfs_fsmap *keys, + struct xfs_getfsmap_info *info) +{ + struct xfs_mount *mp = tp->t_mountp; + struct xfs_fsmap *dkey_low; + struct xfs_fsmap *dkey_high; + xfs_fsblock_t start_fsb; + xfs_fsblock_t end_fsb; + xfs_rtblock_t rtstart; + xfs_rtblock_t rtend; + xfs_rtblock_t rem; + xfs_daddr_t eofs; + int is_free; + int error = 0; + + dkey_low = keys; + dkey_high = keys + 1; + eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks); + if (dkey_low->fmr_physical >= eofs) + return 0; + if (dkey_high->fmr_physical >= eofs) + dkey_high->fmr_physical = eofs - 1; + start_fsb = XFS_BB_TO_FSBT(mp, dkey_low->fmr_physical); + end_fsb = XFS_BB_TO_FSB(mp, dkey_high->fmr_physical); + + /* Set up search keys */ + info->low.rm_startblock = start_fsb; + error = xfs_fsmap_owner_to_rmap(dkey_low, &info->low); + if (error) + return error; + info->low.rm_offset = XFS_BB_TO_FSBT(mp, dkey_low->fmr_offset); + info->low.rm_blockcount = 0; + xfs_getfsmap_set_irec_flags(&info->low, dkey_low); + + info->high.rm_startblock = end_fsb; + error = xfs_fsmap_owner_to_rmap(dkey_high, &info->high); + if (error) + return error; + info->high.rm_offset = XFS_BB_TO_FSBT(mp, dkey_high->fmr_offset); + info->high.rm_blockcount = 0; + xfs_getfsmap_set_irec_flags(&info->high, dkey_high); + + info->missing_owner = FMR_OWN_UNKNOWN; + + trace_xfs_fsmap_low_key(mp, info->dev, info->agno, + info->low.rm_startblock, + info->low.rm_blockcount, + info->low.rm_owner, + info->low.rm_offset); + + trace_xfs_fsmap_high_key(mp, info->dev, info->agno, + info->high.rm_startblock, + info->high.rm_blockcount, + info->high.rm_owner, + info->high.rm_offset); + + xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); + + /* Iterate the bitmap, looking for discrepancies. */ + rtstart = 0; + rem = mp->m_sb.sb_rblocks; + while (rem) { + /* Is the first block free? */ + error = xfs_rtcheck_range(mp, tp, rtstart, 1, 1, &rtend, + &is_free); + if (error) + goto out_unlock; + + /* How long does the extent go for? */ + error = xfs_rtfind_forw(mp, tp, rtstart, + mp->m_sb.sb_rblocks - 1, &rtend); + if (error) + goto out_unlock; + + if (is_free) { + error = xfs_getfsmap_rtdev_rtbitmap_helper(mp, + rtstart, rtend, info); + if (error) + goto out_unlock; + } + + rem -= rtend - rtstart + 1; + rtstart = rtend + 1; + } + +out_unlock: + xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); + + /* Report any free space at the end of the rtdev */ + info->last = true; + error = xfs_getfsmap_rtdev_rtbitmap_helper(mp, end_fsb, 0, info); + if (error) + goto err; + +err: + return error; +} + /* Execute a getfsmap query against the regular data device. */ STATIC int xfs_getfsmap_datadev( @@ -741,6 +867,9 @@ xfs_getfsmap_is_valid_device( if (mp->m_logdev_targp && fm->fmr_device == new_encode_dev(mp->m_logdev_targp->bt_dev)) return true; + if (mp->m_rtdev_targp && + fm->fmr_device == new_encode_dev(mp->m_rtdev_targp->bt_dev)) + return true; return false; } @@ -818,6 +947,10 @@ xfs_getfsmap( handlers[1].dev = new_encode_dev(mp->m_logdev_targp->bt_dev); handlers[1].fn = xfs_getfsmap_logdev; } + if (mp->m_rtdev_targp) { + handlers[2].dev = new_encode_dev(mp->m_rtdev_targp->bt_dev); + handlers[2].fn = xfs_getfsmap_rtdev_rtbitmap; + } xfs_sort(handlers, XFS_GETFSMAP_DEVS, sizeof(struct xfs_getfsmap_dev), xfs_getfsmap_dev_compare); diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h index 355dd9e..f798a3e 100644 --- a/fs/xfs/xfs_rtalloc.h +++ b/fs/xfs/xfs_rtalloc.h @@ -126,6 +126,8 @@ int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp, # define xfs_rtfree_extent(t,b,l) (ENOSYS) # define xfs_rtpick_extent(m,t,l,rb) (ENOSYS) # define xfs_growfs_rt(mp,in) (ENOSYS) +# define xfs_rtcheck_range(...) (ENOSYS) +# define xfs_rtfind_forw(...) (ENOSYS) static inline int /* error */ xfs_rtmount_init( xfs_mount_t *mp) /* file system mount structure */