From patchwork Mon Feb 11 12:54:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 10805671 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CB66D13A4 for ; Mon, 11 Feb 2019 12:54:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BA5062A1FB for ; Mon, 11 Feb 2019 12:54:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AED3A2A206; Mon, 11 Feb 2019 12:54:48 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 2A1452A1FB for ; Mon, 11 Feb 2019 12:54:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727611AbfBKMyr (ORCPT ); Mon, 11 Feb 2019 07:54:47 -0500 Received: from bombadil.infradead.org ([198.137.202.133]:35190 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727106AbfBKMyr (ORCPT ); Mon, 11 Feb 2019 07:54:47 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20170209; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From :Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=0UKOUQzK1Ug5/qYx3vElWwKs4Ztb4c49ugcx7yleKtg=; b=ogK2lNZvv44hnBB2qi/CxMrp4R l1cMjSs/5NrBPv5Jl9aqFYxWV0PGvjmBVv6OBhGmzs54WJNEu0dfP3Wxn7axjL317Uj2CL+XYmJPf eQU2GyifhqzBShyWZp7dn9HSMB4PLPEFp9RSdqIuAMtQQ75Iq3Nj9P9cVdyr/I93meakc1TsP4xOr X92Cz5HcSZpcK45EEHhUmyc/Deq2w593wEXoYbVZyudVTFAqvWv2HjmiUy5Rn9CotogQ9xrjbDVDQ TpXBSqjf4pyvguy4Lyv5cfaScjO9cW3i1/kHO4sgTt9hhfV0tXv29vkZspFBOB9ajrdGk/miM8xHM phZDH5Gw==; Received: from 089144210182.atnat0019.highway.a1.net ([89.144.210.182] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.90_1 #2 (Red Hat Linux)) id 1gtB6j-0003PJ-C6; Mon, 11 Feb 2019 12:54:45 +0000 From: Christoph Hellwig To: linux-xfs@vger.kernel.org Cc: Brian Foster Subject: [PATCH 05/10] xfs: split XFS_BMAPI_DELALLOC handling from xfs_bmapi_write Date: Mon, 11 Feb 2019 13:54:22 +0100 Message-Id: <20190211125427.16577-6-hch@lst.de> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190211125427.16577-1-hch@lst.de> References: <20190211125427.16577-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html 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 Delalloc conversion has traditionally been part of our function to allocate blocks on disk (first xfs_bmapi, then xfs_bmapi_write), but delalloc conversion is a little special as we really do not want to allocate blocks over holes, for which we don't have reservations. Split the delalloc conversions into a separate helper to keep the code simple and structured. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster --- fs/xfs/libxfs/xfs_bmap.c | 104 +++++++++++++++++++++------------------ fs/xfs/libxfs/xfs_bmap.h | 4 -- 2 files changed, 56 insertions(+), 52 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index a9c9bd39d822..be2cb5800e02 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -4327,22 +4327,6 @@ xfs_bmapi_write( bma.datatype = 0; bma.minleft = xfs_bmapi_minleft(tp, ip, whichfork); - /* - * The delalloc flag means the caller wants to allocate the entire - * delalloc extent backing bno where bno may not necessarily match the - * startoff. Now that we've looked up the extent, reset the range to - * map based on the extent in the file. If we're in a hole, this may be - * an error so don't adjust anything. - */ - if ((flags & XFS_BMAPI_DELALLOC) && - !eof && bno >= bma.got.br_startoff) { - bno = bma.got.br_startoff; - len = bma.got.br_blockcount; -#ifdef DEBUG - orig_bno = bno; - orig_len = len; -#endif - } n = 0; end = bno + len; obno = bno; @@ -4359,26 +4343,7 @@ xfs_bmapi_write( ASSERT(!((flags & XFS_BMAPI_CONVERT) && (flags & XFS_BMAPI_COWFORK))); - if (flags & XFS_BMAPI_DELALLOC) { - /* - * For the COW fork we can reasonably get a - * request for converting an extent that races - * with other threads already having converted - * part of it, as there converting COW to - * regular blocks is not protected using the - * IOLOCK. - */ - ASSERT(flags & XFS_BMAPI_COWFORK); - if (!(flags & XFS_BMAPI_COWFORK)) { - error = -EIO; - goto error0; - } - - if (eof || bno >= end) - break; - } else { - need_alloc = true; - } + need_alloc = true; } else if (isnullstartblock(bma.got.br_startblock)) { wasdelay = true; } @@ -4487,23 +4452,66 @@ xfs_bmapi_convert_delalloc( int whichfork, struct xfs_bmbt_irec *imap) { - int flags = XFS_BMAPI_DELALLOC; - int nimaps = 1; + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); + struct xfs_bmalloca bma = { NULL }; int error; - int total = XFS_EXTENTADD_SPACE_RES(ip->i_mount, - XFS_DATA_FORK); - if (whichfork == XFS_COW_FORK) - flags |= XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC; + if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &bma.icur, &bma.got) || + bma.got.br_startoff > offset_fsb) { + /* + * No extent found in the range we are trying to convert. This + * should only happen for the COW fork, where another thread + * might have moved the extent to the data fork in the meantime. + */ + WARN_ON_ONCE(whichfork != XFS_COW_FORK); + return -EAGAIN; + } /* - * The delalloc flag means to allocate the entire extent; pass a dummy - * length of 1. + * If we find a real extent here we raced with another thread converting + * the extent. Just return the real extent at this offset. */ - error = xfs_bmapi_write(tp, ip, offset_fsb, 1, flags, total, imap, - &nimaps); - if (!error && !nimaps) - error = -EFSCORRUPTED; + if (!isnullstartblock(bma.got.br_startblock)) { + *imap = bma.got; + return 0; + } + + bma.tp = tp; + bma.ip = ip; + bma.wasdel = true; + bma.offset = bma.got.br_startoff; + bma.length = max_t(xfs_filblks_t, bma.got.br_blockcount, MAXEXTLEN); + bma.total = XFS_EXTENTADD_SPACE_RES(ip->i_mount, XFS_DATA_FORK); + bma.minleft = xfs_bmapi_minleft(tp, ip, whichfork); + if (whichfork == XFS_COW_FORK) + bma.flags = XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC; + + if (!xfs_iext_peek_prev_extent(ifp, &bma.icur, &bma.prev)) + bma.prev.br_startoff = NULLFILEOFF; + + error = xfs_bmapi_allocate(&bma); + if (error) + goto out_finish; + if (WARN_ON_ONCE(bma.blkno == NULLFSBLOCK)) { + error = -ENOSPC; + goto out_finish; + } + + ASSERT(!isnullstartblock(bma.got.br_startblock)); + ASSERT(bma.got.br_startblock || XFS_IS_REALTIME_INODE(ip)); + *imap = bma.got; + + if (whichfork == XFS_COW_FORK) { + error = xfs_refcount_alloc_cow_extent(tp, bma.blkno, + bma.length); + if (error) + goto out_finish; + } + + error = xfs_bmap_btree_to_extents(tp, ip, bma.cur, &bma.logflags, + whichfork); +out_finish: + xfs_bmapi_finish(&bma, whichfork, error); return error; } diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 4dc7d1a02b35..b5eca7a26949 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -95,9 +95,6 @@ struct xfs_extent_free_item /* Map something in the CoW fork. */ #define XFS_BMAPI_COWFORK 0x200 -/* Only convert delalloc space, don't allocate entirely new extents */ -#define XFS_BMAPI_DELALLOC 0x400 - /* Only convert unwritten extents, don't allocate new blocks */ #define XFS_BMAPI_CONVERT_ONLY 0x800 @@ -117,7 +114,6 @@ struct xfs_extent_free_item { XFS_BMAPI_ZERO, "ZERO" }, \ { XFS_BMAPI_REMAP, "REMAP" }, \ { XFS_BMAPI_COWFORK, "COWFORK" }, \ - { XFS_BMAPI_DELALLOC, "DELALLOC" }, \ { XFS_BMAPI_CONVERT_ONLY, "CONVERT_ONLY" }, \ { XFS_BMAPI_NODISCARD, "NODISCARD" }, \ { XFS_BMAPI_NORMAP, "NORMAP" }