From patchwork Tue Mar 12 15:20:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Borisov X-Patchwork-Id: 10849381 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 237F21669 for ; Tue, 12 Mar 2019 15:20:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0F491291AA for ; Tue, 12 Mar 2019 15:20:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0E5FC297D9; Tue, 12 Mar 2019 15:20:40 +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,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 5DAE7297C4 for ; Tue, 12 Mar 2019 15:20:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726727AbfCLPUi (ORCPT ); Tue, 12 Mar 2019 11:20:38 -0400 Received: from mx2.suse.de ([195.135.220.15]:41138 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726427AbfCLPUh (ORCPT ); Tue, 12 Mar 2019 11:20:37 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 6D437B69C for ; Tue, 12 Mar 2019 15:20:35 +0000 (UTC) From: Nikolay Borisov To: linux-btrfs@vger.kernel.org Cc: Nikolay Borisov Subject: [PATCH 1/7] btrfs: Preallocate chunks in cow_file_range_async Date: Tue, 12 Mar 2019 17:20:24 +0200 Message-Id: <20190312152030.31987-2-nborisov@suse.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190312152030.31987-1-nborisov@suse.com> References: <20190312152030.31987-1-nborisov@suse.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 This commit changes the implementation of cow_file_range_async in order to get rid of the BUG_ON in the middle of the loop. Additionally it reworks the inner loop in the hopes of making it more understandable. The idea is to make async_cow be a top-level structured, shared amongst all chunks being sent for compression. This allows to perform one memory allocation at the beginning and gracefully fail the IO if there isn't enough memory. Now, each chunk is going to be described by an async_chunk struct. It's the responsibility of the final chunk to actually free the memory. Signed-off-by: Nikolay Borisov Reviewed-by: Johannes Thumshirn --- fs/btrfs/inode.c | 105 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 71 insertions(+), 34 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 05bbfd02ea49..2c13915c6f71 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -366,7 +366,7 @@ struct async_extent { struct list_head list; }; -struct async_cow { +struct async_chunk { struct inode *inode; struct btrfs_fs_info *fs_info; struct page *locked_page; @@ -375,9 +375,15 @@ struct async_cow { unsigned int write_flags; struct list_head extents; struct btrfs_work work; + atomic_t *pending; +}; + +struct async_cow { + atomic_t num_chunks; /* Number of chunks in flight */ + struct async_chunk chunks[]; }; -static noinline int add_async_extent(struct async_cow *cow, +static noinline int add_async_extent(struct async_chunk *cow, u64 start, u64 ram_size, u64 compressed_size, struct page **pages, @@ -447,7 +453,7 @@ static inline void inode_should_defrag(struct btrfs_inode *inode, static noinline void compress_file_range(struct inode *inode, struct page *locked_page, u64 start, u64 end, - struct async_cow *async_cow, + struct async_chunk *async_cow, int *num_added) { struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); @@ -713,7 +719,7 @@ static void free_async_extent_pages(struct async_extent *async_extent) * queued. We walk all the async extents created by compress_file_range * and send them down to the disk. */ -static noinline void submit_compressed_extents(struct async_cow *async_cow) +static noinline void submit_compressed_extents(struct async_chunk *async_cow) { struct inode *inode = async_cow->inode; struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); @@ -1132,9 +1138,9 @@ static noinline int cow_file_range(struct inode *inode, */ static noinline void async_cow_start(struct btrfs_work *work) { - struct async_cow *async_cow; + struct async_chunk *async_cow; int num_added = 0; - async_cow = container_of(work, struct async_cow, work); + async_cow = container_of(work, struct async_chunk, work); compress_file_range(async_cow->inode, async_cow->locked_page, async_cow->start, async_cow->end, async_cow, @@ -1151,10 +1157,10 @@ static noinline void async_cow_start(struct btrfs_work *work) static noinline void async_cow_submit(struct btrfs_work *work) { struct btrfs_fs_info *fs_info; - struct async_cow *async_cow; + struct async_chunk *async_cow; unsigned long nr_pages; - async_cow = container_of(work, struct async_cow, work); + async_cow = container_of(work, struct async_chunk, work); fs_info = async_cow->fs_info; nr_pages = (async_cow->end - async_cow->start + PAGE_SIZE) >> @@ -1177,11 +1183,16 @@ static noinline void async_cow_submit(struct btrfs_work *work) static noinline void async_cow_free(struct btrfs_work *work) { - struct async_cow *async_cow; - async_cow = container_of(work, struct async_cow, work); + struct async_chunk *async_cow; + async_cow = container_of(work, struct async_chunk, work); if (async_cow->inode) btrfs_add_delayed_iput(async_cow->inode); - kfree(async_cow); + /* + * Since the pointer to 'pending' is at the beginning of the array of + * async_cow's, freeing it ensures the whole array has been freed. + */ + if (atomic_dec_and_test(async_cow->pending)) + kfree(async_cow->pending); } static int cow_file_range_async(struct inode *inode, struct page *locked_page, @@ -1190,45 +1201,71 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page, unsigned int write_flags) { struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); - struct async_cow *async_cow; + struct async_cow *ctx; + struct async_chunk *async_chunk; unsigned long nr_pages; u64 cur_end; + u64 num_chunks = DIV_ROUND_UP(end - start, SZ_512K); + int i; + bool should_compress; clear_extent_bit(&BTRFS_I(inode)->io_tree, start, end, EXTENT_LOCKED, 1, 0, NULL); - while (start < end) { - async_cow = kmalloc(sizeof(*async_cow), GFP_NOFS); - BUG_ON(!async_cow); /* -ENOMEM */ + + if (BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS && + !btrfs_test_opt(fs_info, FORCE_COMPRESS)) { + num_chunks = 1; + should_compress = false; + } else { + should_compress = true; + } + + ctx = kmalloc(struct_size(ctx, chunks, num_chunks), GFP_NOFS); + if (!ctx) { + unsigned clear_bits = EXTENT_LOCKED | EXTENT_DELALLOC | + EXTENT_DELALLOC_NEW | EXTENT_DEFRAG | + EXTENT_DO_ACCOUNTING; + unsigned long page_ops = PAGE_UNLOCK | PAGE_CLEAR_DIRTY | + PAGE_SET_WRITEBACK | PAGE_END_WRITEBACK | + PAGE_SET_ERROR; + extent_clear_unlock_delalloc(inode, start, end, 0, locked_page, + clear_bits, page_ops); + return -ENOMEM; + } + + async_chunk = ctx->chunks; + atomic_set(&ctx->num_chunks, num_chunks); + + for (i = 0; i < num_chunks; i++) { + + if (should_compress) + cur_end = min(end, start + SZ_512K - 1); + else + cur_end = end; + /* * igrab is called higher up in the call chain, take only the * lightweight reference for the callback lifetime */ ihold(inode); - async_cow->inode = inode; - async_cow->fs_info = fs_info; - async_cow->locked_page = locked_page; - async_cow->start = start; - async_cow->write_flags = write_flags; - - if (BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS && - !btrfs_test_opt(fs_info, FORCE_COMPRESS)) - cur_end = end; - else - cur_end = min(end, start + SZ_512K - 1); - - async_cow->end = cur_end; - INIT_LIST_HEAD(&async_cow->extents); - - btrfs_init_work(&async_cow->work, + async_chunk[i].pending= &ctx->num_chunks; + async_chunk[i].inode = inode; + async_chunk[i].start = start; + async_chunk[i].end = cur_end; + async_chunk[i].fs_info = fs_info; + async_chunk[i].locked_page = locked_page; + async_chunk[i].write_flags = write_flags; + INIT_LIST_HEAD(&async_chunk[i].extents); + + btrfs_init_work(&async_chunk[i].work, btrfs_delalloc_helper, async_cow_start, async_cow_submit, async_cow_free); - nr_pages = (cur_end - start + PAGE_SIZE) >> - PAGE_SHIFT; + nr_pages = DIV_ROUND_UP(cur_end - start, PAGE_SIZE); atomic_add(nr_pages, &fs_info->async_delalloc_pages); - btrfs_queue_work(fs_info->delalloc_workers, &async_cow->work); + btrfs_queue_work(fs_info->delalloc_workers, &async_chunk[i].work); *nr_written += nr_pages; start = cur_end + 1; From patchwork Tue Mar 12 15:20:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Borisov X-Patchwork-Id: 10849389 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 65A7D1575 for ; Tue, 12 Mar 2019 15:20:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4DDFA297CF for ; Tue, 12 Mar 2019 15:20:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4C416297D8; Tue, 12 Mar 2019 15:20:51 +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,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 B0002297CF for ; Tue, 12 Mar 2019 15:20:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726828AbfCLPUt (ORCPT ); Tue, 12 Mar 2019 11:20:49 -0400 Received: from mx2.suse.de ([195.135.220.15]:41162 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726452AbfCLPUh (ORCPT ); Tue, 12 Mar 2019 11:20:37 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id BE958B69E for ; Tue, 12 Mar 2019 15:20:35 +0000 (UTC) From: Nikolay Borisov To: linux-btrfs@vger.kernel.org Cc: Nikolay Borisov Subject: [PATCH 2/7] btrfs: Rename async_cow to async_chunk Date: Tue, 12 Mar 2019 17:20:25 +0200 Message-Id: <20190312152030.31987-3-nborisov@suse.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190312152030.31987-1-nborisov@suse.com> References: <20190312152030.31987-1-nborisov@suse.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 Now that we have an explicit async_chunk struct rename references to variables of this type to async_chunk. No functional changes. Signed-off-by: Nikolay Borisov Reviewed-by: Johannes Thumshirn --- fs/btrfs/inode.c | 60 ++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 2c13915c6f71..be3777d03c80 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -453,7 +453,7 @@ static inline void inode_should_defrag(struct btrfs_inode *inode, static noinline void compress_file_range(struct inode *inode, struct page *locked_page, u64 start, u64 end, - struct async_chunk *async_cow, + struct async_chunk *async_chunk, int *num_added) { struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); @@ -636,7 +636,7 @@ static noinline void compress_file_range(struct inode *inode, * allocation on disk for these compressed pages, and * will submit them to the elevator. */ - add_async_extent(async_cow, start, total_in, + add_async_extent(async_chunk, start, total_in, total_compressed, pages, nr_pages, compress_type); @@ -683,7 +683,7 @@ static noinline void compress_file_range(struct inode *inode, if (redirty) extent_range_redirty_for_io(inode, start, end); - add_async_extent(async_cow, start, end - start + 1, 0, NULL, 0, + add_async_extent(async_chunk, start, end - start + 1, 0, NULL, 0, BTRFS_COMPRESS_NONE); *num_added += 1; @@ -719,9 +719,9 @@ static void free_async_extent_pages(struct async_extent *async_extent) * queued. We walk all the async extents created by compress_file_range * and send them down to the disk. */ -static noinline void submit_compressed_extents(struct async_chunk *async_cow) +static noinline void submit_compressed_extents(struct async_chunk *async_chunk) { - struct inode *inode = async_cow->inode; + struct inode *inode = async_chunk->inode; struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct async_extent *async_extent; u64 alloc_hint = 0; @@ -732,8 +732,8 @@ static noinline void submit_compressed_extents(struct async_chunk *async_cow) int ret = 0; again: - while (!list_empty(&async_cow->extents)) { - async_extent = list_entry(async_cow->extents.next, + while (!list_empty(&async_chunk->extents)) { + async_extent = list_entry(async_chunk->extents.next, struct async_extent, list); list_del(&async_extent->list); @@ -750,7 +750,7 @@ static noinline void submit_compressed_extents(struct async_chunk *async_cow) async_extent->ram_size - 1); /* allocate blocks */ - ret = cow_file_range(inode, async_cow->locked_page, + ret = cow_file_range(inode, async_chunk->locked_page, async_extent->start, async_extent->start + async_extent->ram_size - 1, @@ -774,7 +774,7 @@ static noinline void submit_compressed_extents(struct async_chunk *async_cow) async_extent->ram_size - 1, WB_SYNC_ALL); else if (ret) - unlock_page(async_cow->locked_page); + unlock_page(async_chunk->locked_page); kfree(async_extent); cond_resched(); continue; @@ -861,7 +861,7 @@ static noinline void submit_compressed_extents(struct async_chunk *async_cow) ins.objectid, ins.offset, async_extent->pages, async_extent->nr_pages, - async_cow->write_flags)) { + async_chunk->write_flags)) { struct page *p = async_extent->pages[0]; const u64 start = async_extent->start; const u64 end = start + async_extent->ram_size - 1; @@ -1138,16 +1138,16 @@ static noinline int cow_file_range(struct inode *inode, */ static noinline void async_cow_start(struct btrfs_work *work) { - struct async_chunk *async_cow; + struct async_chunk *async_chunk; int num_added = 0; - async_cow = container_of(work, struct async_chunk, work); + async_chunk = container_of(work, struct async_chunk, work); - compress_file_range(async_cow->inode, async_cow->locked_page, - async_cow->start, async_cow->end, async_cow, + compress_file_range(async_chunk->inode, async_chunk->locked_page, + async_chunk->start, async_chunk->end, async_chunk, &num_added); if (num_added == 0) { - btrfs_add_delayed_iput(async_cow->inode); - async_cow->inode = NULL; + btrfs_add_delayed_iput(async_chunk->inode); + async_chunk->inode = NULL; } } @@ -1157,13 +1157,13 @@ static noinline void async_cow_start(struct btrfs_work *work) static noinline void async_cow_submit(struct btrfs_work *work) { struct btrfs_fs_info *fs_info; - struct async_chunk *async_cow; + struct async_chunk *async_chunk; unsigned long nr_pages; - async_cow = container_of(work, struct async_chunk, work); + async_chunk = container_of(work, struct async_chunk, work); - fs_info = async_cow->fs_info; - nr_pages = (async_cow->end - async_cow->start + PAGE_SIZE) >> + fs_info = async_chunk->fs_info; + nr_pages = (async_chunk->end - async_chunk->start + PAGE_SIZE) >> PAGE_SHIFT; /* atomic_sub_return implies a barrier */ @@ -1172,27 +1172,27 @@ static noinline void async_cow_submit(struct btrfs_work *work) cond_wake_up_nomb(&fs_info->async_submit_wait); /* - * ->inode could be NULL if async_cow_start has failed to compress, + * ->inode could be NULL if async_chunk_start has failed to compress, * in which case we don't have anything to submit, yet we need to * always adjust ->async_delalloc_pages as its paired with the init * happening in cow_file_range_async */ - if (async_cow->inode) - submit_compressed_extents(async_cow); + if (async_chunk->inode) + submit_compressed_extents(async_chunk); } static noinline void async_cow_free(struct btrfs_work *work) { - struct async_chunk *async_cow; - async_cow = container_of(work, struct async_chunk, work); - if (async_cow->inode) - btrfs_add_delayed_iput(async_cow->inode); + struct async_chunk *async_chunk; + async_chunk = container_of(work, struct async_chunk, work); + if (async_chunk->inode) + btrfs_add_delayed_iput(async_chunk->inode); /* * Since the pointer to 'pending' is at the beginning of the array of - * async_cow's, freeing it ensures the whole array has been freed. + * async_chunk's, freeing it ensures the whole array has been freed. */ - if (atomic_dec_and_test(async_cow->pending)) - kfree(async_cow->pending); + if (atomic_dec_and_test(async_chunk->pending)) + kfree(async_chunk->pending); } static int cow_file_range_async(struct inode *inode, struct page *locked_page, From patchwork Tue Mar 12 15:20:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Borisov X-Patchwork-Id: 10849379 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 58C471669 for ; Tue, 12 Mar 2019 15:20:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 447FB297D7 for ; Tue, 12 Mar 2019 15:20:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 42300297C4; Tue, 12 Mar 2019 15:20:39 +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,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 C3792297D2 for ; Tue, 12 Mar 2019 15:20:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726671AbfCLPUh (ORCPT ); Tue, 12 Mar 2019 11:20:37 -0400 Received: from mx2.suse.de ([195.135.220.15]:41170 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726255AbfCLPUh (ORCPT ); Tue, 12 Mar 2019 11:20:37 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 112AFB69F for ; Tue, 12 Mar 2019 15:20:36 +0000 (UTC) From: Nikolay Borisov To: linux-btrfs@vger.kernel.org Cc: Nikolay Borisov Subject: [PATCH 3/7] btrfs: Remove fs_info from struct async_chunk Date: Tue, 12 Mar 2019 17:20:26 +0200 Message-Id: <20190312152030.31987-4-nborisov@suse.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190312152030.31987-1-nborisov@suse.com> References: <20190312152030.31987-1-nborisov@suse.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 The associated btrfs_work already contains a reference to the fs_info so use that instead of passing it via async_chunk. No functional changes. Signed-off-by: Nikolay Borisov Reviewed-by: Johannes Thumshirn --- fs/btrfs/inode.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index be3777d03c80..2a9d24bc8b53 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -368,7 +368,6 @@ struct async_extent { struct async_chunk { struct inode *inode; - struct btrfs_fs_info *fs_info; struct page *locked_page; u64 start; u64 end; @@ -1156,13 +1155,11 @@ static noinline void async_cow_start(struct btrfs_work *work) */ static noinline void async_cow_submit(struct btrfs_work *work) { - struct btrfs_fs_info *fs_info; - struct async_chunk *async_chunk; + struct async_chunk *async_chunk = container_of(work, struct async_chunk, + work); + struct btrfs_fs_info *fs_info = btrfs_work_owner(work); unsigned long nr_pages; - async_chunk = container_of(work, struct async_chunk, work); - - fs_info = async_chunk->fs_info; nr_pages = (async_chunk->end - async_chunk->start + PAGE_SIZE) >> PAGE_SHIFT; @@ -1252,7 +1249,6 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page, async_chunk[i].inode = inode; async_chunk[i].start = start; async_chunk[i].end = cur_end; - async_chunk[i].fs_info = fs_info; async_chunk[i].locked_page = locked_page; async_chunk[i].write_flags = write_flags; INIT_LIST_HEAD(&async_chunk[i].extents); From patchwork Tue Mar 12 15:20:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Borisov X-Patchwork-Id: 10849391 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 CDC7A1669 for ; Tue, 12 Mar 2019 15:20:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B73E3297CE for ; Tue, 12 Mar 2019 15:20:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B5522297C2; Tue, 12 Mar 2019 15:20:51 +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,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 51395297D5 for ; Tue, 12 Mar 2019 15:20:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726812AbfCLPUs (ORCPT ); Tue, 12 Mar 2019 11:20:48 -0400 Received: from mx2.suse.de ([195.135.220.15]:41176 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726564AbfCLPUh (ORCPT ); Tue, 12 Mar 2019 11:20:37 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 5DE4DB6A0 for ; Tue, 12 Mar 2019 15:20:36 +0000 (UTC) From: Nikolay Borisov To: linux-btrfs@vger.kernel.org Cc: Nikolay Borisov Subject: [PATCH 4/7] btrfs: Make compress_file_range take only struct async_chunk Date: Tue, 12 Mar 2019 17:20:27 +0200 Message-Id: <20190312152030.31987-5-nborisov@suse.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190312152030.31987-1-nborisov@suse.com> References: <20190312152030.31987-1-nborisov@suse.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 All context this function needs is held within struct async_chunk. Currently we not only pass the struct but also every individual member. This is redundant, simplify it by only passing struct async_chunk and leaving it to compress_file_range to extract the values it requires. No functional changes. Signed-off-by: Nikolay Borisov Reviewed-by: Johannes Thumshirn --- fs/btrfs/inode.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 2a9d24bc8b53..df008aa195b4 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -449,14 +449,14 @@ static inline void inode_should_defrag(struct btrfs_inode *inode, * are written in the same order that the flusher thread sent them * down. */ -static noinline void compress_file_range(struct inode *inode, - struct page *locked_page, - u64 start, u64 end, - struct async_chunk *async_chunk, - int *num_added) +static noinline void compress_file_range(struct async_chunk *async_chunk, + int *num_added) { + struct inode *inode = async_chunk->inode; struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); u64 blocksize = fs_info->sectorsize; + u64 start = async_chunk->start; + u64 end = async_chunk->end; u64 actual_end; int ret = 0; struct page **pages = NULL; @@ -675,9 +675,9 @@ static noinline void compress_file_range(struct inode *inode, * to our extent and set things up for the async work queue to run * cow_file_range to do the normal delalloc dance. */ - if (page_offset(locked_page) >= start && - page_offset(locked_page) <= end) - __set_page_dirty_nobuffers(locked_page); + if (page_offset(async_chunk->locked_page) >= start && + page_offset(async_chunk->locked_page) <= end) + __set_page_dirty_nobuffers(async_chunk->locked_page); /* unlocked later on in the async handlers */ if (redirty) @@ -1141,9 +1141,7 @@ static noinline void async_cow_start(struct btrfs_work *work) int num_added = 0; async_chunk = container_of(work, struct async_chunk, work); - compress_file_range(async_chunk->inode, async_chunk->locked_page, - async_chunk->start, async_chunk->end, async_chunk, - &num_added); + compress_file_range(async_chunk, &num_added); if (num_added == 0) { btrfs_add_delayed_iput(async_chunk->inode); async_chunk->inode = NULL; From patchwork Tue Mar 12 15:20:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Borisov X-Patchwork-Id: 10849387 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 9442F1669 for ; Tue, 12 Mar 2019 15:20:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 81EF129768 for ; Tue, 12 Mar 2019 15:20:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8066529762; Tue, 12 Mar 2019 15:20:49 +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,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 19F00297CE for ; Tue, 12 Mar 2019 15:20:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726798AbfCLPUr (ORCPT ); Tue, 12 Mar 2019 11:20:47 -0400 Received: from mx2.suse.de ([195.135.220.15]:41182 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726600AbfCLPUi (ORCPT ); Tue, 12 Mar 2019 11:20:38 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id B3EAFB69B for ; Tue, 12 Mar 2019 15:20:36 +0000 (UTC) From: Nikolay Borisov To: linux-btrfs@vger.kernel.org Cc: Nikolay Borisov Subject: [PATCH 5/7] btrfs: Replace clear_extent_bit with unlock_extent Date: Tue, 12 Mar 2019 17:20:28 +0200 Message-Id: <20190312152030.31987-6-nborisov@suse.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190312152030.31987-1-nborisov@suse.com> References: <20190312152030.31987-1-nborisov@suse.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 Signed-off-by: Nikolay Borisov Reviewed-by: Johannes Thumshirn --- fs/btrfs/inode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index df008aa195b4..0123f7067c8a 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -1204,8 +1204,7 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page, int i; bool should_compress; - clear_extent_bit(&BTRFS_I(inode)->io_tree, start, end, EXTENT_LOCKED, - 1, 0, NULL); + unlock_extent(&BTRFS_I(inode)->io_tree, start, end); if (BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS && !btrfs_test_opt(fs_info, FORCE_COMPRESS)) { From patchwork Tue Mar 12 15:20:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Borisov X-Patchwork-Id: 10849385 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 55BCE1669 for ; Tue, 12 Mar 2019 15:20:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3EDDF29229 for ; Tue, 12 Mar 2019 15:20:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3D1D12880C; Tue, 12 Mar 2019 15:20:42 +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,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 D681129796 for ; Tue, 12 Mar 2019 15:20:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726738AbfCLPUj (ORCPT ); Tue, 12 Mar 2019 11:20:39 -0400 Received: from mx2.suse.de ([195.135.220.15]:41188 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726684AbfCLPUi (ORCPT ); Tue, 12 Mar 2019 11:20:38 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 0CAE1B6A1 for ; Tue, 12 Mar 2019 15:20:37 +0000 (UTC) From: Nikolay Borisov To: linux-btrfs@vger.kernel.org Cc: Nikolay Borisov Subject: [PATCH 6/7] btrfs: Set iotree only once in submit_compressed_extents Date: Tue, 12 Mar 2019 17:20:29 +0200 Message-Id: <20190312152030.31987-7-nborisov@suse.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190312152030.31987-1-nborisov@suse.com> References: <20190312152030.31987-1-nborisov@suse.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 The inode never changes so it's sufficient to dereference it and get the iotree only once, before the execution of the main loop. No functional changes, only the size of the function is decreased: add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-44 (-44) Function old new delta submit_compressed_extents 1240 1196 -44 Total: Before=88476, After=88432, chg -0.05% Signed-off-by: Nikolay Borisov Reviewed-by: Johannes Thumshirn --- fs/btrfs/inode.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 0123f7067c8a..f5bd6fb840a5 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -727,7 +727,7 @@ static noinline void submit_compressed_extents(struct async_chunk *async_chunk) struct btrfs_key ins; struct extent_map *em; struct btrfs_root *root = BTRFS_I(inode)->root; - struct extent_io_tree *io_tree; + struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; int ret = 0; again: @@ -735,9 +735,6 @@ static noinline void submit_compressed_extents(struct async_chunk *async_chunk) async_extent = list_entry(async_chunk->extents.next, struct async_extent, list); list_del(&async_extent->list); - - io_tree = &BTRFS_I(inode)->io_tree; - retry: /* did the compression code fall back to uncompressed IO? */ if (!async_extent->pages) { From patchwork Tue Mar 12 15:20:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikolay Borisov X-Patchwork-Id: 10849383 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 544361575 for ; Tue, 12 Mar 2019 15:20:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 41D02297DE for ; Tue, 12 Mar 2019 15:20:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4066C297DF; Tue, 12 Mar 2019 15:20:41 +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,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 DF9E3297BD for ; Tue, 12 Mar 2019 15:20:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726711AbfCLPUk (ORCPT ); Tue, 12 Mar 2019 11:20:40 -0400 Received: from mx2.suse.de ([195.135.220.15]:41194 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726689AbfCLPUi (ORCPT ); Tue, 12 Mar 2019 11:20:38 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 57F4EB69F for ; Tue, 12 Mar 2019 15:20:37 +0000 (UTC) From: Nikolay Borisov To: linux-btrfs@vger.kernel.org Cc: Nikolay Borisov Subject: [PATCH 7/7] btrfs: Factor out common extent locking code in submit_compressed_extents Date: Tue, 12 Mar 2019 17:20:30 +0200 Message-Id: <20190312152030.31987-8-nborisov@suse.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190312152030.31987-1-nborisov@suse.com> References: <20190312152030.31987-1-nborisov@suse.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 Irrespective of whether the compress code fell back to uncompressed or a compressed extent has to be submitted, the extent range is always locked. So factor out the common lock_extent call at the beginning of the loop. No functional changes just removes one duplicate lock_extent call. Signed-off-by: Nikolay Borisov Reviewed-by: Johannes Thumshirn --- fs/btrfs/inode.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index f5bd6fb840a5..9fd7cd453a54 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -736,15 +736,14 @@ static noinline void submit_compressed_extents(struct async_chunk *async_chunk) struct async_extent, list); list_del(&async_extent->list); retry: + + lock_extent(io_tree, async_extent->start, + async_extent->start + async_extent->ram_size - 1); /* did the compression code fall back to uncompressed IO? */ if (!async_extent->pages) { int page_started = 0; unsigned long nr_written = 0; - lock_extent(io_tree, async_extent->start, - async_extent->start + - async_extent->ram_size - 1); - /* allocate blocks */ ret = cow_file_range(inode, async_chunk->locked_page, async_extent->start, @@ -776,9 +775,6 @@ static noinline void submit_compressed_extents(struct async_chunk *async_chunk) continue; } - lock_extent(io_tree, async_extent->start, - async_extent->start + async_extent->ram_size - 1); - ret = btrfs_reserve_extent(root, async_extent->ram_size, async_extent->compressed_size, async_extent->compressed_size,