From patchwork Sun Mar 31 14:24:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Lyakas X-Patchwork-Id: 10878769 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 C4D0614DE for ; Sun, 31 Mar 2019 14:25:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AE2D728534 for ; Sun, 31 Mar 2019 14:25:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A27FC287E0; Sun, 31 Mar 2019 14:25:35 +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.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,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 31EF228534 for ; Sun, 31 Mar 2019 14:25:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731176AbfCaOZe (ORCPT ); Sun, 31 Mar 2019 10:25:34 -0400 Received: from mail-wr1-f68.google.com ([209.85.221.68]:34213 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731172AbfCaOZe (ORCPT ); Sun, 31 Mar 2019 10:25:34 -0400 Received: by mail-wr1-f68.google.com with SMTP id p10so8514748wrq.1 for ; Sun, 31 Mar 2019 07:25:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zadara-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id; bh=pWs2bUQ64f/gNRuDNVO2VtX9fwrIlFWcml7DBb+rcTo=; b=ooYgu3znGl4CjpheY8fmTJnl+mcsRb/hM1K/FKdqVX1qtrCdizRip//2M/iolBFC4D ydezR0RAg9+8mqnKHPk7Vczo+EamqW8MtQ/mfG1C6kGCXflGojneWhpRQGPVHL5JLJqJ CnHgcNImXCp3lWvb2nXMb2S7/gedwCmZ6yMnkqBLabyYXhCiKdx7cK4gZzNpH/nalIAj NM6RsFbMtboMMKVLHxPjF3IkbnVCZr9Lry1CEkOB2CLmDuvsebYpHG8UNyKF9XcBSwdR NQFP95afscW6v4uA5CtrkQEEgIl5lI/B7wx4bybvSggC/+CeHPuRdjQP9MnQ1+l3VKoF QkKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=pWs2bUQ64f/gNRuDNVO2VtX9fwrIlFWcml7DBb+rcTo=; b=VBn1EDpEoHTtuyQWdTOT6MNYQWL4UuAZUhrXDlfg7IOydrVndA7oQKR2Nip4so5YYP uxRuRPEk9d3+mEddbxBalHMM15OEJLV4Tcar94FL4fLCVFRAA61SnUz5LHwVOfU5iDLZ YrpSoZTU6lEZsLsUiIxwQl4FdjW2WkPHRMycWD9tnH0V0wRVg2BMf9pJPAkx++w4jwb9 PTLImqUcMMnHh8K2/SsQgPa6/9SPIXKRYKeoPMY5t2y7+nZmnVpKpf7ByUvv3kgHBghO zUjSWimPB21MkmwbR5PGSlaKCjphWigLsxOcKs1gFbAIxniMVuTgJpBjBTn6zlguv7ap UaKQ== X-Gm-Message-State: APjAAAUBTA4o4lYTebrMABA3KE6RbUC862ObJqWEcb1qf+HpqK3Y6JK9 Z24AMH8uq1eSOIGSD78IBWowkcQQHwk= X-Google-Smtp-Source: APXvYqxP9bIwDqKILL28oQQ79HPQHCMoRzaIyCjfHF256Yqf/VIrTNsc72U5M3G0zrD1W0/W6O68aw== X-Received: by 2002:a5d:4a4f:: with SMTP id v15mr35774580wrs.5.1554042332699; Sun, 31 Mar 2019 07:25:32 -0700 (PDT) Received: from localhost.localdomain ([82.166.81.77]) by smtp.gmail.com with ESMTPSA id o4sm16904218wmo.20.2019.03.31.07.25.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 31 Mar 2019 07:25:32 -0700 (PDT) From: Alex Lyakas To: linux-xfs@vger.kernel.org Cc: stable@vger.kernel.org, darrick.wong@oracle.com, hch@lst.de, shyam@zadara.com Subject: [STABLE PATCH 1/2] xfs: add the ability to join a held buffer to a defer_ops Date: Sun, 31 Mar 2019 17:24:42 +0300 Message-Id: <1554042282-3344-1-git-send-email-alex@zadara.com> X-Mailer: git-send-email 1.9.1 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 From: "Darrick J. Wong" In certain cases, defer_ops callers will lock a buffer and want to hold the lock across transaction rolls. Similar to ijoined inodes, we want to dirty & join the buffer with each transaction roll in defer_finish so that afterwards the caller still owns the buffer lock and we haven't inadvertently pinned the log. Signed-off-by: Darrick J. Wong Signed-off-by: Alex Lyakas --- fs/xfs/libxfs/xfs_defer.c | 39 ++++++++++++++++++++++++++++++++++++--- fs/xfs/libxfs/xfs_defer.h | 5 ++++- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index 072ebfe..087fea0 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -249,6 +249,10 @@ for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) xfs_trans_log_inode(*tp, dop->dop_inodes[i], XFS_ILOG_CORE); + /* Hold the (previously bjoin'd) buffer locked across the roll. */ + for (i = 0; i < XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++) + xfs_trans_dirty_buf(*tp, dop->dop_bufs[i]); + trace_xfs_defer_trans_roll((*tp)->t_mountp, dop); /* Roll the transaction. */ @@ -264,6 +268,12 @@ for (i = 0; i < XFS_DEFER_OPS_NR_INODES && dop->dop_inodes[i]; i++) xfs_trans_ijoin(*tp, dop->dop_inodes[i], 0); + /* Rejoin the buffers and dirty them so the log moves forward. */ + for (i = 0; i < XFS_DEFER_OPS_NR_BUFS && dop->dop_bufs[i]; i++) { + xfs_trans_bjoin(*tp, dop->dop_bufs[i]); + xfs_trans_bhold(*tp, dop->dop_bufs[i]); + } + return error; } @@ -295,6 +305,31 @@ } } + ASSERT(0); + return -EFSCORRUPTED; +} + +/* + * Add this buffer to the deferred op. Each joined buffer is relogged + * each time we roll the transaction. + */ +int +xfs_defer_bjoin( + struct xfs_defer_ops *dop, + struct xfs_buf *bp) +{ + int i; + + for (i = 0; i < XFS_DEFER_OPS_NR_BUFS; i++) { + if (dop->dop_bufs[i] == bp) + return 0; + else if (dop->dop_bufs[i] == NULL) { + dop->dop_bufs[i] = bp; + return 0; + } + } + + ASSERT(0); return -EFSCORRUPTED; } @@ -493,9 +528,7 @@ struct xfs_defer_ops *dop, xfs_fsblock_t *fbp) { - dop->dop_committed = false; - dop->dop_low = false; - memset(&dop->dop_inodes, 0, sizeof(dop->dop_inodes)); + memset(dop, 0, sizeof(struct xfs_defer_ops)); *fbp = NULLFSBLOCK; INIT_LIST_HEAD(&dop->dop_intake); INIT_LIST_HEAD(&dop->dop_pending); diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index d4f046d..045beac 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -59,6 +59,7 @@ enum xfs_defer_ops_type { }; #define XFS_DEFER_OPS_NR_INODES 2 /* join up to two inodes */ +#define XFS_DEFER_OPS_NR_BUFS 2 /* join up to two buffers */ struct xfs_defer_ops { bool dop_committed; /* did any trans commit? */ @@ -66,8 +67,9 @@ struct xfs_defer_ops { struct list_head dop_intake; /* unlogged pending work */ struct list_head dop_pending; /* logged pending work */ - /* relog these inodes with each roll */ + /* relog these with each roll */ struct xfs_inode *dop_inodes[XFS_DEFER_OPS_NR_INODES]; + struct xfs_buf *dop_bufs[XFS_DEFER_OPS_NR_BUFS]; }; void xfs_defer_add(struct xfs_defer_ops *dop, enum xfs_defer_ops_type type, @@ -77,6 +79,7 @@ void xfs_defer_add(struct xfs_defer_ops *dop, enum xfs_defer_ops_type type, void xfs_defer_init(struct xfs_defer_ops *dop, xfs_fsblock_t *fbp); bool xfs_defer_has_unfinished_work(struct xfs_defer_ops *dop); int xfs_defer_ijoin(struct xfs_defer_ops *dop, struct xfs_inode *ip); +int xfs_defer_bjoin(struct xfs_defer_ops *dop, struct xfs_buf *bp); /* Description of a deferred type. */ struct xfs_defer_op_type {