From patchwork Tue Nov 15 18:00:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13044042 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AFAB2C433FE for ; Tue, 15 Nov 2022 18:01:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238244AbiKOSBl (ORCPT ); Tue, 15 Nov 2022 13:01:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50394 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238029AbiKOSBH (ORCPT ); Tue, 15 Nov 2022 13:01:07 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B076B11C2A for ; Tue, 15 Nov 2022 10:00:41 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 350ED1F8E0; Tue, 15 Nov 2022 18:00:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1668535240; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=K/+4uL317yjTCA01hYB5sabZtn+knk1BAX2rFaUsm0I=; b=sVZCLc+LHog25/d78xJy9SCKBiUu48dO4MGrFTrwn3/od+8guLdNK0n3bt9k6bbUJbW8RE 24MiBHeZn8w1NaOOG2Nzs4gAmGMIdJVPYtYMBQIK2mGANBfcEK4F0c9Q7c+0wTOFKHLu/s E/g3cVDFh8DiJESCuED30cq01RV9GEc= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1668535240; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=K/+4uL317yjTCA01hYB5sabZtn+knk1BAX2rFaUsm0I=; b=tkJNCkjAwnpteAoEtBo06+RZU0nRPWT0k+IaL8F6US4ZTwMqlavkKJD/qV/90mFn7mQP5r S4c66PZS0Ch3dsAA== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id E1D1413A91; Tue, 15 Nov 2022 18:00:39 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id xosSL8fTc2OEZAAAMHmgww (envelope-from ); Tue, 15 Nov 2022 18:00:39 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Goldwyn Rodrigues Subject: [PATCH 01/16] btrfs: check for range correctness while locking or setting extent bits Date: Tue, 15 Nov 2022 12:00:19 -0600 Message-Id: <07534e31d822b5c08609c72e5a2e8054604765d9.1668530684.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Since we will be working at the mercy of userspace, check if the range is valid and proceed to lock or set bits only if start < end. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/extent-io-tree.c | 6 ++++++ fs/btrfs/ordered-data.c | 3 +++ 2 files changed, 9 insertions(+) diff --git a/fs/btrfs/extent-io-tree.c b/fs/btrfs/extent-io-tree.c index 21fa15123af8..80657c820df4 100644 --- a/fs/btrfs/extent-io-tree.c +++ b/fs/btrfs/extent-io-tree.c @@ -557,6 +557,9 @@ int __clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, int wake; int delete = (bits & EXTENT_CLEAR_ALL_BITS); + if (unlikely(start > end)) + return 0; + btrfs_debug_check_extent_io_range(tree, start, end); trace_btrfs_clear_extent_bit(tree, start, end - start + 1, bits); @@ -979,6 +982,9 @@ static int __set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, u64 last_end; u32 exclusive_bits = (bits & EXTENT_LOCKED); + if (unlikely(start > end)) + return 0; + btrfs_debug_check_extent_io_range(tree, start, end); trace_btrfs_set_extent_bit(tree, start, end - start + 1, bits); diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 4bed0839b640..0a5512ed9a21 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -1043,6 +1043,9 @@ void btrfs_lock_and_flush_ordered_range(struct btrfs_inode *inode, u64 start, struct extent_state *cache = NULL; struct extent_state **cachedp = &cache; + if (unlikely(start > end)) + return; + if (cached_state) cachedp = cached_state; From patchwork Tue Nov 15 18:00:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13044043 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CD532C43219 for ; Tue, 15 Nov 2022 18:01:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238263AbiKOSBn (ORCPT ); Tue, 15 Nov 2022 13:01:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50794 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237952AbiKOSBI (ORCPT ); Tue, 15 Nov 2022 13:01:08 -0500 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AC46D2F005 for ; Tue, 15 Nov 2022 10:00:43 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 6690433688; Tue, 15 Nov 2022 18:00:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1668535242; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Iy5bXyflPNjSnEIykYuf/uYXJoIj0vxQu+TYe+3yv2w=; b=r5uP+VGJEb010SJ8/Y8TzwbfLRSuAak7qADiRPKGEafZM5U9Co128zLHHvV52XBYBAl35x h/A+x7GniEQkSCL8OhhtljOEg6xlRM8zE8qlAOPXTTt7NmgVXbm3pV1jXOjKTAPn1jqmM0 KSfHrMpz+onyyLtstEhNnF3TfC8wZOQ= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1668535242; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Iy5bXyflPNjSnEIykYuf/uYXJoIj0vxQu+TYe+3yv2w=; b=tUX6LHEXhLrE+sUWlNwamGKRQqzTBUWsC//ziCPCw1bHaudW/fOM1xYIEMxCU4FlkH7lFz XBpAitStElKuTwCA== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 1A16613A91; Tue, 15 Nov 2022 18:00:41 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id ZOsQOsnTc2OKZAAAMHmgww (envelope-from ); Tue, 15 Nov 2022 18:00:41 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Goldwyn Rodrigues Subject: [PATCH 02/16] btrfs: qgroup flush responsibility of the caller Date: Tue, 15 Nov 2022 12:00:20 -0600 Message-Id: X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Qgroup reservation will be performed under extent locks. If qgroup runs low, btrfs starts a flush to squeeze out the last available space from over-reserved uncommitted extents. Move the flush outside of the reserve function so it can be called by the callee of the reserving function. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/block-group.c | 2 +- fs/btrfs/delalloc-space.c | 17 +++++++---------- fs/btrfs/delalloc-space.h | 5 ++--- fs/btrfs/file.c | 19 ++++++++++++++++--- fs/btrfs/inode.c | 23 +++++++++++++---------- fs/btrfs/qgroup.c | 27 +-------------------------- fs/btrfs/qgroup.h | 16 ++++++---------- fs/btrfs/relocation.c | 3 +-- fs/btrfs/root-tree.c | 3 +-- 9 files changed, 48 insertions(+), 67 deletions(-) diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c index 708d843daa72..578c6cbdef3b 100644 --- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -2945,7 +2945,7 @@ static int cache_save_setup(struct btrfs_block_group *block_group, cache_size *= fs_info->sectorsize; ret = btrfs_check_data_free_space(BTRFS_I(inode), &data_reserved, 0, - cache_size, false); + cache_size); if (ret) goto out_put; diff --git a/fs/btrfs/delalloc-space.c b/fs/btrfs/delalloc-space.c index 7ddb1d104e8e..b46614bec817 100644 --- a/fs/btrfs/delalloc-space.c +++ b/fs/btrfs/delalloc-space.c @@ -130,7 +130,7 @@ int btrfs_alloc_data_chunk_ondemand(struct btrfs_inode *inode, u64 bytes) int btrfs_check_data_free_space(struct btrfs_inode *inode, struct extent_changeset **reserved, u64 start, - u64 len, bool noflush) + u64 len) { struct btrfs_fs_info *fs_info = inode->root->fs_info; enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_FLUSH_DATA; @@ -141,9 +141,7 @@ int btrfs_check_data_free_space(struct btrfs_inode *inode, round_down(start, fs_info->sectorsize); start = round_down(start, fs_info->sectorsize); - if (noflush) - flush = BTRFS_RESERVE_NO_FLUSH; - else if (btrfs_is_free_space_inode(inode)) + if (btrfs_is_free_space_inode(inode)) flush = BTRFS_RESERVE_FLUSH_FREE_SPACE_INODE; ret = btrfs_reserve_data_bytes(fs_info, len, flush); @@ -298,7 +296,7 @@ static void calc_inode_reservations(struct btrfs_fs_info *fs_info, } int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes, - u64 disk_num_bytes, bool noflush) + u64 disk_num_bytes) { struct btrfs_root *root = inode->root; struct btrfs_fs_info *fs_info = root->fs_info; @@ -317,7 +315,7 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes, * If we have a transaction open (can happen if we call truncate_block * from truncate), then we need FLUSH_LIMIT so we don't deadlock. */ - if (noflush || btrfs_is_free_space_inode(inode)) { + if (btrfs_is_free_space_inode(inode)) { flush = BTRFS_RESERVE_NO_FLUSH; } else { if (current->journal_info) @@ -342,8 +340,7 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes, */ calc_inode_reservations(fs_info, num_bytes, disk_num_bytes, &meta_reserve, &qgroup_reserve); - ret = btrfs_qgroup_reserve_meta_prealloc(root, qgroup_reserve, true, - noflush); + ret = btrfs_qgroup_reserve_meta_prealloc(root, qgroup_reserve, true); if (ret) return ret; ret = btrfs_reserve_metadata_bytes(fs_info, block_rsv, meta_reserve, flush); @@ -464,10 +461,10 @@ int btrfs_delalloc_reserve_space(struct btrfs_inode *inode, { int ret; - ret = btrfs_check_data_free_space(inode, reserved, start, len, false); + ret = btrfs_check_data_free_space(inode, reserved, start, len); if (ret < 0) return ret; - ret = btrfs_delalloc_reserve_metadata(inode, len, len, false); + ret = btrfs_delalloc_reserve_metadata(inode, len, len); if (ret < 0) { btrfs_free_reserved_data_space(inode, *reserved, start, len); extent_changeset_free(*reserved); diff --git a/fs/btrfs/delalloc-space.h b/fs/btrfs/delalloc-space.h index c5d573f2366e..b91fcde5da80 100644 --- a/fs/btrfs/delalloc-space.h +++ b/fs/btrfs/delalloc-space.h @@ -7,8 +7,7 @@ struct extent_changeset; int btrfs_alloc_data_chunk_ondemand(struct btrfs_inode *inode, u64 bytes); int btrfs_check_data_free_space(struct btrfs_inode *inode, - struct extent_changeset **reserved, u64 start, u64 len, - bool noflush); + struct extent_changeset **reserved, u64 start, u64 len); void btrfs_free_reserved_data_space(struct btrfs_inode *inode, struct extent_changeset *reserved, u64 start, u64 len); void btrfs_delalloc_release_space(struct btrfs_inode *inode, @@ -21,7 +20,7 @@ void btrfs_delalloc_release_metadata(struct btrfs_inode *inode, u64 num_bytes, int btrfs_delalloc_reserve_space(struct btrfs_inode *inode, struct extent_changeset **reserved, u64 start, u64 len); int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes, - u64 disk_num_bytes, bool noflush); + u64 disk_num_bytes); void btrfs_delalloc_release_extents(struct btrfs_inode *inode, u64 num_bytes); #endif /* BTRFS_DELALLOC_SPACE_H */ diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 448b143a5cb2..940f10f42790 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1189,6 +1189,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb, unsigned int ilock_flags = 0; const bool nowait = (iocb->ki_flags & IOCB_NOWAIT); unsigned int bdp_flags = (nowait ? BDP_ASYNC : 0); + bool flushed = false; if (nowait) ilock_flags |= BTRFS_ILOCK_TRY; @@ -1242,11 +1243,11 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb, only_release_metadata = false; sector_offset = pos & (fs_info->sectorsize - 1); - +reserve: extent_changeset_release(data_reserved); ret = btrfs_check_data_free_space(BTRFS_I(inode), &data_reserved, pos, - write_bytes, nowait); + write_bytes); if (ret < 0) { int can_nocow; @@ -1255,6 +1256,12 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb, break; } + if (!nowait && !flushed && ret == -EDQUOT) { + flushed = true; + btrfs_qgroup_flush(BTRFS_I(inode)->root); + goto reserve; + } + /* * If we don't have to COW at the offset, reserve * metadata only. write_bytes may get smaller than @@ -1278,7 +1285,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb, WARN_ON(reserve_bytes == 0); ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), reserve_bytes, - reserve_bytes, nowait); + reserve_bytes); if (ret) { if (!only_release_metadata) btrfs_free_reserved_data_space(BTRFS_I(inode), @@ -1289,6 +1296,12 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb, if (nowait && ret == -ENOSPC) ret = -EAGAIN; + + if (!nowait && !flushed && ret == -EDQUOT) { + flushed = true; + btrfs_qgroup_flush(BTRFS_I(inode)->root); + goto reserve; + } break; } diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 4248e6cabbdc..29c1748adacf 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4936,7 +4936,7 @@ int btrfs_truncate_block(struct btrfs_inode *inode, loff_t from, loff_t len, block_end = block_start + blocksize - 1; ret = btrfs_check_data_free_space(inode, &data_reserved, block_start, - blocksize, false); + blocksize); if (ret < 0) { if (btrfs_check_nocow_lock(inode, block_start, &write_bytes, false) > 0) { /* For nocow case, no need to reserve data space */ @@ -4945,7 +4945,7 @@ int btrfs_truncate_block(struct btrfs_inode *inode, loff_t from, loff_t len, goto out; } } - ret = btrfs_delalloc_reserve_metadata(inode, blocksize, blocksize, false); + ret = btrfs_delalloc_reserve_metadata(inode, blocksize, blocksize); if (ret < 0) { if (!only_release_metadata) btrfs_free_reserved_data_space(inode, data_reserved, @@ -7484,6 +7484,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map, bool space_reserved = false; u64 prev_len; int ret = 0; + bool flushed = false; /* * We don't allocate a new extent in the following cases @@ -7515,10 +7516,14 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map, prev_len = len; if (can_nocow) { struct extent_map *em2; - +again: /* We can NOCOW, so only need to reserve metadata space. */ - ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), len, len, - nowait); + ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), len, len); + if (!nowait && !flushed && ret == -EDQUOT) { + btrfs_qgroup_flush(BTRFS_I(inode)->root); + flushed = true; + goto again; + } if (ret < 0) { /* Our caller expects us to free the input extent map. */ free_extent_map(em); @@ -7566,8 +7571,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map, * We have to COW and we have already reserved data space before, * so now we reserve only metadata. */ - ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), len, len, - false); + ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), len, len); if (ret < 0) goto out; space_reserved = true; @@ -7690,7 +7694,7 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start, if (write && !(flags & IOMAP_NOWAIT)) { ret = btrfs_check_data_free_space(BTRFS_I(inode), &dio_data->data_reserved, - start, data_alloc_len, false); + start, data_alloc_len); if (!ret) dio_data->data_space_reserved = true; else if (ret && !(BTRFS_I(inode)->flags & @@ -10801,8 +10805,7 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from, ret = btrfs_qgroup_reserve_data(inode, &data_reserved, start, num_bytes); if (ret) goto out_free_data_space; - ret = btrfs_delalloc_reserve_metadata(inode, num_bytes, disk_num_bytes, - false); + ret = btrfs_delalloc_reserve_metadata(inode, num_bytes, disk_num_bytes); if (ret) goto out_qgroup_free_data; diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 05e79f7b4433..db55f3a7949d 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -3695,7 +3695,7 @@ static int qgroup_unreserve_range(struct btrfs_inode *inode, * In theory this shouldn't provide much space, but any more qgroup space * is needed. */ -static int try_flush_qgroup(struct btrfs_root *root) +int btrfs_qgroup_flush(struct btrfs_root *root) { struct btrfs_trans_handle *trans; int ret; @@ -3801,15 +3801,6 @@ int btrfs_qgroup_reserve_data(struct btrfs_inode *inode, struct extent_changeset **reserved_ret, u64 start, u64 len) { - int ret; - - ret = qgroup_reserve_data(inode, reserved_ret, start, len); - if (ret <= 0 && ret != -EDQUOT) - return ret; - - ret = try_flush_qgroup(inode->root); - if (ret < 0) - return ret; return qgroup_reserve_data(inode, reserved_ret, start, len); } @@ -4008,22 +3999,6 @@ int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, return ret; } -int __btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, - enum btrfs_qgroup_rsv_type type, bool enforce, - bool noflush) -{ - int ret; - - ret = btrfs_qgroup_reserve_meta(root, num_bytes, type, enforce); - if ((ret <= 0 && ret != -EDQUOT) || noflush) - return ret; - - ret = try_flush_qgroup(root); - if (ret < 0) - return ret; - return btrfs_qgroup_reserve_meta(root, num_bytes, type, enforce); -} - void btrfs_qgroup_free_meta_all_pertrans(struct btrfs_root *root) { struct btrfs_fs_info *fs_info = root->fs_info; diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h index 7bffa10589d6..6dbcdab56d0c 100644 --- a/fs/btrfs/qgroup.h +++ b/fs/btrfs/qgroup.h @@ -369,24 +369,20 @@ int btrfs_qgroup_free_data(struct btrfs_inode *inode, u64 len); int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, enum btrfs_qgroup_rsv_type type, bool enforce); -int __btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, - enum btrfs_qgroup_rsv_type type, bool enforce, - bool noflush); /* Reserve metadata space for pertrans and prealloc type */ static inline int btrfs_qgroup_reserve_meta_pertrans(struct btrfs_root *root, int num_bytes, bool enforce) { - return __btrfs_qgroup_reserve_meta(root, num_bytes, + return btrfs_qgroup_reserve_meta(root, num_bytes, BTRFS_QGROUP_RSV_META_PERTRANS, - enforce, false); + enforce); } static inline int btrfs_qgroup_reserve_meta_prealloc(struct btrfs_root *root, - int num_bytes, bool enforce, - bool noflush) + int num_bytes, bool enforce) { - return __btrfs_qgroup_reserve_meta(root, num_bytes, + return btrfs_qgroup_reserve_meta(root, num_bytes, BTRFS_QGROUP_RSV_META_PREALLOC, - enforce, noflush); + enforce); } void __btrfs_qgroup_free_meta(struct btrfs_root *root, int num_bytes, @@ -439,5 +435,5 @@ int btrfs_qgroup_trace_subtree_after_cow(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *eb); void btrfs_qgroup_destroy_extent_records(struct btrfs_transaction *trans); bool btrfs_check_quota_leak(struct btrfs_fs_info *fs_info); - +int btrfs_qgroup_flush(struct btrfs_root *root); #endif diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index aa80e51bc8ca..e8c45192b72a 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -3013,8 +3013,7 @@ static int relocate_one_page(struct inode *inode, struct file_ra_state *ra, /* Reserve metadata for this range */ ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), - clamped_len, clamped_len, - false); + clamped_len, clamped_len); if (ret) goto release_page; diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index 859874579456..1c92a2c915d3 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c @@ -512,8 +512,7 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root, /* One for parent inode, two for dir entries */ qgroup_num_bytes = 3 * fs_info->nodesize; ret = btrfs_qgroup_reserve_meta_prealloc(root, - qgroup_num_bytes, true, - false); + qgroup_num_bytes, true); if (ret) return ret; } From patchwork Tue Nov 15 18:00:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13044044 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F0B2BC433FE for ; Tue, 15 Nov 2022 18:01:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237952AbiKOSBo (ORCPT ); Tue, 15 Nov 2022 13:01:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50782 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238090AbiKOSBI (ORCPT ); Tue, 15 Nov 2022 13:01:08 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B6FC7108 for ; Tue, 15 Nov 2022 10:00:45 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 6E6451F8E9; Tue, 15 Nov 2022 18:00:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1668535244; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ufWE0JtJ3U7iLRpbLE7tVDsUSR8tOxLV0WNy8paVL0M=; b=Ysf4bqA9BK6H8V0RNSPfaJhwiadx9G1yKV2v3o+YD9Nxs8j2nx2+jKuz+6ev1z363PWvdI MBy6dFMcjQdWBTonqZvi0wd7MqOGdEsWRvGwMEOJ2q7e+CZEDw9S9R8n4ODw9AOEMIFJk3 Es5CBAGf28ttUoJiL5q5J5rfLG3VKhc= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1668535244; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ufWE0JtJ3U7iLRpbLE7tVDsUSR8tOxLV0WNy8paVL0M=; b=SGtjC50FiRkgjGa0d/iw1nWnVngN43eZ5TenG6bH0lHj85tplTAYsPdA+wWxsUyMLdJz+5 d1f9mtUHPGgrjFCw== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 2281F13A91; Tue, 15 Nov 2022 18:00:44 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 5wNgAMzTc2OSZAAAMHmgww (envelope-from ); Tue, 15 Nov 2022 18:00:44 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Goldwyn Rodrigues Subject: [PATCH 03/16] btrfs: wait ordered range before locking during truncate Date: Tue, 15 Nov 2022 12:00:21 -0600 Message-Id: <07644d32ba3e517e26199b4b78f81636655a7702.1668530684.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Check if truncate needs to wait for ordered range before calling btrfs_truncate(). Instead of performing it in btrfs_truncate(), perform the wait before the call. Remove the no longer needed variable to perform writeback in btrfs_truncate(). Signed-off-by: Goldwyn Rodrigues Reviewed-by: Johannes Thumshirn Reviewed-by: Josef Bacik --- fs/btrfs/inode.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 29c1748adacf..1044a34a20e6 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -124,7 +124,7 @@ static const struct file_operations btrfs_dir_file_operations; static struct kmem_cache *btrfs_inode_cachep; static int btrfs_setsize(struct inode *inode, struct iattr *attr); -static int btrfs_truncate(struct btrfs_inode *inode, bool skip_writeback); +static int btrfs_truncate(struct btrfs_inode *inode); static noinline int cow_file_range(struct btrfs_inode *inode, struct page *locked_page, u64 start, u64 end, int *page_started, @@ -5240,7 +5240,7 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) } else { struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); - if (btrfs_is_zoned(fs_info)) { + if (btrfs_is_zoned(fs_info) || (newsize < oldsize)) { ret = btrfs_wait_ordered_range(inode, ALIGN(newsize, fs_info->sectorsize), (u64)-1); @@ -5261,7 +5261,8 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) inode_dio_wait(inode); - ret = btrfs_truncate(BTRFS_I(inode), newsize == oldsize); + ret = btrfs_truncate(BTRFS_I(inode)); + if (ret && inode->i_nlink) { int err; @@ -8627,7 +8628,7 @@ vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf) return ret; } -static int btrfs_truncate(struct btrfs_inode *inode, bool skip_writeback) +static int btrfs_truncate(struct btrfs_inode *inode) { struct btrfs_truncate_control control = { .inode = inode, @@ -8640,17 +8641,8 @@ static int btrfs_truncate(struct btrfs_inode *inode, bool skip_writeback) struct btrfs_block_rsv *rsv; int ret; struct btrfs_trans_handle *trans; - u64 mask = fs_info->sectorsize - 1; u64 min_size = btrfs_calc_metadata_size(fs_info, 1); - if (!skip_writeback) { - ret = btrfs_wait_ordered_range(&inode->vfs_inode, - inode->vfs_inode.i_size & (~mask), - (u64)-1); - if (ret) - return ret; - } - /* * Yes ladies and gentlemen, this is indeed ugly. We have a couple of * things going on here: From patchwork Tue Nov 15 18:00:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13044045 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 38473C4332F for ; Tue, 15 Nov 2022 18:01:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238368AbiKOSBq (ORCPT ); Tue, 15 Nov 2022 13:01:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50796 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238251AbiKOSBJ (ORCPT ); Tue, 15 Nov 2022 13:01:09 -0500 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CDD14C10 for ; Tue, 15 Nov 2022 10:00:47 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 8884E336CD; Tue, 15 Nov 2022 18:00:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1668535246; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uc3zwMPWJa+3nz3UEityHBUfqKfc6GUABZOxcrB+Elc=; b=kudD8IZSa1Noc3+QADxiAYbCY5XS3loMZhk0PylhmwXXYob7Q1N/a7vToGDfvydc69xNEV qkbiAa8lo0gHMzG5YzxHL0sTdoO6UEuZcYBzzO/as6KK2tlC+HjoXEw1CNmgZuxyAmmyyP /lPPArIMj7ThBkvtqcVGJPQt1M7YonE= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1668535246; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uc3zwMPWJa+3nz3UEityHBUfqKfc6GUABZOxcrB+Elc=; b=nY1eGHuuICdG7wasAdcFkIUK+y1LUOGweAZeDaqxBYhFBlVaEdHy9exsmrBoK/YaQhcyuY A6IwlyxgzHK2AtDA== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 3259213A91; Tue, 15 Nov 2022 18:00:46 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id xdZBBM7Tc2OaZAAAMHmgww (envelope-from ); Tue, 15 Nov 2022 18:00:46 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Goldwyn Rodrigues Subject: [PATCH 04/16] btrfs: lock extents while truncating Date: Tue, 15 Nov 2022 12:00:22 -0600 Message-Id: <7ffb8c402e6b8cd3679d5b9a97dc0b43e75079d5.1668530684.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Extent locking before pages. Lock extents while performing truncate_setsize(). This calls btrfs_invalidatepage(), so remove all locking during invalidatepage(). Note, extent locks are not required during inode eviction, which calls invalidatepage as well. Signed-off-by: Goldwyn Rodrigues Reviewed-by: Josef Bacik --- fs/btrfs/file.c | 4 ++-- fs/btrfs/inode.c | 42 ++++++++++++++++++++---------------------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 940f10f42790..473a0743270b 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -2212,10 +2212,10 @@ static void btrfs_punch_hole_lock_range(struct inode *inode, const u64 page_lockend = round_down(lockend + 1, PAGE_SIZE) - 1; while (1) { - truncate_pagecache_range(inode, lockstart, lockend); - lock_extent(&BTRFS_I(inode)->io_tree, lockstart, lockend, cached_state); + + truncate_pagecache_range(inode, lockstart, lockend); /* * We can't have ordered extents in the range, nor dirty/writeback * pages, because we have locked the inode's VFS lock in exclusive diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 1044a34a20e6..4bfa51871ddc 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4913,7 +4913,6 @@ int btrfs_truncate_block(struct btrfs_inode *inode, loff_t from, loff_t len, { struct btrfs_fs_info *fs_info = inode->root->fs_info; struct address_space *mapping = inode->vfs_inode.i_mapping; - struct extent_io_tree *io_tree = &inode->io_tree; struct btrfs_ordered_extent *ordered; struct extent_state *cached_state = NULL; struct extent_changeset *data_reserved = NULL; @@ -4980,11 +4979,8 @@ int btrfs_truncate_block(struct btrfs_inode *inode, loff_t from, loff_t len, } wait_on_page_writeback(page); - lock_extent(io_tree, block_start, block_end, &cached_state); - ordered = btrfs_lookup_ordered_extent(inode, block_start); if (ordered) { - unlock_extent(io_tree, block_start, block_end, &cached_state); unlock_page(page); put_page(page); btrfs_start_ordered_extent(ordered, 1); @@ -4998,10 +4994,8 @@ int btrfs_truncate_block(struct btrfs_inode *inode, loff_t from, loff_t len, ret = btrfs_set_extent_delalloc(inode, block_start, block_end, 0, &cached_state); - if (ret) { - unlock_extent(io_tree, block_start, block_end, &cached_state); + if (ret) goto out_unlock; - } if (offset != blocksize) { if (!len) @@ -5016,7 +5010,6 @@ int btrfs_truncate_block(struct btrfs_inode *inode, loff_t from, loff_t len, btrfs_page_clear_checked(fs_info, page, block_start, block_end + 1 - block_start); btrfs_page_set_dirty(fs_info, page, block_start, block_end + 1 - block_start); - unlock_extent(io_tree, block_start, block_end, &cached_state); if (only_release_metadata) set_extent_bit(&inode->io_tree, block_start, block_end, @@ -5108,6 +5101,8 @@ int btrfs_cont_expand(struct btrfs_inode *inode, loff_t oldsize, loff_t size) u64 hole_size; int err = 0; + btrfs_lock_and_flush_ordered_range(inode, hole_start, block_end - 1, + &cached_state); /* * If our size started in the middle of a block we need to zero out the * rest of the block before we expand the i_size, otherwise we could @@ -5115,13 +5110,11 @@ int btrfs_cont_expand(struct btrfs_inode *inode, loff_t oldsize, loff_t size) */ err = btrfs_truncate_block(inode, oldsize, 0, 0); if (err) - return err; + goto out; if (size <= hole_start) - return 0; + goto out; - btrfs_lock_and_flush_ordered_range(inode, hole_start, block_end - 1, - &cached_state); cur_offset = hole_start; while (1) { em = btrfs_get_extent(inode, NULL, 0, cur_offset, @@ -5183,6 +5176,7 @@ int btrfs_cont_expand(struct btrfs_inode *inode, loff_t oldsize, loff_t size) break; } free_extent_map(em); +out: unlock_extent(io_tree, hole_start, block_end - 1, &cached_state); return err; } @@ -5195,6 +5189,7 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) loff_t newsize = attr->ia_size; int mask = attr->ia_valid; int ret; + bool flushed = false; /* * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a @@ -5239,6 +5234,9 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) btrfs_end_transaction(trans); } else { struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + u64 start = round_down(newsize, fs_info->sectorsize); + u64 end = round_up(oldsize, fs_info->sectorsize) - 1; + struct extent_state **cached = NULL; if (btrfs_is_zoned(fs_info) || (newsize < oldsize)) { ret = btrfs_wait_ordered_range(inode, @@ -5256,12 +5254,20 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) if (newsize == 0) set_bit(BTRFS_INODE_FLUSH_ON_CLOSE, &BTRFS_I(inode)->runtime_flags); - +again: + lock_extent(&BTRFS_I(inode)->io_tree, start, end, cached); truncate_setsize(inode, newsize); inode_dio_wait(inode); ret = btrfs_truncate(BTRFS_I(inode)); + unlock_extent(&BTRFS_I(inode)->io_tree, start, end, cached); + + if (ret == -EDQUOT && !flushed) { + flushed = true; + btrfs_qgroup_flush(BTRFS_I(inode)->root); + goto again; + } if (ret && inode->i_nlink) { int err; @@ -8342,9 +8348,6 @@ static void btrfs_invalidate_folio(struct folio *folio, size_t offset, return; } - if (!inode_evicting) - lock_extent(tree, page_start, page_end, &cached_state); - cur = page_start; while (cur < page_end) { struct btrfs_ordered_extent *ordered; @@ -8445,7 +8448,7 @@ static void btrfs_invalidate_folio(struct folio *folio, size_t offset, */ btrfs_qgroup_free_data(inode, NULL, cur, range_end + 1 - cur); if (!inode_evicting) { - clear_extent_bit(tree, cur, range_end, EXTENT_LOCKED | + clear_extent_bit(tree, cur, range_end, EXTENT_DELALLOC | EXTENT_UPTODATE | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG | extra_flags, &cached_state); @@ -8695,12 +8698,9 @@ static int btrfs_truncate(struct btrfs_inode *inode) trans->block_rsv = rsv; while (1) { - struct extent_state *cached_state = NULL; const u64 new_size = inode->vfs_inode.i_size; - const u64 lock_start = ALIGN_DOWN(new_size, fs_info->sectorsize); control.new_size = new_size; - lock_extent(&inode->io_tree, lock_start, (u64)-1, &cached_state); /* * We want to drop from the next block forward in case this new * size is not block aligned since we will be keeping the last @@ -8715,8 +8715,6 @@ static int btrfs_truncate(struct btrfs_inode *inode) inode_sub_bytes(&inode->vfs_inode, control.sub_bytes); btrfs_inode_safe_disk_i_size_write(inode, control.last_size); - unlock_extent(&inode->io_tree, lock_start, (u64)-1, &cached_state); - trans->block_rsv = &fs_info->trans_block_rsv; if (ret != -ENOSPC && ret != -EAGAIN) break; From patchwork Tue Nov 15 18:00:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13044046 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C46FEC43217 for ; Tue, 15 Nov 2022 18:01:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238374AbiKOSBr (ORCPT ); Tue, 15 Nov 2022 13:01:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50788 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238255AbiKOSBJ (ORCPT ); Tue, 15 Nov 2022 13:01:09 -0500 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F08E22AD for ; Tue, 15 Nov 2022 10:00:49 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id AB58D336D2; Tue, 15 Nov 2022 18:00:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1668535248; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=mkPDwZwoqHgEKeNvYJ9df9I0XhzJmdZcYflX9P2sc+I=; b=qYNvLFYV2q4Nx6cT2l/oaEE+3Tty/sMli9A+QBQAmny0hviB8uleTEjZC1wXPBMG2YL/+G djqk0P/SIo6jJt9mgwKPcU1xoRYUPsKZbuviPi4OCihH7LWIMr351O8Enm0BuBoAFfKfa+ mMmfxOjkjMK1YrcjtSmTJixM9LA/9Eo= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1668535248; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=mkPDwZwoqHgEKeNvYJ9df9I0XhzJmdZcYflX9P2sc+I=; b=ngebfW6h8EQSkFWsurCYihRD8Ir4XUeIZjN5+XCdgGlFzeh4e2578kApQf2DaloJIhFsjM sLLEHqRvMlfPx4Cg== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 5B34013A91; Tue, 15 Nov 2022 18:00:48 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id JMtSDtDTc2OcZAAAMHmgww (envelope-from ); Tue, 15 Nov 2022 18:00:48 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Goldwyn Rodrigues Subject: [PATCH 05/16] btrfs: No need to lock extent while performing invalidate_folio() Date: Tue, 15 Nov 2022 12:00:23 -0600 Message-Id: <259239dfcb4ab26250036c6429c47ff6214ac8ef.1668530684.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Don't lock extents while performing invalidate_folio because this is performed by the calling function higher up the call chain. With this change, extent_invalidate_folio() calls only folio_wait_writeback(). Remove and cleanup this function. Signed-off-by: Goldwyn Rodrigues Reviewed-by: Josef Bacik --- fs/btrfs/disk-io.c | 4 +--- fs/btrfs/extent_io.c | 32 -------------------------------- fs/btrfs/extent_io.h | 2 -- 3 files changed, 1 insertion(+), 37 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 91a088210e5a..8ac9612f8f27 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -888,9 +888,7 @@ static bool btree_release_folio(struct folio *folio, gfp_t gfp_flags) static void btree_invalidate_folio(struct folio *folio, size_t offset, size_t length) { - struct extent_io_tree *tree; - tree = &BTRFS_I(folio->mapping->host)->io_tree; - extent_invalidate_folio(tree, folio, offset); + folio_wait_writeback(folio); btree_release_folio(folio, GFP_NOFS); if (folio_get_private(folio)) { btrfs_warn(BTRFS_I(folio->mapping->host)->root->fs_info, diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 65ba5c3658cf..92068e4ff9c3 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -3324,38 +3324,6 @@ void extent_readahead(struct readahead_control *rac) submit_one_bio(&bio_ctrl); } -/* - * basic invalidate_folio code, this waits on any locked or writeback - * ranges corresponding to the folio, and then deletes any extent state - * records from the tree - */ -int extent_invalidate_folio(struct extent_io_tree *tree, - struct folio *folio, size_t offset) -{ - struct extent_state *cached_state = NULL; - u64 start = folio_pos(folio); - u64 end = start + folio_size(folio) - 1; - size_t blocksize = folio->mapping->host->i_sb->s_blocksize; - - /* This function is only called for the btree inode */ - ASSERT(tree->owner == IO_TREE_BTREE_INODE_IO); - - start += ALIGN(offset, blocksize); - if (start > end) - return 0; - - lock_extent(tree, start, end, &cached_state); - folio_wait_writeback(folio); - - /* - * Currently for btree io tree, only EXTENT_LOCKED is utilized, - * so here we only need to unlock the extent range to free any - * existing extent state. - */ - unlock_extent(tree, start, end, &cached_state); - return 0; -} - /* * a helper for release_folio, this tests for areas of the page that * are locked or under IO and drops the related state bits if it is safe diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index a0bafc7f6c07..3adb22a034a0 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -239,8 +239,6 @@ void extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end); void extent_clear_unlock_delalloc(struct btrfs_inode *inode, u64 start, u64 end, struct page *locked_page, u32 bits_to_clear, unsigned long page_ops); -int extent_invalidate_folio(struct extent_io_tree *tree, - struct folio *folio, size_t offset); int btrfs_alloc_page_array(unsigned int nr_pages, struct page **page_array); From patchwork Tue Nov 15 18:00:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13044047 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 53CF7C43219 for ; Tue, 15 Nov 2022 18:01:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238393AbiKOSBs (ORCPT ); Tue, 15 Nov 2022 13:01:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51778 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238278AbiKOSBL (ORCPT ); Tue, 15 Nov 2022 13:01:11 -0500 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0693E1157 for ; Tue, 15 Nov 2022 10:00:52 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id B293D33688; Tue, 15 Nov 2022 18:00:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1668535250; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GijL5/Y3oGaK8CJh9+F4rjmFJZqDl2bmnRrf+LTx3i4=; b=MFCjQgdupdyCO/of3Kn2kLZebnIN1CL0sab2wlK5DQ4GZ4HXjVNxKvcuZIHUmRk1ChhJjh HJhuSAbquRocLxCKh3TQu0rTY8kemdtM3IAKVn9GaCtTpg/KSh5cOT4xCuplcpVKFwU9l5 pwWcW9M6dtCIYsI/YalWqRD9ND+H+yQ= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1668535250; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GijL5/Y3oGaK8CJh9+F4rjmFJZqDl2bmnRrf+LTx3i4=; b=YEwfNA5t5QGyeFfgcbAKTs9gna35qVmFcXvsPzAOCRVAIji/bU9jQ7S/9jYObvvAZSPQ/e fTi0trFsi10MBFAw== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 635DA13A91; Tue, 15 Nov 2022 18:00:50 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id oIxIENLTc2OfZAAAMHmgww (envelope-from ); Tue, 15 Nov 2022 18:00:50 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Goldwyn Rodrigues Subject: [PATCH 06/16] btrfs: Lock extents before pages in writepages Date: Tue, 15 Nov 2022 12:00:24 -0600 Message-Id: <28cb7dbc0216d2a5f55efd296113f9f9576dda41.1668530684.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org writepages() locks the extents in find_lock_delalloc_range() and unlocks using clear_bit EXTENT_LOCKED operations is cow/delalloc operations. Call extent locking/unlocking around writepages() sequence as opposed to while performing delayed allocation. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/extent_io.c | 5 ----- fs/btrfs/inode.c | 43 +++++++++++++++++++++++++++++++------------ 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 92068e4ff9c3..42bae149f923 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -464,15 +464,10 @@ noinline_for_stack bool find_lock_delalloc_range(struct inode *inode, } } - /* step three, lock the state bits for the whole range */ - lock_extent(tree, delalloc_start, delalloc_end, &cached_state); - /* then test to make sure it is all still delalloc */ ret = test_range_bit(tree, delalloc_start, delalloc_end, EXTENT_DELALLOC, 1, cached_state); if (!ret) { - unlock_extent(tree, delalloc_start, delalloc_end, - &cached_state); __unlock_for_delalloc(inode, locked_page, delalloc_start, delalloc_end); cond_resched(); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 4bfa51871ddc..92726831dd5d 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -992,7 +992,6 @@ static int submit_one_async_extent(struct btrfs_inode *inode, struct async_extent *async_extent, u64 *alloc_hint) { - struct extent_io_tree *io_tree = &inode->io_tree; struct btrfs_root *root = inode->root; struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_key ins; @@ -1013,7 +1012,6 @@ static int submit_one_async_extent(struct btrfs_inode *inode, if (!(start >= locked_page_end || end <= locked_page_start)) locked_page = async_chunk->locked_page; } - lock_extent(io_tree, start, end, NULL); /* We have fall back to uncompressed write */ if (!async_extent->pages) @@ -1067,7 +1065,7 @@ static int submit_one_async_extent(struct btrfs_inode *inode, /* Clear dirty, set writeback and unlock the pages. */ extent_clear_unlock_delalloc(inode, start, end, - NULL, EXTENT_LOCKED | EXTENT_DELALLOC, + NULL, EXTENT_DELALLOC, PAGE_UNLOCK | PAGE_START_WRITEBACK); if (btrfs_submit_compressed_write(inode, start, /* file_offset */ async_extent->ram_size, /* num_bytes */ @@ -1095,7 +1093,7 @@ static int submit_one_async_extent(struct btrfs_inode *inode, btrfs_free_reserved_extent(fs_info, ins.objectid, ins.offset, 1); out_free: extent_clear_unlock_delalloc(inode, start, end, - NULL, EXTENT_LOCKED | EXTENT_DELALLOC | + NULL, EXTENT_DELALLOC | EXTENT_DELALLOC_NEW | EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING, PAGE_UNLOCK | PAGE_START_WRITEBACK | @@ -1263,7 +1261,7 @@ static noinline int cow_file_range(struct btrfs_inode *inode, */ extent_clear_unlock_delalloc(inode, start, end, locked_page, - EXTENT_LOCKED | EXTENT_DELALLOC | + EXTENT_DELALLOC | EXTENT_DELALLOC_NEW | EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING, PAGE_UNLOCK | PAGE_START_WRITEBACK | PAGE_END_WRITEBACK); @@ -1374,7 +1372,7 @@ static noinline int cow_file_range(struct btrfs_inode *inode, extent_clear_unlock_delalloc(inode, start, start + ram_size - 1, locked_page, - EXTENT_LOCKED | EXTENT_DELALLOC, + EXTENT_DELALLOC, page_ops); if (num_bytes < cur_alloc_size) num_bytes = 0; @@ -1425,7 +1423,7 @@ static noinline int cow_file_range(struct btrfs_inode *inode, * We process each region below. */ - clear_bits = EXTENT_LOCKED | EXTENT_DELALLOC | EXTENT_DELALLOC_NEW | + clear_bits = EXTENT_DELALLOC | EXTENT_DELALLOC_NEW | EXTENT_DEFRAG | EXTENT_CLEAR_META_RESV; page_ops = PAGE_UNLOCK | PAGE_START_WRITEBACK | PAGE_END_WRITEBACK; @@ -1575,7 +1573,7 @@ static int cow_file_range_async(struct btrfs_inode *inode, memalloc_nofs_restore(nofs_flag); if (!ctx) { - unsigned clear_bits = EXTENT_LOCKED | EXTENT_DELALLOC | + unsigned clear_bits = EXTENT_DELALLOC | EXTENT_DELALLOC_NEW | EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING; unsigned long page_ops = PAGE_UNLOCK | PAGE_START_WRITEBACK | @@ -1955,7 +1953,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode, path = btrfs_alloc_path(); if (!path) { extent_clear_unlock_delalloc(inode, start, end, locked_page, - EXTENT_LOCKED | EXTENT_DELALLOC | + EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, PAGE_UNLOCK | PAGE_START_WRITEBACK | @@ -2169,7 +2167,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode, nocow_args.num_bytes); extent_clear_unlock_delalloc(inode, cur_offset, nocow_end, - locked_page, EXTENT_LOCKED | + locked_page, EXTENT_DELALLOC | EXTENT_CLEAR_DATA_RESV, PAGE_UNLOCK | PAGE_SET_ORDERED); @@ -2205,7 +2203,7 @@ static noinline int run_delalloc_nocow(struct btrfs_inode *inode, if (ret && cur_offset < end) extent_clear_unlock_delalloc(inode, cur_offset, end, - locked_page, EXTENT_LOCKED | + locked_page, EXTENT_DELALLOC | EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING, PAGE_UNLOCK | PAGE_START_WRITEBACK | @@ -8223,7 +8221,28 @@ static int btrfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, static int btrfs_writepages(struct address_space *mapping, struct writeback_control *wbc) { - return extent_writepages(mapping, wbc); + u64 start, end; + struct inode *inode = mapping->host; + struct extent_state *cached = NULL; + int ret; + u64 isize = round_up(i_size_read(inode), PAGE_SIZE) - 1; + + if (wbc->range_cyclic) { + start = mapping->writeback_index << PAGE_SHIFT; + end = isize; + } else { + start = round_down(wbc->range_start, PAGE_SIZE); + end = round_up(wbc->range_end, PAGE_SIZE) - 1; + end = min(isize, end); + } + + if (start >= end) + return 0; + + lock_extent(&BTRFS_I(inode)->io_tree, start, end, &cached); + ret = extent_writepages(mapping, wbc); + unlock_extent(&BTRFS_I(inode)->io_tree, start, end, &cached); + return ret; } static void btrfs_readahead(struct readahead_control *rac) From patchwork Tue Nov 15 18:00:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13044048 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 562EFC4332F for ; Tue, 15 Nov 2022 18:01:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238401AbiKOSBt (ORCPT ); Tue, 15 Nov 2022 13:01:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50512 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238294AbiKOSBM (ORCPT ); Tue, 15 Nov 2022 13:01:12 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 834B6C03 for ; Tue, 15 Nov 2022 10:00:54 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 415361F8E0; Tue, 15 Nov 2022 18:00:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1668535253; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vGarr4DN5B7hiz14x15U9Lw/fKq3vgsceZuvf/ubqqo=; b=rjU+I9AlU6au1709xR2/ePM57vUpvMQRBLSm6LBJvlSdoKg1wb5RxTqZKV8aZJYRptrBqk kWF4P8tzmbrGZdOG31dw3zN6hcqkX+nrYFQp3EU0IRE+bl9F7o8xSIN/y6Q/DNcH31P319 Ejdbg9D9zg4f3p941i6Y6bt5rB4hxdQ= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1668535253; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vGarr4DN5B7hiz14x15U9Lw/fKq3vgsceZuvf/ubqqo=; b=0Mn9ySS1DLn6t5/ZnGjby3CDTqGmetkFAVhFJTUV4gOdDiC2quqvf8cpg0TPAGvSvucfgo mdtF2hjQzwfBgvCw== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id D4C8913A91; Tue, 15 Nov 2022 18:00:52 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id /MYsKtTTc2OhZAAAMHmgww (envelope-from ); Tue, 15 Nov 2022 18:00:52 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Goldwyn Rodrigues Subject: [PATCH 07/16] btrfs: Lock extents before folio for read()s Date: Tue, 15 Nov 2022 12:00:25 -0600 Message-Id: <5c7c77d0735c18cea82c347eef2ce2eb169681e6.1668530684.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Perform extent locking around buffered reads as opposed to while performing folio reads. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/compression.c | 5 ----- fs/btrfs/extent_io.c | 36 +----------------------------------- fs/btrfs/file.c | 17 ++++++++++++++--- 3 files changed, 15 insertions(+), 43 deletions(-) diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 30adf430241e..7f6452c4234e 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -526,11 +526,9 @@ static noinline int add_ra_bio_pages(struct inode *inode, struct extent_map *em; struct address_space *mapping = inode->i_mapping; struct extent_map_tree *em_tree; - struct extent_io_tree *tree; int sectors_missed = 0; em_tree = &BTRFS_I(inode)->extent_tree; - tree = &BTRFS_I(inode)->io_tree; if (isize == 0) return 0; @@ -597,7 +595,6 @@ static noinline int add_ra_bio_pages(struct inode *inode, } page_end = (pg_index << PAGE_SHIFT) + PAGE_SIZE - 1; - lock_extent(tree, cur, page_end, NULL); read_lock(&em_tree->lock); em = lookup_extent_mapping(em_tree, cur, page_end + 1 - cur); read_unlock(&em_tree->lock); @@ -611,7 +608,6 @@ static noinline int add_ra_bio_pages(struct inode *inode, (cur + fs_info->sectorsize > extent_map_end(em)) || (em->block_start >> 9) != cb->orig_bio->bi_iter.bi_sector) { free_extent_map(em); - unlock_extent(tree, cur, page_end, NULL); unlock_page(page); put_page(page); break; @@ -631,7 +627,6 @@ static noinline int add_ra_bio_pages(struct inode *inode, add_size = min(em->start + em->len, page_end + 1) - cur; ret = bio_add_page(cb->orig_bio, page, add_size, offset_in_page(cur)); if (ret != add_size) { - unlock_extent(tree, cur, page_end, NULL); unlock_page(page); put_page(page); break; diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 42bae149f923..c5430cabad62 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -891,15 +891,6 @@ static void end_page_read(struct page *page, bool uptodate, u64 start, u32 len) btrfs_subpage_end_reader(fs_info, page, start, len); } -static void end_sector_io(struct page *page, u64 offset, bool uptodate) -{ - struct btrfs_inode *inode = BTRFS_I(page->mapping->host); - const u32 sectorsize = inode->root->fs_info->sectorsize; - - end_page_read(page, uptodate, offset, sectorsize); - unlock_extent(&inode->io_tree, offset, offset + sectorsize - 1, NULL); -} - static void submit_data_read_repair(struct inode *inode, struct btrfs_bio *failed_bbio, u32 bio_offset, const struct bio_vec *bvec, @@ -960,7 +951,7 @@ static void submit_data_read_repair(struct inode *inode, * will not be properly unlocked. */ next: - end_sector_io(page, start + offset, uptodate); + end_page_read(page, uptodate, start + offset, sectorsize); } } @@ -1072,9 +1063,6 @@ static void endio_readpage_release_extent(struct processed_extent *processed, struct btrfs_inode *inode, u64 start, u64 end, bool uptodate) { - struct extent_state *cached = NULL; - struct extent_io_tree *tree; - /* The first extent, initialize @processed */ if (!processed->inode) goto update; @@ -1096,13 +1084,6 @@ static void endio_readpage_release_extent(struct processed_extent *processed, return; } - tree = &processed->inode->io_tree; - /* - * Now we don't have range contiguous to the processed range, release - * the processed range now. - */ - unlock_extent(tree, processed->start, processed->end, &cached); - update: /* Update processed to current range */ processed->inode = inode; @@ -1743,11 +1724,9 @@ static int btrfs_do_readpage(struct page *page, struct extent_map **em_cached, size_t pg_offset = 0; size_t iosize; size_t blocksize = inode->i_sb->s_blocksize; - struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree; ret = set_page_extent_mapped(page); if (ret < 0) { - unlock_extent(tree, start, end, NULL); btrfs_page_set_error(fs_info, page, start, PAGE_SIZE); unlock_page(page); goto out; @@ -1772,14 +1751,12 @@ static int btrfs_do_readpage(struct page *page, struct extent_map **em_cached, if (cur >= last_byte) { iosize = PAGE_SIZE - pg_offset; memzero_page(page, pg_offset, iosize); - unlock_extent(tree, cur, cur + iosize - 1, NULL); end_page_read(page, true, cur, iosize); break; } em = __get_extent_map(inode, page, pg_offset, cur, end - cur + 1, em_cached); if (IS_ERR(em)) { - unlock_extent(tree, cur, end, NULL); end_page_read(page, false, cur, end + 1 - cur); ret = PTR_ERR(em); break; @@ -1849,8 +1826,6 @@ static int btrfs_do_readpage(struct page *page, struct extent_map **em_cached, /* we've found a hole, just zero and go on */ if (block_start == EXTENT_MAP_HOLE) { memzero_page(page, pg_offset, iosize); - - unlock_extent(tree, cur, cur + iosize - 1, NULL); end_page_read(page, true, cur, iosize); cur = cur + iosize; pg_offset += iosize; @@ -1858,7 +1833,6 @@ static int btrfs_do_readpage(struct page *page, struct extent_map **em_cached, } /* the get_extent function already copied into the page */ if (block_start == EXTENT_MAP_INLINE) { - unlock_extent(tree, cur, cur + iosize - 1, NULL); end_page_read(page, true, cur, iosize); cur = cur + iosize; pg_offset += iosize; @@ -1874,7 +1848,6 @@ static int btrfs_do_readpage(struct page *page, struct extent_map **em_cached, * We have to unlock the remaining range, or the page * will never be unlocked. */ - unlock_extent(tree, cur, end, NULL); end_page_read(page, false, cur, end + 1 - cur); goto out; } @@ -1888,13 +1861,9 @@ static int btrfs_do_readpage(struct page *page, struct extent_map **em_cached, int btrfs_read_folio(struct file *file, struct folio *folio) { struct page *page = &folio->page; - struct btrfs_inode *inode = BTRFS_I(page->mapping->host); - u64 start = page_offset(page); - u64 end = start + PAGE_SIZE - 1; struct btrfs_bio_ctrl bio_ctrl = { 0 }; int ret; - btrfs_lock_and_flush_ordered_range(inode, start, end, NULL); ret = btrfs_do_readpage(page, NULL, &bio_ctrl, 0, NULL); /* @@ -1911,11 +1880,8 @@ static inline void contiguous_readpages(struct page *pages[], int nr_pages, struct btrfs_bio_ctrl *bio_ctrl, u64 *prev_em_start) { - struct btrfs_inode *inode = BTRFS_I(pages[0]->mapping->host); int index; - btrfs_lock_and_flush_ordered_range(inode, start, end, NULL); - for (index = 0; index < nr_pages; index++) { btrfs_do_readpage(pages[index], em_cached, bio_ctrl, REQ_RAHEAD, prev_em_start); diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 473a0743270b..9266ee6c1a61 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -3806,15 +3806,26 @@ static ssize_t btrfs_direct_read(struct kiocb *iocb, struct iov_iter *to) static ssize_t btrfs_file_read_iter(struct kiocb *iocb, struct iov_iter *to) { ssize_t ret = 0; + struct inode *inode = file_inode(iocb->ki_filp); + loff_t len = iov_iter_count(to); + u64 start = round_down(iocb->ki_pos, PAGE_SIZE); + u64 end = round_up(iocb->ki_pos + len, PAGE_SIZE) - 1; + struct extent_state *cached = NULL; if (iocb->ki_flags & IOCB_DIRECT) { ret = btrfs_direct_read(iocb, to); - if (ret < 0 || !iov_iter_count(to) || - iocb->ki_pos >= i_size_read(file_inode(iocb->ki_filp))) + if (ret < 0 || !len || + iocb->ki_pos >= i_size_read(inode)) return ret; } - return filemap_read(iocb, to, ret); + btrfs_lock_and_flush_ordered_range(BTRFS_I(inode), start, + end, &cached); + + ret = filemap_read(iocb, to, ret); + + unlock_extent(&BTRFS_I(inode)->io_tree, start, end, &cached); + return ret; } const struct file_operations btrfs_file_operations = { From patchwork Tue Nov 15 18:00:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13044049 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5D33DC433FE for ; Tue, 15 Nov 2022 18:01:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238294AbiKOSBu (ORCPT ); Tue, 15 Nov 2022 13:01:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51792 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238299AbiKOSBM (ORCPT ); Tue, 15 Nov 2022 13:01:12 -0500 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9A914CD8 for ; Tue, 15 Nov 2022 10:00:56 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 59BFE336CD; Tue, 15 Nov 2022 18:00:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1668535255; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YlvVevUyxLJUPaEGndY91b0zfj8IZJxwb8yZRJLnu0Q=; b=il/WWpO2JTofiCWruz7+HErZM/LEm613Zo50L1ghJrHWvozWCiVonjfvxOMVZ1wZw7Z8D5 fviG5oeLBwq46ASUBBcrFV5BYH3oaHj2q26DGf8N1otgYrNsgFf+2HR95THuJe4C2ltypN M37n514E8d7RIjt176/jTHtfsuCm8mw= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1668535255; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YlvVevUyxLJUPaEGndY91b0zfj8IZJxwb8yZRJLnu0Q=; b=HlMnX3CZ0U6YiHkhc/oBS067uTkpsi99zzP+6PffFGD75P4LvaWouGIWIrPEUchQUpp+HN tNWdkGijV75TN0CA== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 0E0FA13A91; Tue, 15 Nov 2022 18:00:54 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 4hoCN9bTc2OjZAAAMHmgww (envelope-from ); Tue, 15 Nov 2022 18:00:54 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Goldwyn Rodrigues Subject: [PATCH 08/16] btrfs: Lock extents before pages for buffered write() Date: Tue, 15 Nov 2022 12:00:26 -0600 Message-Id: <387d15a567d7c56ceb2408783ebe31e431cb537f.1668530684.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org While performing writes, lock the extents before locking the pages. Ideally, this should be done before space reservations. However, This is performed after check for space because qgroup initiates writeback which may cause deadlocks. Signed-off-by: Goldwyn Rodrigues Reviewed-by: Josef Bacik --- fs/btrfs/file.c | 78 ++++++++++++------------------------------------- 1 file changed, 19 insertions(+), 59 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 9266ee6c1a61..559214ded4eb 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -967,8 +967,8 @@ static noinline int prepare_pages(struct inode *inode, struct page **pages, * the other < 0 number - Something wrong happens */ static noinline int -lock_and_cleanup_extent_if_need(struct btrfs_inode *inode, struct page **pages, - size_t num_pages, loff_t pos, +lock_and_cleanup_extent_if_need(struct btrfs_inode *inode, + loff_t pos, size_t write_bytes, u64 *lockstart, u64 *lockend, bool nowait, struct extent_state **cached_state) @@ -976,7 +976,6 @@ lock_and_cleanup_extent_if_need(struct btrfs_inode *inode, struct page **pages, struct btrfs_fs_info *fs_info = inode->root->fs_info; u64 start_pos; u64 last_pos; - int i; int ret = 0; start_pos = round_down(pos, fs_info->sectorsize); @@ -987,15 +986,8 @@ lock_and_cleanup_extent_if_need(struct btrfs_inode *inode, struct page **pages, if (nowait) { if (!try_lock_extent(&inode->io_tree, start_pos, last_pos, - cached_state)) { - for (i = 0; i < num_pages; i++) { - unlock_page(pages[i]); - put_page(pages[i]); - pages[i] = NULL; - } - + cached_state)) return -EAGAIN; - } } else { lock_extent(&inode->io_tree, start_pos, last_pos, cached_state); } @@ -1007,10 +999,6 @@ lock_and_cleanup_extent_if_need(struct btrfs_inode *inode, struct page **pages, ordered->file_offset <= last_pos) { unlock_extent(&inode->io_tree, start_pos, last_pos, cached_state); - for (i = 0; i < num_pages; i++) { - unlock_page(pages[i]); - put_page(pages[i]); - } btrfs_start_ordered_extent(ordered, 1); btrfs_put_ordered_extent(ordered); return -EAGAIN; @@ -1023,13 +1011,6 @@ lock_and_cleanup_extent_if_need(struct btrfs_inode *inode, struct page **pages, ret = 1; } - /* - * We should be called after prepare_pages() which should have locked - * all pages in the range. - */ - for (i = 0; i < num_pages; i++) - WARN_ON(!PageLocked(pages[i])); - return ret; } @@ -1306,13 +1287,22 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb, } release_bytes = reserve_bytes; -again: ret = balance_dirty_pages_ratelimited_flags(inode->i_mapping, bdp_flags); if (ret) { btrfs_delalloc_release_extents(BTRFS_I(inode), reserve_bytes); break; } + extents_locked = lock_and_cleanup_extent_if_need(BTRFS_I(inode), + pos, write_bytes, &lockstart, &lockend, + nowait, &cached_state); + if (extents_locked < 0) { + ret = extents_locked; + btrfs_delalloc_release_extents(BTRFS_I(inode), reserve_bytes); + break; + } + + /* * This is going to setup the pages array with the number of * pages we want, so we don't really need to worry about the @@ -1320,25 +1310,9 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb, */ ret = prepare_pages(inode, pages, num_pages, pos, write_bytes, force_page_uptodate, false); - if (ret) { - btrfs_delalloc_release_extents(BTRFS_I(inode), - reserve_bytes); - break; - } - - extents_locked = lock_and_cleanup_extent_if_need( - BTRFS_I(inode), pages, - num_pages, pos, write_bytes, &lockstart, - &lockend, nowait, &cached_state); - if (extents_locked < 0) { - if (!nowait && extents_locked == -EAGAIN) - goto again; - + if (ret) btrfs_delalloc_release_extents(BTRFS_I(inode), reserve_bytes); - ret = extents_locked; - break; - } copied = btrfs_copy_from_user(pos, write_bytes, pages, i); @@ -1387,33 +1361,19 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb, ret = btrfs_dirty_pages(BTRFS_I(inode), pages, dirty_pages, pos, copied, - &cached_state, only_release_metadata); - - /* - * If we have not locked the extent range, because the range's - * start offset is >= i_size, we might still have a non-NULL - * cached extent state, acquired while marking the extent range - * as delalloc through btrfs_dirty_pages(). Therefore free any - * possible cached extent state to avoid a memory leak. - */ - if (extents_locked) - unlock_extent(&BTRFS_I(inode)->io_tree, lockstart, - lockend, &cached_state); - else - free_extent_state(cached_state); + NULL, only_release_metadata); btrfs_delalloc_release_extents(BTRFS_I(inode), reserve_bytes); - if (ret) { - btrfs_drop_pages(fs_info, pages, num_pages, pos, copied); + btrfs_drop_pages(fs_info, pages, num_pages, pos, copied); + if (extents_locked) + unlock_extent(&BTRFS_I(inode)->io_tree, lockstart, lockend, &cached_state); + if (ret) break; - } release_bytes = 0; if (only_release_metadata) btrfs_check_nocow_unlock(BTRFS_I(inode)); - btrfs_drop_pages(fs_info, pages, num_pages, pos, copied); - cond_resched(); pos += copied; From patchwork Tue Nov 15 18:00:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13044050 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2F767C4332F for ; Tue, 15 Nov 2022 18:02:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229785AbiKOSBw (ORCPT ); Tue, 15 Nov 2022 13:01:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50728 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238328AbiKOSBM (ORCPT ); Tue, 15 Nov 2022 13:01:12 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DFFC4C6F for ; Tue, 15 Nov 2022 10:00:58 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 9AB3F1F8E9; Tue, 15 Nov 2022 18:00:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1668535257; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=SnbTSvjoJjWsQJbvP3aYbA704ygvLB72HpnbdDRNaTA=; b=0f27JIUbUIyB6cxl7vWiE28lsxoVu3za20b9igIQLX3FtfHoUUB++fSMbKrjGwOhDD59U/ FvtpFfdKw1LtT47hFnNHIQ1NQmmiql6IGOhSMxYk1n2hakinw9bpJRdnm2baf7/mwL5+U6 OjwZKPvNedWolCHks0I4Pp+hw0GZeTA= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1668535257; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=SnbTSvjoJjWsQJbvP3aYbA704ygvLB72HpnbdDRNaTA=; b=oX6B81YycHFADHMfX+OqBkg+6yFw2WxmyAjV9Qlv7n2jG0wCurhwR7aWCIesVmdohrbpeJ 2pE1BIZ54pRpSlAw== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 5326813A91; Tue, 15 Nov 2022 18:00:57 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id ekZMC9nTc2OrZAAAMHmgww (envelope-from ); Tue, 15 Nov 2022 18:00:57 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Goldwyn Rodrigues Subject: [PATCH 09/16] btrfs: lock/unlock extents while creation/end of async_chunk Date: Tue, 15 Nov 2022 12:00:27 -0600 Message-Id: X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org writepages() writebacks the unwritten pages the synchronously. So we know that once writepages returns, the pages are "done" and can be safely unlocked. However, with async writes, this is done over a thread. So, for async writeback, perform this within the async thread. Locking is performed at origin of async_chunk and unlocked when async_chunk completes. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/inode.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 92726831dd5d..aa393219019b 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -528,6 +528,7 @@ struct async_chunk { struct list_head extents; struct cgroup_subsys_state *blkcg_css; struct btrfs_work work; + struct extent_state *cached_state; struct async_cow *async_cow; }; @@ -1491,6 +1492,9 @@ static noinline void async_cow_start(struct btrfs_work *work) compressed_extents = compress_file_range(async_chunk); if (compressed_extents == 0) { + unlock_extent(&async_chunk->inode->io_tree, + async_chunk->start, async_chunk->end, + &async_chunk->cached_state); btrfs_add_delayed_iput(async_chunk->inode); async_chunk->inode = NULL; } @@ -1530,11 +1534,16 @@ static noinline void async_cow_free(struct btrfs_work *work) struct async_cow *async_cow; async_chunk = container_of(work, struct async_chunk, work); - if (async_chunk->inode) + if (async_chunk->inode) { + unlock_extent(&async_chunk->inode->io_tree, + async_chunk->start, async_chunk->end, + &async_chunk->cached_state); btrfs_add_delayed_iput(async_chunk->inode); + } if (async_chunk->blkcg_css) css_put(async_chunk->blkcg_css); + async_cow = async_chunk->async_cow; if (atomic_dec_and_test(&async_cow->num_chunks)) kvfree(async_cow); @@ -1558,7 +1567,6 @@ static int cow_file_range_async(struct btrfs_inode *inode, unsigned nofs_flag; const blk_opf_t write_flags = wbc_to_write_flags(wbc); - unlock_extent(&inode->io_tree, start, end, NULL); if (inode->flags & BTRFS_INODE_NOCOMPRESS && !btrfs_test_opt(fs_info, FORCE_COMPRESS)) { @@ -1600,6 +1608,9 @@ static int cow_file_range_async(struct btrfs_inode *inode, ihold(&inode->vfs_inode); async_chunk[i].async_cow = ctx; async_chunk[i].inode = inode; + async_chunk[i].cached_state = NULL; + btrfs_lock_and_flush_ordered_range(inode, start, cur_end, + &async_chunk[i].cached_state); async_chunk[i].start = start; async_chunk[i].end = cur_end; async_chunk[i].write_flags = write_flags; @@ -8222,10 +8233,11 @@ static int btrfs_writepages(struct address_space *mapping, struct writeback_control *wbc) { u64 start, end; - struct inode *inode = mapping->host; + struct btrfs_inode *inode = BTRFS_I(mapping->host); struct extent_state *cached = NULL; + bool async_wb; int ret; - u64 isize = round_up(i_size_read(inode), PAGE_SIZE) - 1; + u64 isize = round_up(i_size_read(&inode->vfs_inode), PAGE_SIZE) - 1; if (wbc->range_cyclic) { start = mapping->writeback_index << PAGE_SHIFT; @@ -8239,9 +8251,18 @@ static int btrfs_writepages(struct address_space *mapping, if (start >= end) return 0; - lock_extent(&BTRFS_I(inode)->io_tree, start, end, &cached); + /* + * For async I/O, locking and unlocking is performed with the + * allocation and completion of async_chunk. + */ + async_wb = btrfs_inode_can_compress(inode) && + inode_need_compress(inode, start, end); + if (!async_wb) + lock_extent(&inode->io_tree, start, end, &cached); ret = extent_writepages(mapping, wbc); - unlock_extent(&BTRFS_I(inode)->io_tree, start, end, &cached); + if (!async_wb) + unlock_extent(&inode->io_tree, start, end, &cached); + return ret; } From patchwork Tue Nov 15 18:00:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13044053 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A9745C43217 for ; Tue, 15 Nov 2022 18:02:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237647AbiKOSBx (ORCPT ); Tue, 15 Nov 2022 13:01:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51784 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238341AbiKOSBM (ORCPT ); Tue, 15 Nov 2022 13:01:12 -0500 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EB38C10AE for ; Tue, 15 Nov 2022 10:01:00 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id A33AE33688; Tue, 15 Nov 2022 18:00:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1668535259; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=m1S9aFMQgZSYdBscg33X+SuuffT4OeQntDrE+719T5g=; b=y3Pcok3KHoxrF/lXKuNqsQnliJgVLU7T3SW+nZmMqT93jwRfZe3ztIVqmsVETWpXm8es6j Dy3awhZRYpGK03d0/VipBEvbcuTYmubvu4jIwz3JTyoaHEadMVZpQ5iuEk+tegU+Ytg9c/ omjTTev0adf1oDgtQEhQjKyuHbrfVZk= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1668535259; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=m1S9aFMQgZSYdBscg33X+SuuffT4OeQntDrE+719T5g=; b=EMoDjGiEDamFEdBqROVOUUrx4kJ6SrQTamq7ObuMLAFDa4UApUDaJJxGjpobB+RKL+HaZz lIwoM0IoW2ienNAg== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 5BF9313A91; Tue, 15 Nov 2022 18:00:59 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id YRQ5DtvTc2OuZAAAMHmgww (envelope-from ); Tue, 15 Nov 2022 18:00:59 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Goldwyn Rodrigues Subject: [PATCH 10/16] btrfs: decide early if range should be async Date: Tue, 15 Nov 2022 12:00:28 -0600 Message-Id: X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org This sets the async bit early in the writeback and uses it to decide if it should write asynchronously. Since there could be missing pages, check if page is NULL while performing heuristics. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/compression.c | 4 ++++ fs/btrfs/inode.c | 11 +++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 7f6452c4234e..09b846a516ed 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -1610,6 +1610,10 @@ static void heuristic_collect_sample(struct inode *inode, u64 start, u64 end, curr_sample_pos = 0; while (index < index_end) { page = find_get_page(inode->i_mapping, index); + if (!page) { + index++; + continue; + } in_data = kmap_local_page(page); /* Handle case where the start is not aligned to PAGE_SIZE */ i = start % PAGE_SIZE; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index aa393219019b..070fb7071e39 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2264,8 +2264,7 @@ int btrfs_run_delalloc_range(struct btrfs_inode *inode, struct page *locked_page ASSERT(!zoned || btrfs_is_data_reloc_root(inode->root)); ret = run_delalloc_nocow(inode, locked_page, start, end, page_started, nr_written); - } else if (!btrfs_inode_can_compress(inode) || - !inode_need_compress(inode, start, end)) { + } else if (!test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, &inode->runtime_flags)) { if (zoned) ret = run_delalloc_zoned(inode, locked_page, start, end, page_started, nr_written); @@ -2273,7 +2272,6 @@ int btrfs_run_delalloc_range(struct btrfs_inode *inode, struct page *locked_page ret = cow_file_range(inode, locked_page, start, end, page_started, nr_written, 1, NULL); } else { - set_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, &inode->runtime_flags); ret = cow_file_range_async(inode, wbc, locked_page, start, end, page_started, nr_written); } @@ -8257,9 +8255,14 @@ static int btrfs_writepages(struct address_space *mapping, */ async_wb = btrfs_inode_can_compress(inode) && inode_need_compress(inode, start, end); - if (!async_wb) + + if (async_wb) + set_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, &inode->runtime_flags); + else lock_extent(&inode->io_tree, start, end, &cached); + ret = extent_writepages(mapping, wbc); + if (!async_wb) unlock_extent(&inode->io_tree, start, end, &cached); From patchwork Tue Nov 15 18:00:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13044052 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CA43AC4321E for ; Tue, 15 Nov 2022 18:02:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238416AbiKOSBz (ORCPT ); Tue, 15 Nov 2022 13:01:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50690 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238362AbiKOSBM (ORCPT ); Tue, 15 Nov 2022 13:01:12 -0500 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F067E23 for ; Tue, 15 Nov 2022 10:01:03 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id CADAA336CD; Tue, 15 Nov 2022 18:01:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1668535261; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Eq1QK8PaSBDmfGrMkmM7IlCNVB9KX+y+0shSOsb3gV8=; b=tU2JK22C+qCsBgNmjxr2Efchbm6xo2e+cLm79Bs+kb3FqL19wTkDrHBwi2wjVRmAZRVZPk 5NKbl+x4+Qt3qBT6K9KSfwVr/c/VnLx7BCioyCqS05x65tTJrYRFeBnpgNhYrAQHy+yQmX dAgtLeK9JtLBJAj0VvroHOythDWPP2U= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1668535261; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Eq1QK8PaSBDmfGrMkmM7IlCNVB9KX+y+0shSOsb3gV8=; b=CTu57/WWqLCCu2KG/V8jawI+ab1Yx77UrnUde1LxIpTZTLexqegBFnwnyfjs0ucq7uXFI5 UrKnY7mT4v86hcAg== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 7C00413A91; Tue, 15 Nov 2022 18:01:01 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id S+FAFt3Tc2OyZAAAMHmgww (envelope-from ); Tue, 15 Nov 2022 18:01:01 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Goldwyn Rodrigues Subject: [PATCH 11/16] btrfs: lock extents before pages - defrag Date: Tue, 15 Nov 2022 12:00:29 -0600 Message-Id: <9d2c5c3625dae4a58dfb42a387f33f1f7be0fe42.1668530684.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org lock and flush the range before performing defrag. Signed-off-by: Goldwyn Rodrigues Reviewed-by: Josef Bacik --- fs/btrfs/defrag.c | 48 ++++++++++------------------------------------- 1 file changed, 10 insertions(+), 38 deletions(-) diff --git a/fs/btrfs/defrag.c b/fs/btrfs/defrag.c index 0a3c261b69c9..5345c121ac46 100644 --- a/fs/btrfs/defrag.c +++ b/fs/btrfs/defrag.c @@ -719,9 +719,6 @@ static struct page *defrag_prepare_one_page(struct btrfs_inode *inode, pgoff_t i { struct address_space *mapping = inode->vfs_inode.i_mapping; gfp_t mask = btrfs_alloc_write_mask(mapping); - u64 page_start = (u64)index << PAGE_SHIFT; - u64 page_end = page_start + PAGE_SIZE - 1; - struct extent_state *cached_state = NULL; struct page *page; int ret; @@ -751,32 +748,6 @@ static struct page *defrag_prepare_one_page(struct btrfs_inode *inode, pgoff_t i return ERR_PTR(ret); } - /* Wait for any existing ordered extent in the range */ - while (1) { - struct btrfs_ordered_extent *ordered; - - lock_extent(&inode->io_tree, page_start, page_end, &cached_state); - ordered = btrfs_lookup_ordered_range(inode, page_start, PAGE_SIZE); - unlock_extent(&inode->io_tree, page_start, page_end, - &cached_state); - if (!ordered) - break; - - unlock_page(page); - btrfs_start_ordered_extent(ordered, 1); - btrfs_put_ordered_extent(ordered); - lock_page(page); - /* - * We unlocked the page above, so we need check if it was - * released or not. - */ - if (page->mapping != mapping || !PagePrivate(page)) { - unlock_page(page); - put_page(page); - goto again; - } - } - /* * Now the page range has no ordered extent any more. Read the page to * make it uptodate. @@ -1074,6 +1045,11 @@ static int defrag_one_range(struct btrfs_inode *inode, u64 start, u32 len, if (!pages) return -ENOMEM; + /* Lock the pages range */ + btrfs_lock_and_flush_ordered_range(inode, start_index << PAGE_SHIFT, + (last_index << PAGE_SHIFT) + PAGE_SIZE - 1, + &cached_state); + /* Prepare all pages */ for (i = 0; i < nr_pages; i++) { pages[i] = defrag_prepare_one_page(inode, start_index + i); @@ -1086,10 +1062,6 @@ static int defrag_one_range(struct btrfs_inode *inode, u64 start, u32 len, for (i = 0; i < nr_pages; i++) wait_on_page_writeback(pages[i]); - /* Lock the pages range */ - lock_extent(&inode->io_tree, start_index << PAGE_SHIFT, - (last_index << PAGE_SHIFT) + PAGE_SIZE - 1, - &cached_state); /* * Now we have a consistent view about the extent map, re-check * which range really needs to be defragged. @@ -1101,7 +1073,7 @@ static int defrag_one_range(struct btrfs_inode *inode, u64 start, u32 len, newer_than, do_compress, true, &target_list, last_scanned_ret); if (ret < 0) - goto unlock_extent; + goto free_pages; list_for_each_entry(entry, &target_list, list) { ret = defrag_one_locked_target(inode, entry, pages, nr_pages, @@ -1114,10 +1086,6 @@ static int defrag_one_range(struct btrfs_inode *inode, u64 start, u32 len, list_del_init(&entry->list); kfree(entry); } -unlock_extent: - unlock_extent(&inode->io_tree, start_index << PAGE_SHIFT, - (last_index << PAGE_SHIFT) + PAGE_SIZE - 1, - &cached_state); free_pages: for (i = 0; i < nr_pages; i++) { if (pages[i]) { @@ -1126,6 +1094,10 @@ static int defrag_one_range(struct btrfs_inode *inode, u64 start, u32 len, } } kfree(pages); + + unlock_extent(&inode->io_tree, start_index << PAGE_SHIFT, + (last_index << PAGE_SHIFT) + PAGE_SIZE - 1, + &cached_state); return ret; } From patchwork Tue Nov 15 18:00:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13044056 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 39B8AC41535 for ; Tue, 15 Nov 2022 18:02:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238496AbiKOSCA (ORCPT ); Tue, 15 Nov 2022 13:02:00 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50532 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229824AbiKOSBM (ORCPT ); Tue, 15 Nov 2022 13:01:12 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 28A8A1151 for ; Tue, 15 Nov 2022 10:01:05 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id D87D51F8E0; Tue, 15 Nov 2022 18:01:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1668535263; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=az/70XOTVDc5ZyO9DliOMVSP+U3oAe/sj3jWn6jkCUE=; b=jSRFH8WThvi2MXhVtCfS9fFd+TKYqvrSHKii2f1NIsMeONIxm+Wc4d1W3ciIqrQ725y2nh wfaBN10WeeM3wZq2x2Qr5us9g3n0KZe4CuN65dDUnKdcsAQhSLvaP4672vW3P5i2JMogG6 nCK+E9h5AOL8VA26Tye+hnLH+5/Liqk= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1668535263; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=az/70XOTVDc5ZyO9DliOMVSP+U3oAe/sj3jWn6jkCUE=; b=msMgnYlXjIy1te5hsZOZRO6yFi4AVWWzCQ8T+syrbOB2Q+n0RYg9Su8GsE5glLCpru8ykm oXVslnNla17kdNBQ== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 8C5CF13A91; Tue, 15 Nov 2022 18:01:03 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id oQJXGt/Tc2O2ZAAAMHmgww (envelope-from ); Tue, 15 Nov 2022 18:01:03 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Goldwyn Rodrigues Subject: [PATCH 12/16] btrfs: Perform memory faults under locked extent Date: Tue, 15 Nov 2022 12:00:30 -0600 Message-Id: <68054cb6c0be33ef7c55ef8d4b5f4dda0a0d9cbf.1668530684.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org As a part of locking extents before pages, lock entire memfault region while servicing faults. Remove extent locking from page_mkwrite(), since it is part of the fault. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/file.c | 18 +++++++++++++++++- fs/btrfs/inode.c | 6 ------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 559214ded4eb..876e0d81b191 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1980,8 +1980,24 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) goto out; } +static vm_fault_t btrfs_fault(struct vm_fault *vmf) +{ + struct extent_state *cached_state = NULL; + struct inode *inode = file_inode(vmf->vma->vm_file); + struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; + u64 page_start = vmf->pgoff; + u64 page_end = page_start + PAGE_SIZE - 1; + vm_fault_t ret; + + lock_extent(io_tree, page_start, page_end, &cached_state); + ret = filemap_fault(vmf); + unlock_extent(io_tree, page_start, page_end, &cached_state); + + return ret; +} + static const struct vm_operations_struct btrfs_file_vm_ops = { - .fault = filemap_fault, + .fault = btrfs_fault, .map_pages = filemap_map_pages, .page_mkwrite = btrfs_page_mkwrite, }; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 070fb7071e39..b421260d52e2 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -8530,7 +8530,6 @@ vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf) struct page *page = vmf->page; struct inode *inode = file_inode(vmf->vma->vm_file); struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); - struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; struct btrfs_ordered_extent *ordered; struct extent_state *cached_state = NULL; struct extent_changeset *data_reserved = NULL; @@ -8585,11 +8584,9 @@ vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf) } wait_on_page_writeback(page); - lock_extent(io_tree, page_start, page_end, &cached_state); ret2 = set_page_extent_mapped(page); if (ret2 < 0) { ret = vmf_error(ret2); - unlock_extent(io_tree, page_start, page_end, &cached_state); goto out_unlock; } @@ -8600,7 +8597,6 @@ vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf) ordered = btrfs_lookup_ordered_range(BTRFS_I(inode), page_start, PAGE_SIZE); if (ordered) { - unlock_extent(io_tree, page_start, page_end, &cached_state); unlock_page(page); up_read(&BTRFS_I(inode)->i_mmap_lock); btrfs_start_ordered_extent(ordered, 1); @@ -8633,7 +8629,6 @@ vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf) ret2 = btrfs_set_extent_delalloc(BTRFS_I(inode), page_start, end, 0, &cached_state); if (ret2) { - unlock_extent(io_tree, page_start, page_end, &cached_state); ret = VM_FAULT_SIGBUS; goto out_unlock; } @@ -8653,7 +8648,6 @@ vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf) btrfs_set_inode_last_sub_trans(BTRFS_I(inode)); - unlock_extent(io_tree, page_start, page_end, &cached_state); up_read(&BTRFS_I(inode)->i_mmap_lock); btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE); From patchwork Tue Nov 15 18:00:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13044051 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E025BC43219 for ; Tue, 15 Nov 2022 18:02:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238424AbiKOSBz (ORCPT ); Tue, 15 Nov 2022 13:01:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51824 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231758AbiKOSBM (ORCPT ); Tue, 15 Nov 2022 13:01:12 -0500 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 224861092 for ; Tue, 15 Nov 2022 10:01:07 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id D34AD33688; Tue, 15 Nov 2022 18:01:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1668535265; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Z03a08xyeEMLVwMbsWvdMMDA7ZqAQ5+EsgQ/J6+4MDM=; b=odgGQwKfcWkqOynvBCNE5qh+YvzBDpnal3DZ+CezrghH5t+sp1poJMM4prXs4v1dMv4SBx B6hKsN/7tloQmNLgzbKm6w57u0C/rVfyJ3A9ZG7t/8qkyaaLQAdphga6swC2jih/ovNPhb QGFAg1asCYDWxiBFNJXAeRxQlC74sP0= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1668535265; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Z03a08xyeEMLVwMbsWvdMMDA7ZqAQ5+EsgQ/J6+4MDM=; b=p+WceA6jxlnor3lbz9bEqhN/gK/vUkZyIS3RScnJLPaiR62KcUMIsCdcF/2OxLcigGvSfm 309z+IDpWfAxPgBg== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 8C20E13A91; Tue, 15 Nov 2022 18:01:05 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id INI+GuHTc2O6ZAAAMHmgww (envelope-from ); Tue, 15 Nov 2022 18:01:05 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Goldwyn Rodrigues Subject: [PATCH 13/16] btrfs: writepage fixup lock rearrangement Date: Tue, 15 Nov 2022 12:00:31 -0600 Message-Id: <996e43b8178ba3e5f9db220cc9e5d437c3794f06.1668530684.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Perform extent lock before pages while performing writepage_fixup_worker. Signed-off-by: Goldwyn Rodrigues Reviewed-by: Josef Bacik --- fs/btrfs/inode.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index b421260d52e2..2806ef69122e 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2909,6 +2909,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) u64 page_end; int ret = 0; bool free_delalloc_space = true; + bool flushed = false; fixup = container_of(work, struct btrfs_writepage_fixup, work); page = fixup->page; @@ -2920,9 +2921,16 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) * This is similar to page_mkwrite, we need to reserve the space before * we take the page lock. */ +reserve: ret = btrfs_delalloc_reserve_space(inode, &data_reserved, page_start, PAGE_SIZE); + if (ret == -EDQUOT && !flushed) { + btrfs_qgroup_flush(inode->root); + flushed = true; + goto reserve; + } again: + lock_extent(&inode->io_tree, page_start, page_end, NULL); lock_page(page); /* @@ -2965,19 +2973,18 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) if (ret) goto out_page; - lock_extent(&inode->io_tree, page_start, page_end, &cached_state); - /* already ordered? We're done */ if (PageOrdered(page)) goto out_reserved; ordered = btrfs_lookup_ordered_range(inode, page_start, PAGE_SIZE); if (ordered) { - unlock_extent(&inode->io_tree, page_start, page_end, - &cached_state); unlock_page(page); + unlock_extent(&inode->io_tree, page_start, page_end, + NULL); btrfs_start_ordered_extent(ordered, 1); btrfs_put_ordered_extent(ordered); + goto again; } @@ -3000,7 +3007,6 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) if (free_delalloc_space) btrfs_delalloc_release_space(inode, data_reserved, page_start, PAGE_SIZE, true); - unlock_extent(&inode->io_tree, page_start, page_end, &cached_state); out_page: if (ret) { /* From patchwork Tue Nov 15 18:00:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13044055 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 29E9FC4167B for ; Tue, 15 Nov 2022 18:02:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238480AbiKOSB6 (ORCPT ); Tue, 15 Nov 2022 13:01:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51816 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229678AbiKOSBN (ORCPT ); Tue, 15 Nov 2022 13:01:13 -0500 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 316881161 for ; Tue, 15 Nov 2022 10:01:09 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id E6ABD336CD; Tue, 15 Nov 2022 18:01:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1668535267; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wIvtsO76tyAt0xnmv0CJbL/aHLQCt0Mo0S4+1mDuFFs=; b=sAwFfMRE9+EkR1av/8Q4zR+lS4TwkQdLcYo8qrSLLQaXXvEfGGChl2UCjhmtow3P68Ceb3 ennvYyaMJ2zpRO7sH9YR68n+Zpjhip/A5kGvxRPv8P6/W0O1vpVDazrKbY6nRl3XUY4meM tXaQ6AflWKLqPirb3mKBr6crV75d0Ic= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1668535267; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wIvtsO76tyAt0xnmv0CJbL/aHLQCt0Mo0S4+1mDuFFs=; b=aEUN2wtkR82LnNLqBWh24O3e70ZacZl7Z/+r0DsEoQSEcxZNfCZitXV3yBCiA9tm8HdBH0 WPJytyySn73ULnAg== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 947A513A91; Tue, 15 Nov 2022 18:01:07 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id vmYeHOPTc2PGZAAAMHmgww (envelope-from ); Tue, 15 Nov 2022 18:01:07 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Goldwyn Rodrigues Subject: [PATCH 14/16] btrfs: lock extent before pages for encoded read ioctls Date: Tue, 15 Nov 2022 12:00:32 -0600 Message-Id: <7d0e6ad948ebd8ce5b5858b720a9e2403221d677.1668530684.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Lock extent before pages while performing read ioctls. Signed-off-by: Goldwyn Rodrigues Reviewed-by: Josef Bacik --- fs/btrfs/inode.c | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 2806ef69122e..3c3f38b0048d 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -10237,13 +10237,11 @@ static ssize_t btrfs_encoded_read_inline( u64 lockend, struct extent_state **cached_state, u64 extent_start, size_t count, - struct btrfs_ioctl_encoded_io_args *encoded, - bool *unlocked) + struct btrfs_ioctl_encoded_io_args *encoded) { struct btrfs_inode *inode = BTRFS_I(file_inode(iocb->ki_filp)); struct btrfs_root *root = inode->root; struct btrfs_fs_info *fs_info = root->fs_info; - struct extent_io_tree *io_tree = &inode->io_tree; struct btrfs_path *path; struct extent_buffer *leaf; struct btrfs_file_extent_item *item; @@ -10305,9 +10303,6 @@ static ssize_t btrfs_encoded_read_inline( } read_extent_buffer(leaf, tmp, ptr, count); btrfs_release_path(path); - unlock_extent(io_tree, start, lockend, cached_state); - btrfs_inode_unlock(inode, BTRFS_ILOCK_SHARED); - *unlocked = true; ret = copy_to_iter(tmp, count, iter); if (ret != count) @@ -10482,11 +10477,9 @@ static ssize_t btrfs_encoded_read_regular(struct kiocb *iocb, u64 start, u64 lockend, struct extent_state **cached_state, u64 disk_bytenr, u64 disk_io_size, - size_t count, bool compressed, - bool *unlocked) + size_t count, bool compressed) { struct btrfs_inode *inode = BTRFS_I(file_inode(iocb->ki_filp)); - struct extent_io_tree *io_tree = &inode->io_tree; struct page **pages; unsigned long nr_pages, i; u64 cur; @@ -10508,10 +10501,6 @@ static ssize_t btrfs_encoded_read_regular(struct kiocb *iocb, if (ret) goto out; - unlock_extent(io_tree, start, lockend, cached_state); - btrfs_inode_unlock(inode, BTRFS_ILOCK_SHARED); - *unlocked = true; - if (compressed) { i = 0; page_offset = 0; @@ -10554,7 +10543,6 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter, u64 start, lockend, disk_bytenr, disk_io_size; struct extent_state *cached_state = NULL; struct extent_map *em; - bool unlocked = false; file_accessed(iocb->ki_filp); @@ -10605,7 +10593,7 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter, em = NULL; ret = btrfs_encoded_read_inline(iocb, iter, start, lockend, &cached_state, extent_start, - count, encoded, &unlocked); + count, encoded); goto out; } @@ -10658,9 +10646,6 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter, em = NULL; if (disk_bytenr == EXTENT_MAP_HOLE) { - unlock_extent(io_tree, start, lockend, &cached_state); - btrfs_inode_unlock(inode, BTRFS_ILOCK_SHARED); - unlocked = true; ret = iov_iter_zero(count, iter); if (ret != count) ret = -EFAULT; @@ -10668,8 +10653,7 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter, ret = btrfs_encoded_read_regular(iocb, iter, start, lockend, &cached_state, disk_bytenr, disk_io_size, count, - encoded->compression, - &unlocked); + encoded->compression); } out: @@ -10678,11 +10662,9 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter, out_em: free_extent_map(em); out_unlock_extent: - if (!unlocked) - unlock_extent(io_tree, start, lockend, &cached_state); + unlock_extent(io_tree, start, lockend, &cached_state); out_unlock_inode: - if (!unlocked) - btrfs_inode_unlock(inode, BTRFS_ILOCK_SHARED); + btrfs_inode_unlock(inode, BTRFS_ILOCK_SHARED); return ret; } From patchwork Tue Nov 15 18:00:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13044054 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F2570C4167D for ; Tue, 15 Nov 2022 18:02:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238455AbiKOSB4 (ORCPT ); Tue, 15 Nov 2022 13:01:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50510 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230480AbiKOSBN (ORCPT ); Tue, 15 Nov 2022 13:01:13 -0500 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C318218C for ; Tue, 15 Nov 2022 10:01:11 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 0D66D33688; Tue, 15 Nov 2022 18:01:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1668535270; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3KeGJ7XtW0nREon3ApSWnE6cR8oVkL/5sql3WTZUJQg=; b=gBk0/KcaRpb9/DZzqcJ4mMatr+G0t3ZWwNTlMtRxyxFLEN6iZg96wIQnu7GN3pIv8q0c9Q Oo9LLCeKqNQevD+ZZAnYx/8XUoPTfkxDx8+a3TvqOYoNNgkMbrPe2gg8T0XOVIy8JNTPjU jxen2pdXy03e5Sw53ecrAXafBUfsL2c= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1668535270; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3KeGJ7XtW0nREon3ApSWnE6cR8oVkL/5sql3WTZUJQg=; b=VrXdUn8RL+1/N42jgMvt2D/piUMG05Qn16XHmtW1Wjv35vYHxqTkQJLyZNN1btvYXFVdxm B3eQRvw8EH9FYUDg== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id B8B8F13A91; Tue, 15 Nov 2022 18:01:09 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id fPwyJeXTc2PNZAAAMHmgww (envelope-from ); Tue, 15 Nov 2022 18:01:09 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Goldwyn Rodrigues Subject: [PATCH 15/16] btrfs: lock extent before pages in encoded write Date: Tue, 15 Nov 2022 12:00:33 -0600 Message-Id: X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Lock the extent range while performing direct encoded writes, as opposed to individual pages. Signed-off-by: Goldwyn Rodrigues Reviewed-by: Josef Bacik --- fs/btrfs/inode.c | 52 +++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 3c3f38b0048d..e640eb8eb4ec 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -10768,37 +10768,18 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from, pages = kvcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL_ACCOUNT); if (!pages) return -ENOMEM; - for (i = 0; i < nr_pages; i++) { - size_t bytes = min_t(size_t, PAGE_SIZE, iov_iter_count(from)); - char *kaddr; - - pages[i] = alloc_page(GFP_KERNEL_ACCOUNT); - if (!pages[i]) { - ret = -ENOMEM; - goto out_pages; - } - kaddr = kmap_local_page(pages[i]); - if (copy_from_iter(kaddr, bytes, from) != bytes) { - kunmap_local(kaddr); - ret = -EFAULT; - goto out_pages; - } - if (bytes < PAGE_SIZE) - memset(kaddr + bytes, 0, PAGE_SIZE - bytes); - kunmap_local(kaddr); - } for (;;) { struct btrfs_ordered_extent *ordered; ret = btrfs_wait_ordered_range(&inode->vfs_inode, start, num_bytes); if (ret) - goto out_pages; + goto out; ret = invalidate_inode_pages2_range(inode->vfs_inode.i_mapping, start >> PAGE_SHIFT, end >> PAGE_SHIFT); if (ret) - goto out_pages; + goto out; lock_extent(io_tree, start, end, &cached_state); ordered = btrfs_lookup_ordered_range(inode, start, num_bytes); if (!ordered && @@ -10810,6 +10791,26 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from, cond_resched(); } + for (i = 0; i < nr_pages; i++) { + size_t bytes = min_t(size_t, PAGE_SIZE, iov_iter_count(from)); + char *kaddr; + + pages[i] = alloc_page(GFP_KERNEL_ACCOUNT); + if (!pages[i]) { + ret = -ENOMEM; + goto out_pages; + } + kaddr = kmap_local_page(pages[i]); + if (copy_from_iter(kaddr, bytes, from) != bytes) { + kunmap_local(kaddr); + ret = -EFAULT; + goto out_pages; + } + if (bytes < PAGE_SIZE) + memset(kaddr + bytes, 0, PAGE_SIZE - bytes); + kunmap_local(kaddr); + } + /* * We don't use the higher-level delalloc space functions because our * num_bytes and disk_num_bytes are different. @@ -10867,8 +10868,6 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from, if (start + encoded->len > inode->vfs_inode.i_size) i_size_write(&inode->vfs_inode, start + encoded->len); - unlock_extent(io_tree, start, end, &cached_state); - btrfs_delalloc_release_extents(inode, num_bytes); if (btrfs_submit_compressed_write(inode, start, num_bytes, ins.objectid, @@ -10878,6 +10877,9 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from, ret = -EIO; goto out_pages; } + + unlock_extent(io_tree, start, end, &cached_state); + ret = orig_count; goto out; @@ -10897,14 +10899,14 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from, */ if (!extent_reserved) btrfs_free_reserved_data_space_noquota(fs_info, disk_num_bytes); -out_unlock: - unlock_extent(io_tree, start, end, &cached_state); out_pages: for (i = 0; i < nr_pages; i++) { if (pages[i]) __free_page(pages[i]); } kvfree(pages); +out_unlock: + unlock_extent(io_tree, start, end, &cached_state); out: if (ret >= 0) iocb->ki_pos += encoded->len; From patchwork Tue Nov 15 18:00:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13044057 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8B8C6C46467 for ; Tue, 15 Nov 2022 18:02:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231698AbiKOSCE (ORCPT ); Tue, 15 Nov 2022 13:02:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50848 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231475AbiKOSBO (ORCPT ); Tue, 15 Nov 2022 13:01:14 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5C7AC62C7 for ; Tue, 15 Nov 2022 10:01:13 -0800 (PST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 1CE291F8E0; Tue, 15 Nov 2022 18:01:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1668535272; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Wqci/3B1Q9K7U2AZI/lsbKOytc6jr8mWCM1rkUcjzog=; b=pn1Uugat2MHvpf88oPhgR1/gkLBRO+QvRnz3K68jlLlbAIxE4NnlDNjs1N/9F7C836X0hV 877G01mVVlgouj0Jvb1QCQjf1Df/SOWw6U8pbl04ilzIcmdQeisWjJj0mt47luztmxcDeA fGmeeHmnVcXiuPUJ7yQ6CFpddwh8hqs= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1668535272; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Wqci/3B1Q9K7U2AZI/lsbKOytc6jr8mWCM1rkUcjzog=; b=DcYhfbhBDo9Vghc+FjBAoZJ0tAYYezxdIGi/CXSVoxACSXQuIPc7iSdu/wRs7QLamJHxca GTfD/L2XoQPsUBCA== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id C4CFE13A91; Tue, 15 Nov 2022 18:01:11 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id p8kTKOfTc2PVZAAAMHmgww (envelope-from ); Tue, 15 Nov 2022 18:01:11 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Goldwyn Rodrigues Subject: [PATCH 16/16] btrfs: btree_writepages lock extents before pages Date: Tue, 15 Nov 2022 12:00:34 -0600 Message-Id: <994c7a74720e3c8589263095704dc7f87cfdb3e7.1668530684.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org Lock extents before pages while performing btree_writepages(). Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/disk-io.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 8ac9612f8f27..b7e7c4c9d404 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -858,8 +858,25 @@ static int btree_migrate_folio(struct address_space *mapping, static int btree_writepages(struct address_space *mapping, struct writeback_control *wbc) { + u64 start, end; + struct btrfs_inode *inode = BTRFS_I(mapping->host); + struct extent_state *cached = NULL; struct btrfs_fs_info *fs_info; int ret; + u64 isize = round_up(i_size_read(&inode->vfs_inode), PAGE_SIZE) - 1; + + if (wbc->range_cyclic) { + start = mapping->writeback_index << PAGE_SHIFT; + end = isize; + } else { + start = round_down(wbc->range_start, PAGE_SIZE); + end = round_up(wbc->range_end, PAGE_SIZE) - 1; + end = min(isize, end); + } + + if (start >= end) + return 0; + if (wbc->sync_mode == WB_SYNC_NONE) { @@ -874,7 +891,12 @@ static int btree_writepages(struct address_space *mapping, if (ret < 0) return 0; } - return btree_write_cache_pages(mapping, wbc); + + lock_extent(&inode->io_tree, start, end, &cached); + ret = btree_write_cache_pages(mapping, wbc); + unlock_extent(&inode->io_tree, start, end, &cached); + + return ret; } static bool btree_release_folio(struct folio *folio, gfp_t gfp_flags)