From patchwork Tue Oct 3 15:06:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Timofey Titovets X-Patchwork-Id: 9983031 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 8EC9C60375 for ; Tue, 3 Oct 2017 15:07:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 80DBD287D2 for ; Tue, 3 Oct 2017 15:07:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 759C228806; Tue, 3 Oct 2017 15:07:14 +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.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID 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 155A7287D2 for ; Tue, 3 Oct 2017 15:07:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752176AbdJCPHL (ORCPT ); Tue, 3 Oct 2017 11:07:11 -0400 Received: from mail-lf0-f67.google.com ([209.85.215.67]:51713 "EHLO mail-lf0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751874AbdJCPHH (ORCPT ); Tue, 3 Oct 2017 11:07:07 -0400 Received: by mail-lf0-f67.google.com with SMTP id m142so6294093lfg.8 for ; Tue, 03 Oct 2017 08:07:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=vj6PdN/ON/TuhRE/xqTzodzXOavfXuUvZxzRfDmCWo4=; b=rVZEh64X4YWOUjdJd/XDSglO7EePxCAEAIUKyTtUyTZBdxX+JmuiHVbu6oZHvbCac6 AS7UW5/fcvBrnjYhdlQiZ0PWY/SmAJ71eeEpzFOrvq4RzUm070vj+/eeK1pfIRafrrsW fdFKMPdfyK/oC7jCFLGCM9VMpw8EeE+T61jwSLM6hWBudm9buODKnsHUC+gRp2iFRybl Ltxze6++VyQ7gktJuu47BQNqzfbIIzoBgjMdDsdbgYuEoSG11CvJL4eZEW7GoSE4f02W 7in2ttViE1y1KGu15V9jP/QoyopIsEKFjXihDhnhPZeeLGCNJ25ZvkmleZn00CL6jdux l72Q== 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:in-reply-to :references; bh=vj6PdN/ON/TuhRE/xqTzodzXOavfXuUvZxzRfDmCWo4=; b=mo9GbpCIrcaeY0fT7R1svpVRWAPwJ6Q/gWpJGwWEvswT+bRE6GgyZ7M7pOF4INXZNz 5g4eitBMhe+MPxG6Lq+H7wcEgHFv7FolD7Jh2dpRrUwQLWJCy2z3GimUsO5F3+dfaGz0 tM/OUYpFBhgpDrdI4TcAsQTUzzxz3n7weCjgw7qBJR08XvsIItj6XqlxAeV1RcG/slu8 aEhp+nWcM8qUBLmcY9h0ZCr7h2d3k95H7QYZvXMuDStMCW1D0z0sjvJ5aRRVG4SlbxOG 2I54GdeN/5wuQIEwu2iEh+/wG+IJuU7gnlSzsBms7XGK8d7kLECnil4CQS4x2SwQ2TuE h1ug== X-Gm-Message-State: AHPjjUipnE5jl9hvrPAJOJmkVQCdNu/MTGHQYLn0Gy+YNQAkZSHr0Vr2 +f+PwxnYUYQUUS1BS4WH+uysHg== X-Google-Smtp-Source: AOwi7QD1Bk/elMCfFm7ZgJi47oQiBtOEDnarkravnJ1IZJXreAkkp6oQsdsxPHwd9bpAfxurP5uNSg== X-Received: by 10.25.25.208 with SMTP id 199mr5828485lfz.106.1507043226070; Tue, 03 Oct 2017 08:07:06 -0700 (PDT) Received: from titovetst-l.itransition.corp ([93.171.6.182]) by smtp.gmail.com with ESMTPSA id t20sm2938498ljb.91.2017.10.03.08.07.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 03 Oct 2017 08:07:05 -0700 (PDT) From: Timofey Titovets To: linux-btrfs@vger.kernel.org Cc: Timofey Titovets Subject: [PATCH 2/4] Btrfs: clear_dirty only on pages only in compression range Date: Tue, 3 Oct 2017 18:06:02 +0300 Message-Id: <20171003150604.19596-3-nefelim4ag@gmail.com> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20171003150604.19596-1-nefelim4ag@gmail.com> References: <20171003150604.19596-1-nefelim4ag@gmail.com> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP We need to call extent_range_clear_dirty_for_io() on compression range to prevent application from changing page content, while pages compressing. but "(end - start)" can be much (up to 1024 times) bigger then compression range (BTRFS_MAX_UNCOMPRESSED), so optimize that by calculating compression range for that loop iteration, and flip bits only on that range v1 -> v2: - Make that more obviously and more safeprone v2 -> v3: - Rebased on: Btrfs: compress_file_range() remove dead variable num_bytes - Update change log - Add comments Signed-off-by: Timofey Titovets --- fs/btrfs/inode.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) -- 2.14.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" 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/btrfs/inode.c b/fs/btrfs/inode.c index 237df8fdf7b8..b6e81bd650ea 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -460,6 +460,7 @@ static noinline void compress_file_range(struct inode *inode, struct btrfs_root *root = BTRFS_I(inode)->root; u64 blocksize = fs_info->sectorsize; u64 actual_end; + u64 current_end; u64 isize = i_size_read(inode); int ret = 0; struct page **pages = NULL; @@ -505,6 +506,21 @@ static noinline void compress_file_range(struct inode *inode, (start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size)) goto cleanup_and_bail_uncompressed; + /* + * We need to call extent_range_clear_dirty_for_io() + * on compression range to prevent application from changing + * page content, while pages compressing. + * + * but (end - start) can be much (up to 1024 times) bigger + * then compression range, so optimize that + * by calculating compression range for + * that iteration, and flip bits only on that range + */ + if (end - start > BTRFS_MAX_UNCOMPRESSED) + current_end = start + BTRFS_MAX_UNCOMPRESSED; + else + current_end = end; + total_compressed = min_t(unsigned long, total_compressed, BTRFS_MAX_UNCOMPRESSED); total_in = 0; @@ -515,7 +531,7 @@ static noinline void compress_file_range(struct inode *inode, * inode has not been flagged as nocompress. This flag can * change at any time if we discover bad compression ratios. */ - if (inode_need_compress(inode, start, end)) { + if (inode_need_compress(inode, start, current_end)) { WARN_ON(pages); pages = kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS); if (!pages) { @@ -530,14 +546,15 @@ static noinline void compress_file_range(struct inode *inode, /* * we need to call clear_page_dirty_for_io on each - * page in the range. Otherwise applications with the file - * mmap'd can wander in and change the page contents while + * page in compression the range. + * Otherwise applications with the file mmap'd + * can wander in and change the page contents while * we are compressing them. * * If the compression fails for any reason, we set the pages * dirty again later on. */ - extent_range_clear_dirty_for_io(inode, start, end); + extent_range_clear_dirty_for_io(inode, start, current_end); redirty = 1; /* Compression level is applied here and only here */ @@ -678,7 +695,7 @@ static noinline void compress_file_range(struct inode *inode, /* unlocked later on in the async handlers */ if (redirty) - extent_range_redirty_for_io(inode, start, end); + extent_range_redirty_for_io(inode, start, current_end); add_async_extent(async_cow, start, end - start + 1, 0, NULL, 0, BTRFS_COMPRESS_NONE); *num_added += 1;