From patchwork Thu Mar 2 22:24:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157959 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 7D056C678D4 for ; Thu, 2 Mar 2023 22:25:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229981AbjCBWZG (ORCPT ); Thu, 2 Mar 2023 17:25:06 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41788 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229540AbjCBWZF (ORCPT ); Thu, 2 Mar 2023 17:25:05 -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 7B92415143 for ; Thu, 2 Mar 2023 14:25:04 -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 36C3C2237D; Thu, 2 Mar 2023 22:25:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795903; 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=ETP35mJFvVJqwXhOnp/+xm6v2JfOoXdo2Smb1xvPSpI=; b=fWfHP2Dr7WTR/SHUQxdtNebztHfYSW+UZF4U7GvW7ID5RWbGzjhsrVA7WKlHkhOhSwRvsu oJYXl1jPnj7Nu51p/Gx17pD5XgSiMLKRleqf/whtYucgEjii/+uznvnlwThIQ0ebX9Pkw5 pG5H83EAMz8y/6GbQSDf3Nruo4VZT7Y= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795903; 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=ETP35mJFvVJqwXhOnp/+xm6v2JfOoXdo2Smb1xvPSpI=; b=zJ13RZJhr9DQ/jUxhcEXcSQIfCYLC/LoZWrF1xgZEIhXTwAr7gDPTslDNQy3HcFSpjoDMd G1rp6BYW3S1EgEDg== 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 DFBAD13349; Thu, 2 Mar 2023 22:25:02 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id TnAiLz4iAWSFSQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:02 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 01/21] fs: readahead_begin() to call before locking folio Date: Thu, 2 Mar 2023 16:24:46 -0600 Message-Id: <4b8c7d11d7440523dba12205a88b7d43f61a07b1.1677793433.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues The btrfs filesystem needs to lock the extents before locking folios to be read from disk. So, introduce a function in address_space_operaitons, called btrfs_readahead_begin() which is called before the folio are allocateed and locked. --- include/linux/fs.h | 1 + mm/readahead.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/include/linux/fs.h b/include/linux/fs.h index c1769a2c5d70..6b650db57ca3 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -363,6 +363,7 @@ struct address_space_operations { /* Mark a folio dirty. Return true if this dirtied it */ bool (*dirty_folio)(struct address_space *, struct folio *); + void (*readahead_begin)(struct readahead_control *); void (*readahead)(struct readahead_control *); int (*write_begin)(struct file *, struct address_space *mapping, diff --git a/mm/readahead.c b/mm/readahead.c index b10f0cf81d80..6924d5fed350 100644 --- a/mm/readahead.c +++ b/mm/readahead.c @@ -520,6 +520,9 @@ void page_cache_ra_order(struct readahead_control *ractl, new_order--; } + if (mapping->a_ops->readahead_begin) + mapping->a_ops->readahead_begin(ractl); + filemap_invalidate_lock_shared(mapping); while (index <= limit) { unsigned int order = new_order; From patchwork Thu Mar 2 22:24:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157960 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 077CEC6FA8E for ; Thu, 2 Mar 2023 22:25:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229986AbjCBWZK (ORCPT ); Thu, 2 Mar 2023 17:25:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41898 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229557AbjCBWZJ (ORCPT ); Thu, 2 Mar 2023 17:25:09 -0500 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1548323655 for ; Thu, 2 Mar 2023 14:25: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 B730C2237D; Thu, 2 Mar 2023 22:25:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795905; 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=ak0oXyxbl0BtbiBynO/E3Y3H5n/OpoHvrW9GTQENiMw=; b=eTuXq5Ns5vOl7NlMF4DhshS8BUityCSTV2khULXul3U3lYhWcnOLj45xDjNqCqmwPAdHTb YWqZ0SWC9HBBL6ogEgxJN5IRiACNMFBLg1OHEU+aD2sV7GICzTln8Msfi+ce982WvI294V JL+UYHY2QC2JaIA+ZaK7eLm1wSAKbY4= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795905; 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=ak0oXyxbl0BtbiBynO/E3Y3H5n/OpoHvrW9GTQENiMw=; b=XIe7YlyRnQGv5O4+rIfEPp1+ihQb6OJRuKqYCOZ2Usyt8V6Ny88soN3jfAceVoZsSXxu38 AVFBIyyk5O1NWlCA== 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 6EB4313349; Thu, 2 Mar 2023 22:25:05 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id ZAnbDUEiAWSLSQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:05 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 02/21] btrfs: add WARN_ON() on incorrect lock range Date: Thu, 2 Mar 2023 16:24:47 -0600 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues Add a WARN_ON(start > end) to make sure that the locking happens on the correct range and no incorrect nodes (with state->start > state->end) are added to the tree. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/extent-io-tree.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/btrfs/extent-io-tree.c b/fs/btrfs/extent-io-tree.c index 29a225836e28..482721dd1eba 100644 --- a/fs/btrfs/extent-io-tree.c +++ b/fs/btrfs/extent-io-tree.c @@ -1710,6 +1710,7 @@ int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end, int err; u64 failed_start; + WARN_ON(start > end); err = __set_extent_bit(tree, start, end, EXTENT_LOCKED, &failed_start, NULL, cached, NULL, GFP_NOFS); if (err == -EEXIST) { @@ -1732,6 +1733,7 @@ int lock_extent(struct extent_io_tree *tree, u64 start, u64 end, int err; u64 failed_start; + WARN_ON(start > end); err = __set_extent_bit(tree, start, end, EXTENT_LOCKED, &failed_start, &failed_state, cached_state, NULL, GFP_NOFS); while (err == -EEXIST) { From patchwork Thu Mar 2 22:24:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157961 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 02588C6FA8E for ; Thu, 2 Mar 2023 22:25:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229540AbjCBWZO (ORCPT ); Thu, 2 Mar 2023 17:25:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41916 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229557AbjCBWZK (ORCPT ); Thu, 2 Mar 2023 17:25:10 -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 E943CEB53 for ; Thu, 2 Mar 2023 14:25: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-out2.suse.de (Postfix) with ESMTPS id 6333320069; Thu, 2 Mar 2023 22:25:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795908; 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=O9KCkO8DkEDWq1KpZOwRNO4XEUlld9HpJInd1mWjYeQ=; b=HcFS2R0H9CQUvwY+b1HrGANDIgBFJfSiSovWbeGj8TCt9BnXkRSY6AZQb6yDnI2iYX32wf pfWX2pTSa9NxF8mW+lfTP8DgaB4VqsAE7H71dz0DFcvwO2Ki5TdJrAGZuNXb0Dod9WJyuy MwqGsr92OYoJY1fmusHrjZ1ZC2fCCfI= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795908; 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=O9KCkO8DkEDWq1KpZOwRNO4XEUlld9HpJInd1mWjYeQ=; b=i/+qFQmqqs9Xp5cFQDRm9mcB5Q4RT7KrR8/QyD31nF2sv5MDjJf39aeztupNvN18OO9UkP qoOakrOsrOJD0lDQ== 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 1CBB413349; Thu, 2 Mar 2023 22:25:07 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id iogcNkMiAWSPSQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:07 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 03/21] btrfs: Add start < end check in btrfs_debug_check_extent_io_range() Date: Thu, 2 Mar 2023 16:24:48 -0600 Message-Id: <37fd374e88730196100116cc237f637cd6a8962a.1677793433.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues For issues such as zero size writes, we can get start > end. Check them in btrfs_debug_check_extent_io_range() so this may be caught early. Signed-off-by: Goldwyn Rodrigues Reviewed-by: Boris Burkov --- fs/btrfs/extent-io-tree.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/extent-io-tree.c b/fs/btrfs/extent-io-tree.c index 482721dd1eba..d467c614c84e 100644 --- a/fs/btrfs/extent-io-tree.c +++ b/fs/btrfs/extent-io-tree.c @@ -65,7 +65,8 @@ static inline void __btrfs_debug_check_extent_io_range(const char *caller, return; isize = i_size_read(&inode->vfs_inode); - if (end >= PAGE_SIZE && (end % 2) == 0 && end != isize - 1) { + if ((start > end) || + (end >= PAGE_SIZE && (end % 2) == 0 && end != isize - 1)) { btrfs_debug_rl(inode->root->fs_info, "%s: ino %llu isize %llu odd range [%llu,%llu]", caller, btrfs_ino(inode), isize, start, end); From patchwork Thu Mar 2 22:24:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157962 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 E5334C678D4 for ; Thu, 2 Mar 2023 22:25:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229983AbjCBWZP (ORCPT ); Thu, 2 Mar 2023 17:25:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41916 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229985AbjCBWZN (ORCPT ); Thu, 2 Mar 2023 17:25:13 -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 C0F2D1E5E9 for ; Thu, 2 Mar 2023 14:25:12 -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 65A6420069; Thu, 2 Mar 2023 22:25:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795911; 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=BayLPTvrNoPyBevDitXVYno3Aihm310TthDjjBwYREw=; b=tet7P5DkPABvJSLU8xL+yFbF/r8F20JFEaqc2Wm6kN7EyRVLrIHq1gXVSsN5oU8aUlQCKc GbyUB7iG5FF8s4SkX18Amig8Wt9pIUlZ4owPQBNGF2TDIXWwmWXEOOitKkQk6pO9NobiKS 1v5FxIMaciIL1fKOVpvZgPLrDfGok00= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795911; 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=BayLPTvrNoPyBevDitXVYno3Aihm310TthDjjBwYREw=; b=p0JKifAKpE2B+xiim42Nzz26Nr5QQSdBxMhPLqpGMRq2wmEAvARNCyjtsKNwe9Vrg3ptSh J0XYjfYjhXl7mDAQ== 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 1A1A913349; Thu, 2 Mar 2023 22:25:10 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id xGR4OkYiAWSbSQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:10 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 04/21] btrfs: make btrfs_qgroup_flush() non-static Date: Thu, 2 Mar 2023 16:24:49 -0600 Message-Id: <08b4b39eca92493c341831a6cb06836aac7a4967.1677793433.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues btrfs_qgroup_flush() is used to flush data when a qgroup reservation is unsuccessfull. This causes a writeback which takes extent locks. If we have to make reservations under locks, we call reservation function with nowait true, so it does not call btrfs_qgroup_flush(). btrfs_qgroup_flush() call becomes the responsibility of the function performing reservations under locks. They must call the reservation function with nowait=true. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/qgroup.c | 6 +++--- fs/btrfs/qgroup.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 52a7d2fa2284..235bc78a8418 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -3709,7 +3709,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; @@ -3821,7 +3821,7 @@ int btrfs_qgroup_reserve_data(struct btrfs_inode *inode, if (ret <= 0 && ret != -EDQUOT) return ret; - ret = try_flush_qgroup(inode->root); + ret = btrfs_qgroup_flush(inode->root); if (ret < 0) return ret; return qgroup_reserve_data(inode, reserved_ret, start, len); @@ -4032,7 +4032,7 @@ int __btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, if ((ret <= 0 && ret != -EDQUOT) || noflush) return ret; - ret = try_flush_qgroup(root); + ret = btrfs_qgroup_flush(root); if (ret < 0) return ret; return btrfs_qgroup_reserve_meta(root, num_bytes, type, enforce); diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h index 7bffa10589d6..232bc5ad3dca 100644 --- a/fs/btrfs/qgroup.h +++ b/fs/btrfs/qgroup.h @@ -439,5 +439,6 @@ 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 From patchwork Thu Mar 2 22:24:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157963 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 CC676C6FA8E for ; Thu, 2 Mar 2023 22:25:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229985AbjCBWZS (ORCPT ); Thu, 2 Mar 2023 17:25:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42078 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229557AbjCBWZQ (ORCPT ); Thu, 2 Mar 2023 17:25:16 -0500 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 212DF1ABD1 for ; Thu, 2 Mar 2023 14:25:15 -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 D5CC12237D; Thu, 2 Mar 2023 22:25:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795913; 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=U4WThxZcQa544UM/K2TAl358TBd08zZ3lJ0tvpFv6Ss=; b=EC4D/DJLQAvNtq4By3pUK1oaF/XmFBEb8kV1jVK0nYQ4Vmz/20i9sEQi+Ct7HKTTNUpsSo envh3T1aWBAASkGHEYbdNppor2Nq/rL68JI/hue9faBMMRnHJ5SwIUBoBILLvrTDIn+5zV /4ZKYP2jtbqS62FndeEFL6j7e6oqE9k= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795913; 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=U4WThxZcQa544UM/K2TAl358TBd08zZ3lJ0tvpFv6Ss=; b=j1OpGzgCZKEYGnaJt+sWyJXm0XKd3E8IIpw6+FLAdSOPWVEnwzAuD+Now+8kHlyrX0hjfI QMhlbuXdKwAojdBA== 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 84DC813349; Thu, 2 Mar 2023 22:25:13 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id VX4DFEkiAWShSQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:13 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Josef Bacik Subject: [PATCH 05/21] btrfs: Lock extents before pages for buffered write() Date: Thu, 2 Mar 2023 16:24:50 -0600 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues 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 5cc5a1faaef5..a2f8f566cfbf 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -973,8 +973,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) @@ -982,7 +982,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); @@ -993,15 +992,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); } @@ -1013,10 +1005,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); btrfs_put_ordered_extent(ordered); return -EAGAIN; @@ -1029,13 +1017,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; } @@ -1299,13 +1280,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 @@ -1313,25 +1303,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); @@ -1380,33 +1354,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 Thu Mar 2 22:24:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157964 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 C3ED5C678D4 for ; Thu, 2 Mar 2023 22:25:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229988AbjCBWZT (ORCPT ); Thu, 2 Mar 2023 17:25:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42160 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229872AbjCBWZS (ORCPT ); Thu, 2 Mar 2023 17:25:18 -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 E22371ABD4 for ; Thu, 2 Mar 2023 14:25:17 -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 9BE912237E; Thu, 2 Mar 2023 22:25:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795916; 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=1mpVSJgcUEebwBqt616MqGmTtMD4rBecon2H5hNLJRQ=; b=oy0A65jX09PC60hB1oMMYxhjTIXsliCAovgWcC7eeC/AFht/0vhTrin8qzs7SVJN5ZEi5k efwTB+VfdnyYGe1s0ApjUwfdRfneDWxXY+ikk1brSjOy4XnUbAeDSGxM5KpzDh4eXPVpU7 2PqSx+i8+nLdJMY6a9rGLH9iBjztq7A= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795916; 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=1mpVSJgcUEebwBqt616MqGmTtMD4rBecon2H5hNLJRQ=; b=3mA6esVbs5auHf/nxSH1w0eQZl5rI+Gom4VKRG3IcW62/SO1YozpZrTdUSbKxK/KJwPP9K LQzxBh2BNTiyg0Cw== 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 4AC0913349; Thu, 2 Mar 2023 22:25:16 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id NDEhBkwiAWSmSQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:16 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Johannes Thumshirn , Josef Bacik Subject: [PATCH 06/21] btrfs: wait ordered range before locking during truncate Date: Thu, 2 Mar 2023 16:24:51 -0600 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues 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 2c96c39975e0..02307789b0a8 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -109,7 +109,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, @@ -5084,7 +5084,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); @@ -5105,7 +5105,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; @@ -8241,7 +8242,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, @@ -8254,17 +8255,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 Thu Mar 2 22:24:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157965 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 956CCC7EE30 for ; Thu, 2 Mar 2023 22:25:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229992AbjCBWZW (ORCPT ); Thu, 2 Mar 2023 17:25:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42226 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229872AbjCBWZW (ORCPT ); Thu, 2 Mar 2023 17:25:22 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C48DC25BBD for ; Thu, 2 Mar 2023 14:25:20 -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 6E23620062; Thu, 2 Mar 2023 22:25:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795919; 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=SdOtM8EQi4GCWL8+5M7aUI1+HP2fF2JENBb46fg+hEs=; b=miRCU0iwlNF2G2Y71ncu01zykSbH9Wd5oUrBfIaY0ErmfJia+BYss99//ZE2X1wRAopsBR +hoN/yL6oMjAoOJTjp72seL1h3LApy1EcFSS5KCZvdewhKfMjTRRJIShFrvgL8JxJwJh4K EGdDN3/ubZcWQm1YWmijHm3tp2fi2/Y= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795919; 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=SdOtM8EQi4GCWL8+5M7aUI1+HP2fF2JENBb46fg+hEs=; b=DvueH4ZGUVW+HOJVvYKC/IAdZZDPFQs/7LhN8T9vNaNbM74fKQ+nOM4zKUCN//410ivEL4 xDn5iDdyYvzxSmCA== 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 1099713349; Thu, 2 Mar 2023 22:25:18 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 3vZdM04iAWSqSQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:18 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 07/21] btrfs: lock extents while truncating Date: Thu, 2 Mar 2023 16:24:52 -0600 Message-Id: <831366e1026ea504f319f600cef7e0e835aacdb2.1677793433.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues 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. Call btrfs_delalloc_reserve_metadata() with nowait as true to avoid qgroup flush with extent locked. Flush, if required after unlocking in btrfs_setsize(). There are cases when the user will truncate at the file size (which could also be the block size). In such a case, end is start - 1, and it results in incorrect extent bit tree. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/file.c | 4 ++-- fs/btrfs/inode.c | 54 +++++++++++++++++++++++++++--------------------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index a2f8f566cfbf..2e835096e3ce 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -2165,10 +2165,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 02307789b0a8..2816629fafe4 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4757,7 +4757,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; @@ -4789,7 +4788,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, true); if (ret < 0) { if (!only_release_metadata) btrfs_free_reserved_data_space(inode, data_reserved, @@ -4824,11 +4823,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); @@ -4842,10 +4838,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) @@ -4860,7 +4854,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, @@ -4952,6 +4945,13 @@ int btrfs_cont_expand(struct btrfs_inode *inode, loff_t oldsize, loff_t size) u64 hole_size; int err = 0; + /* + * Check so that no erroneous nodes are created in locking trees + * when hole_start and block_end are equal. + */ + if (hole_start != block_end) + 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 @@ -4959,13 +4959,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, @@ -5027,7 +5025,9 @@ int btrfs_cont_expand(struct btrfs_inode *inode, loff_t oldsize, loff_t size) break; } free_extent_map(em); - unlock_extent(io_tree, hole_start, block_end - 1, &cached_state); +out: + if (hole_start != block_end) + unlock_extent(io_tree, hole_start, block_end - 1, &cached_state); return err; } @@ -5039,6 +5039,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 @@ -5083,6 +5084,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, @@ -5100,12 +5104,22 @@ 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: + if (start < end) + lock_extent(&BTRFS_I(inode)->io_tree, start, end, cached); truncate_setsize(inode, newsize); inode_dio_wait(inode); ret = btrfs_truncate(BTRFS_I(inode)); + if (start < end) + 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; @@ -7956,9 +7970,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; @@ -8059,7 +8070,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); @@ -8309,12 +8320,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 @@ -8329,8 +8337,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 Thu Mar 2 22:24:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157966 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 DD43CC6FA8E for ; Thu, 2 Mar 2023 22:25:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229994AbjCBWZZ (ORCPT ); Thu, 2 Mar 2023 17:25:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42332 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229990AbjCBWZY (ORCPT ); Thu, 2 Mar 2023 17:25:24 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1E83D2332B for ; Thu, 2 Mar 2023 14:25:23 -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 D46F02006A; Thu, 2 Mar 2023 22:25:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795921; 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=Mb1qSEFXDLy0O7gDF5NyHC5viBnd/0pzEjbGX65dYxo=; b=yACfjvX5oqNBtlR0U1w2vT9lDlhMIPgHVeXuDNZY+5nSDL7emjmSR/+rnffohQknqUfkkf pwMY5c14dIHmlzIWcCkNvWHq3nG7ySUL+yVL9HQDC8CgJ+do4olCOYCW7HrHW2xk0CZrfm nFyP5D5rpSZ7Z4HTCjPJKiN85ka4JiE= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795921; 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=Mb1qSEFXDLy0O7gDF5NyHC5viBnd/0pzEjbGX65dYxo=; b=04i1mptw/CL2BfHYqJeVq83eWumJMzKZCUs1GgVVjo/IYi0GEPGjUAuV6l5DZ55A1RJhaz MGup3MjGDgC8WXBw== 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 6D9B013349; Thu, 2 Mar 2023 22:25:21 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id zsF1DFEiAWSsSQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:21 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Josef Bacik Subject: [PATCH 08/21] btrfs: no need to lock extent while performing invalidate_folio() Date: Thu, 2 Mar 2023 16:24:53 -0600 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues 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 Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/disk-io.c | 4 +--- fs/btrfs/extent_io.c | 32 -------------------------------- 2 files changed, 1 insertion(+), 35 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 48368d4bc331..c2b954134851 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -755,9 +755,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 c25fa74d7615..ed054c2f38d8 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -2778,38 +2778,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 From patchwork Thu Mar 2 22:24:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157967 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 59F7CC7EE30 for ; Thu, 2 Mar 2023 22:25:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229993AbjCBWZ2 (ORCPT ); Thu, 2 Mar 2023 17:25:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42368 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229995AbjCBWZ0 (ORCPT ); Thu, 2 Mar 2023 17:25:26 -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 8869A1ACFC for ; Thu, 2 Mar 2023 14:25:25 -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 3D91820062; Thu, 2 Mar 2023 22:25:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795924; 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=p0RGUSL/ph+qwRg7N13i6ERvtlAGmelBlgTHClEN7T4=; b=Ri5KMfAnUE+3yCYSnt9jKxb3TcgCFhxoqa6SnYckzEKpB+taocSTDtlevX41Occ5p7RBzk w7i/qGZA8i+BHZSqeZEB5nsn3nkZQiEjyxwEQL8SQMqJEZPeY+9+HdlQDaGHS8U3hL3ltn Q/GGTZH/2OCjIa6H5RTfMyj+TdeCxzs= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795924; 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=p0RGUSL/ph+qwRg7N13i6ERvtlAGmelBlgTHClEN7T4=; b=F2baNaoLHFRjcOVBYuot+afEOY6FQGRA3TVOSfHJv/lktcibaY4SKw/DHJanC4mhx6PMoM ngbE02ddYJq1nACQ== 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 DD4DC13349; Thu, 2 Mar 2023 22:25:23 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id SeloLlMiAWS4SQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:23 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 09/21] btrfs: lock extents before folio for read()s Date: Thu, 2 Mar 2023 16:24:54 -0600 Message-Id: <1cc00df10c78699412b5eed753fa61aa3181d0b6.1677793433.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues Lock the extents before folio by locking them using readahead_begin(). Unlock the extents after the readahead is complete. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/compression.c | 5 ----- fs/btrfs/extent_io.c | 25 ------------------------- fs/btrfs/inode.c | 17 +++++++++++++++++ 3 files changed, 17 insertions(+), 30 deletions(-) diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index f42f31f22d13..b0dd01e31078 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -381,11 +381,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; @@ -452,7 +450,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); @@ -466,7 +463,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; @@ -486,7 +482,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 ed054c2f38d8..e44329a84caf 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -644,9 +644,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; @@ -668,13 +665,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; @@ -1209,11 +1199,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; @@ -1238,14 +1226,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; @@ -1315,8 +1301,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; @@ -1324,7 +1308,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; @@ -1340,7 +1323,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; } @@ -1354,13 +1336,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); /* @@ -1377,11 +1355,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/inode.c b/fs/btrfs/inode.c index 2816629fafe4..53bd9a64e803 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7848,9 +7848,25 @@ static int btrfs_writepages(struct address_space *mapping, return extent_writepages(mapping, wbc); } +static void btrfs_readahead_begin(struct readahead_control *rac) +{ + struct inode *inode = rac->mapping->host; + int sectorsize = btrfs_sb(inode->i_sb)->sectorsize; + u64 start = round_down(readahead_pos(rac), sectorsize); + u64 end = round_up(start + readahead_length(rac), sectorsize) - 1; + + lock_extent(&BTRFS_I(inode)->io_tree, start, end, NULL); +} + static void btrfs_readahead(struct readahead_control *rac) { + struct inode *inode = rac->mapping->host; + int sectorsize = btrfs_sb(inode->i_sb)->sectorsize; + u64 start = round_down(readahead_pos(rac), sectorsize); + u64 end = round_up(start + readahead_length(rac), sectorsize) - 1; + extent_readahead(rac); + unlock_extent(&BTRFS_I(inode)->io_tree, start, end, NULL); } /* @@ -10930,6 +10946,7 @@ static const struct file_operations btrfs_dir_file_operations = { static const struct address_space_operations btrfs_aops = { .read_folio = btrfs_read_folio, .writepages = btrfs_writepages, + .readahead_begin = btrfs_readahead_begin, .readahead = btrfs_readahead, .direct_IO = noop_direct_IO, .invalidate_folio = btrfs_invalidate_folio, From patchwork Thu Mar 2 22:24:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157968 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 63F14C7EE33 for ; Thu, 2 Mar 2023 22:25:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229995AbjCBWZa (ORCPT ); Thu, 2 Mar 2023 17:25:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42418 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229911AbjCBWZ3 (ORCPT ); Thu, 2 Mar 2023 17:25:29 -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 C5F891ACFC for ; Thu, 2 Mar 2023 14:25:27 -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 8109D2006A; Thu, 2 Mar 2023 22:25:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795926; 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=9XdAe69CcLEJrm69PQqUCtA/hKhTPtcRgz0t4zCDbog=; b=MQuDKQ92FhE3w/AeQTY4q47o14dahWyCF0n2ajsmOr/8LQjiQ4cY0ZiftS/FdMztzyir/s Tpa+5Dfbk8Vipoc+j5GyFQp4Fhi4C2/1BQO4Uxq1OiygWwl1nxtHo/BFh8lVKSb0nuPcVy u9vkbF8Fl9i4cj0BiFx26JU4Q3TGXM8= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795926; 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=9XdAe69CcLEJrm69PQqUCtA/hKhTPtcRgz0t4zCDbog=; b=/3eyQDYzFL31eRWEAG5QVmoucVww/rfQ/8Q0O0kcGB5VLLdZDBBnd+/MYtavMsH6msuX4P /K/ZRc06wT79uhCQ== 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 3A26513349; Thu, 2 Mar 2023 22:25:26 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id oVfBA1YiAWS6SQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:26 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 10/21] btrfs: lock extents before pages in writepages Date: Thu, 2 Mar 2023 16:24:55 -0600 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues 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. This converts a range_cyclic wbc to non-range_cyclic wbc with the range set to start from writeback_index and ending at inode size. This is done because inode size can change while the writepages() is going on. So, the number of pages accounted for writeback in wbc are accurate. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/extent_io.c | 5 ---- fs/btrfs/free-space-cache.c | 2 +- fs/btrfs/inode.c | 53 ++++++++++++++++++++++++++++--------- 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index e44329a84caf..cdce2db82d7e 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -483,15 +483,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/free-space-cache.c b/fs/btrfs/free-space-cache.c index 0d250d052487..2373f248d70f 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -355,9 +355,9 @@ int btrfs_truncate_free_space_cache(struct btrfs_trans_handle *trans, } btrfs_i_size_write(inode, 0); - truncate_pagecache(vfs_inode, 0); lock_extent(&inode->io_tree, 0, (u64)-1, &cached_state); + truncate_pagecache(vfs_inode, 0); btrfs_drop_extent_map_range(inode, 0, (u64)-1, false); /* diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 53bd9a64e803..eeddd7cdff58 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -977,7 +977,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; @@ -998,7 +997,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) @@ -1052,7 +1050,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 */ @@ -1080,7 +1078,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 | @@ -1248,7 +1246,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); @@ -1359,7 +1357,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; @@ -1410,7 +1408,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; @@ -1560,7 +1558,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 | @@ -1940,7 +1938,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 | @@ -2154,7 +2152,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); @@ -2190,7 +2188,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 | @@ -7845,7 +7843,38 @@ 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 = 0, end = LLONG_MAX; + struct inode *inode = mapping->host; + struct extent_state *cached = NULL; + int ret; + loff_t isize = i_size_read(inode); + struct writeback_control new_wbc = *wbc; + + if (new_wbc.range_cyclic) { + start = mapping->writeback_index << PAGE_SHIFT; + end = round_up(isize, PAGE_SIZE) - 1; + wbc->range_cyclic = 0; + wbc->range_start = start; + wbc->range_end = end; + } else { + start = round_down(wbc->range_start, PAGE_SIZE); + end = round_up(wbc->range_end, PAGE_SIZE) - 1; + } + + 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); + + if (new_wbc.range_cyclic) { + wbc->range_start = new_wbc.range_start; + wbc->range_end = new_wbc.range_end; + wbc->range_cyclic = 1; + } + + return ret; } static void btrfs_readahead_begin(struct readahead_control *rac) From patchwork Thu Mar 2 22:24:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157969 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 64541C6FA8E for ; Thu, 2 Mar 2023 22:25:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230001AbjCBWZd (ORCPT ); Thu, 2 Mar 2023 17:25:33 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42536 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229911AbjCBWZd (ORCPT ); Thu, 2 Mar 2023 17:25:33 -0500 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5262730198 for ; Thu, 2 Mar 2023 14:25:30 -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 133E92237D; Thu, 2 Mar 2023 22:25:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795929; 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=fIz8Sy2SIL+VPt/TUnMzOuzVIgOxE0LYh1jHsY1RCcs=; b=Syji1fLGUz/6G5/DQptFaYwHK20r2AyZVs88LZKNQ1oTDEMC26X3IxciyHrIghlNGllo8X dHVOwj9gYbsZPRAyHtTXhSF8ep1J+lD8ifzeoG1NdMhmlpWMdfk5GclyMxf6u355GoL9J8 6SXEQPLTUgNwWv6veD3uW9iZ0LzfAXU= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795929; 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=fIz8Sy2SIL+VPt/TUnMzOuzVIgOxE0LYh1jHsY1RCcs=; b=zfeuulkhifib39jtXUkyQSubP09OnxX0Euuk86N6O3PsGvS7W8VAWBHRVVijQFbEUF8pEj /SgmwWPIwH3spjBw== 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 A9AE013349; Thu, 2 Mar 2023 22:25:28 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id Pfy0G1giAWS+SQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:28 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 11/21] btrfs: locking extents for async writeback Date: Thu, 2 Mar 2023 16:24:56 -0600 Message-Id: <2aecd82ddb64139b04ccc51c5e625a7e6b3dc08e.1677793433.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues For async writebacks, lock the extents and then perform the cow file range for async. Unlock when async_chunk is free'd. Since writeback is performed in range, so locked_page can be removed from the structures and function parameters. Similarly for page_started and nr_written. A writeback could involve a hole, so check if the range locked covers the entire extent returned by find_lock_delalloc_range(). If not try to lock the entire range or unlock the pages locked. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/compression.c | 4 + fs/btrfs/extent_io.c | 10 +-- fs/btrfs/extent_io.h | 2 + fs/btrfs/inode.c | 184 ++++++++++++++++++----------------------- 4 files changed, 92 insertions(+), 108 deletions(-) diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index b0dd01e31078..a8fa7f2049ce 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -1424,6 +1424,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/extent_io.c b/fs/btrfs/extent_io.c index cdce2db82d7e..12aa7eaf12c5 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -358,7 +358,7 @@ static int __process_pages_contig(struct address_space *mapping, return err; } -static noinline void __unlock_for_delalloc(struct inode *inode, +noinline void __unlock_for_delalloc(struct inode *inode, struct page *locked_page, u64 start, u64 end) { @@ -383,8 +383,7 @@ static noinline int lock_delalloc_pages(struct inode *inode, u64 processed_end = delalloc_start; int ret; - ASSERT(locked_page); - if (index == locked_page->index && index == end_index) + if (locked_page && index == locked_page->index && index == end_index) return 0; ret = __process_pages_contig(inode->i_mapping, locked_page, delalloc_start, @@ -432,8 +431,9 @@ noinline_for_stack bool find_lock_delalloc_range(struct inode *inode, ASSERT(orig_end > orig_start); /* The range should at least cover part of the page */ - ASSERT(!(orig_start >= page_offset(locked_page) + PAGE_SIZE || - orig_end <= page_offset(locked_page))); + if (locked_page) + ASSERT(!(orig_start >= page_offset(locked_page) + PAGE_SIZE || + orig_end <= page_offset(locked_page))); again: /* step one, find a bunch of delalloc bytes starting at start */ delalloc_start = *start; diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 4341ad978fb8..ddfa100ab629 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -279,6 +279,8 @@ void btrfs_clear_buffer_dirty(struct btrfs_trans_handle *trans, int btrfs_alloc_page_array(unsigned int nr_pages, struct page **page_array); void end_extent_writepage(struct page *page, int err, u64 start, u64 end); +void __unlock_for_delalloc(struct inode *inode, struct page *locked_page, + u64 start, u64 end); #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS bool find_lock_delalloc_range(struct inode *inode, diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index eeddd7cdff58..fb02b2b3ac2e 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -506,7 +506,6 @@ struct async_extent { struct async_chunk { struct btrfs_inode *inode; - struct page *locked_page; u64 start; u64 end; blk_opf_t write_flags; @@ -887,18 +886,6 @@ static noinline int compress_file_range(struct async_chunk *async_chunk) } } cleanup_and_bail_uncompressed: - /* - * No compression, but we still need to write the pages in the file - * we've been given so far. redirty the locked page if it corresponds - * to our extent and set things up for the async work queue to run - * cow_file_range to do the normal delalloc dance. - */ - if (async_chunk->locked_page && - (page_offset(async_chunk->locked_page) >= start && - page_offset(async_chunk->locked_page)) <= end) { - __set_page_dirty_nobuffers(async_chunk->locked_page); - /* unlocked later on in the async handlers */ - } if (redirty) extent_range_redirty_for_io(&inode->vfs_inode, start, end); @@ -926,8 +913,7 @@ static void free_async_extent_pages(struct async_extent *async_extent) } static int submit_uncompressed_range(struct btrfs_inode *inode, - struct async_extent *async_extent, - struct page *locked_page) + struct async_extent *async_extent) { u64 start = async_extent->start; u64 end = async_extent->start + async_extent->ram_size - 1; @@ -942,7 +928,7 @@ static int submit_uncompressed_range(struct btrfs_inode *inode, * Also we call cow_file_range() with @unlock_page == 0, so that we * can directly submit them without interruption. */ - ret = cow_file_range(inode, locked_page, start, end, &page_started, + ret = cow_file_range(inode, NULL, start, end, &page_started, &nr_written, 0, NULL); /* Inline extent inserted, page gets unlocked and everything is done */ if (page_started) { @@ -950,23 +936,12 @@ static int submit_uncompressed_range(struct btrfs_inode *inode, goto out; } if (ret < 0) { - btrfs_cleanup_ordered_extents(inode, locked_page, start, end - start + 1); - if (locked_page) { - const u64 page_start = page_offset(locked_page); - const u64 page_end = page_start + PAGE_SIZE - 1; - - btrfs_page_set_error(inode->root->fs_info, locked_page, - page_start, PAGE_SIZE); - set_page_writeback(locked_page); - end_page_writeback(locked_page); - end_extent_writepage(locked_page, ret, page_start, page_end); - unlock_page(locked_page); - } + btrfs_cleanup_ordered_extents(inode, NULL, start, end - start + 1); goto out; } ret = extent_write_locked_range(&inode->vfs_inode, start, end); - /* All pages will be unlocked, including @locked_page */ + /* All pages will be unlocked */ out: kfree(async_extent); return ret; @@ -980,27 +955,14 @@ static int submit_one_async_extent(struct btrfs_inode *inode, struct btrfs_root *root = inode->root; struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_key ins; - struct page *locked_page = NULL; struct extent_map *em; int ret = 0; u64 start = async_extent->start; u64 end = async_extent->start + async_extent->ram_size - 1; - /* - * If async_chunk->locked_page is in the async_extent range, we need to - * handle it. - */ - if (async_chunk->locked_page) { - u64 locked_page_start = page_offset(async_chunk->locked_page); - u64 locked_page_end = locked_page_start + PAGE_SIZE - 1; - - if (!(start >= locked_page_end || end <= locked_page_start)) - locked_page = async_chunk->locked_page; - } - /* We have fall back to uncompressed write */ if (!async_extent->pages) - return submit_uncompressed_range(inode, async_extent, locked_page); + return submit_uncompressed_range(inode, async_extent); ret = btrfs_reserve_extent(root, async_extent->ram_size, async_extent->compressed_size, @@ -1476,6 +1438,8 @@ 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, NULL); btrfs_add_delayed_iput(async_chunk->inode); async_chunk->inode = NULL; } @@ -1515,11 +1479,15 @@ 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, NULL); 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); @@ -1527,9 +1495,7 @@ static noinline void async_cow_free(struct btrfs_work *work) static int cow_file_range_async(struct btrfs_inode *inode, struct writeback_control *wbc, - struct page *locked_page, - u64 start, u64 end, int *page_started, - unsigned long *nr_written) + u64 start, u64 end) { struct btrfs_fs_info *fs_info = inode->root->fs_info; struct cgroup_subsys_state *blkcg_css = wbc_blkcg_css(wbc); @@ -1539,20 +1505,9 @@ static int cow_file_range_async(struct btrfs_inode *inode, u64 cur_end; u64 num_chunks = DIV_ROUND_UP(end - start, SZ_512K); int i; - bool should_compress; 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)) { - num_chunks = 1; - should_compress = false; - } else { - should_compress = true; - } - nofs_flag = memalloc_nofs_save(); ctx = kvmalloc(struct_size(ctx, chunks, num_chunks), GFP_KERNEL); memalloc_nofs_restore(nofs_flag); @@ -1564,19 +1519,17 @@ static int cow_file_range_async(struct btrfs_inode *inode, unsigned long page_ops = PAGE_UNLOCK | PAGE_START_WRITEBACK | PAGE_END_WRITEBACK | PAGE_SET_ERROR; - extent_clear_unlock_delalloc(inode, start, end, locked_page, + extent_clear_unlock_delalloc(inode, start, end, NULL, clear_bits, page_ops); return -ENOMEM; } + set_bit(BTRFS_INODE_HAS_ASYNC_EXTENT, &inode->runtime_flags); async_chunk = ctx->chunks; atomic_set(&ctx->num_chunks, num_chunks); for (i = 0; i < num_chunks; i++) { - if (should_compress) - cur_end = min(end, start + SZ_512K - 1); - else - cur_end = end; + cur_end = min(end, start + SZ_512K - 1); /* * igrab is called higher up in the call chain, take only the @@ -1590,33 +1543,6 @@ static int cow_file_range_async(struct btrfs_inode *inode, async_chunk[i].write_flags = write_flags; INIT_LIST_HEAD(&async_chunk[i].extents); - /* - * The locked_page comes all the way from writepage and its - * the original page we were actually given. As we spread - * this large delalloc region across multiple async_chunk - * structs, only the first struct needs a pointer to locked_page - * - * This way we don't need racey decisions about who is supposed - * to unlock it. - */ - if (locked_page) { - /* - * Depending on the compressibility, the pages might or - * might not go through async. We want all of them to - * be accounted against wbc once. Let's do it here - * before the paths diverge. wbc accounting is used - * only for foreign writeback detection and doesn't - * need full accuracy. Just account the whole thing - * against the first page. - */ - wbc_account_cgroup_owner(wbc, locked_page, - cur_end - start); - async_chunk[i].locked_page = locked_page; - locked_page = NULL; - } else { - async_chunk[i].locked_page = NULL; - } - if (blkcg_css != blkcg_root_css) { css_get(blkcg_css); async_chunk[i].blkcg_css = blkcg_css; @@ -1632,10 +1558,8 @@ static int cow_file_range_async(struct btrfs_inode *inode, btrfs_queue_work(fs_info->delalloc_workers, &async_chunk[i].work); - *nr_written += nr_pages; start = cur_end + 1; } - *page_started = 1; return 0; } @@ -2238,18 +2162,13 @@ 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 (zoned) ret = run_delalloc_zoned(inode, locked_page, start, end, page_started, nr_written); else 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); } ASSERT(ret <= 0); if (ret) @@ -7840,14 +7759,68 @@ static int btrfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, return extent_fiemap(BTRFS_I(inode), fieinfo, start, len); } +static int btrfs_writepages_async(struct btrfs_inode *inode, struct writeback_control *wbc, u64 start, u64 end) +{ + u64 last_start, cur_start = start; + u64 cur_end; + int ret = 0; + + lock_extent(&inode->io_tree, start, end, NULL); + + while (cur_start < end) { + bool found; + last_start = cur_start; + cur_end = end; + + found = find_lock_delalloc_range(&inode->vfs_inode, NULL, &cur_start, &cur_end); + /* Nothing to writeback */ + if (!found) { + unlock_extent(&inode->io_tree, cur_start, cur_end, NULL); + cur_start = cur_end + 1; + continue; + } + + /* A hole with no pages, unlock part therof */ + if (cur_start > last_start) + unlock_extent(&inode->io_tree, last_start, cur_start - 1, NULL); + + /* Got more than we requested for */ + if (cur_end > end) { + if (try_lock_extent(&inode->io_tree, end + 1, cur_end, NULL)) { + /* Try writing the whole extent */ + end = cur_end; + } else { + /* + * Someone is holding the extent lock. + * Unlock pages from last part of extent, and + * write just as much writepage requested for + */ + __unlock_for_delalloc(&inode->vfs_inode, NULL, end + 1, cur_end); + cur_end = end; + } + } + + ret = cow_file_range_async(inode, wbc, cur_start, cur_end); + if (ret < 0) { + unlock_extent(&inode->io_tree, cur_start, end, NULL); + break; + } + + cur_start = cur_end + 1; + } + + return ret; +} + static int btrfs_writepages(struct address_space *mapping, struct writeback_control *wbc) { u64 start = 0, end = LLONG_MAX; - struct inode *inode = mapping->host; + struct btrfs_inode *inode = BTRFS_I(mapping->host); + struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb); struct extent_state *cached = NULL; int ret; - loff_t isize = i_size_read(inode); + loff_t isize = i_size_read(&inode->vfs_inode); struct writeback_control new_wbc = *wbc; if (new_wbc.range_cyclic) { @@ -7864,9 +7837,14 @@ static int btrfs_writepages(struct address_space *mapping, 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); + if (btrfs_test_opt(fs_info, COMPRESS) && + btrfs_inode_can_compress(inode)) { + ret = btrfs_writepages_async(inode, wbc, start, end); + } else { + lock_extent(&inode->io_tree, start, end, &cached); + ret = extent_writepages(mapping, wbc); + unlock_extent(&inode->io_tree, start, end, &cached); + } if (new_wbc.range_cyclic) { wbc->range_start = new_wbc.range_start; From patchwork Thu Mar 2 22:24:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157970 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 54643C678D4 for ; Thu, 2 Mar 2023 22:25:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229998AbjCBWZf (ORCPT ); Thu, 2 Mar 2023 17:25:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42558 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230000AbjCBWZd (ORCPT ); Thu, 2 Mar 2023 17:25:33 -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 0A8D82A6C3 for ; Thu, 2 Mar 2023 14:25:33 -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 B97AD20062; Thu, 2 Mar 2023 22:25:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795931; 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=YvzgEnrzteNMMF0btcimIn2o+B4PrnaqXo6BnEcB3Rg=; b=KKoVKjg6zr8fwGTAWGMB6V4q+rrXfuyC0kkSf7AEBKKWx4OtbJRNOLAQjo4uYdEhBPZugk j3A34DGZESTOtejfyh2zKKshOYkILEZEWWR4Xw0Qm4nhpt+UttyN/2hdWk8uXWjF2dkg3W D6C93r2t3h0W7PgRHPvj8s9Wjmk00mY= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795931; 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=YvzgEnrzteNMMF0btcimIn2o+B4PrnaqXo6BnEcB3Rg=; b=ZtpGSM+i8R8hlSa5pPdN53ydXIiIjhmrpuMCsvljXx34vT0w24ULjGJQ68aClWO51j5lqj zQOk1NxmwWxdcDCw== 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 70B5F13349; Thu, 2 Mar 2023 22:25:31 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 5gOjD1siAWTCSQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:31 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Josef Bacik Subject: [PATCH 12/21] btrfs: lock extents before pages - defrag Date: Thu, 2 Mar 2023 16:24:57 -0600 Message-Id: <94356619bfac67197c4ccf371aee000f3a771f84.1677793433.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues 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 8065341d831a..dff53458bf52 100644 --- a/fs/btrfs/defrag.c +++ b/fs/btrfs/defrag.c @@ -721,9 +721,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; @@ -753,32 +750,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); - 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. @@ -1076,6 +1047,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); @@ -1088,10 +1064,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. @@ -1103,7 +1075,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, @@ -1116,10 +1088,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]) { @@ -1128,6 +1096,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 Thu Mar 2 22:24:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157971 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 8704AC6FA8E for ; Thu, 2 Mar 2023 22:25:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230004AbjCBWZh (ORCPT ); Thu, 2 Mar 2023 17:25:37 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42618 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230000AbjCBWZg (ORCPT ); Thu, 2 Mar 2023 17:25:36 -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 6919428874 for ; Thu, 2 Mar 2023 14:25:35 -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 24E6C2237D; Thu, 2 Mar 2023 22:25:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795934; 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=VcYoCfnD6Ya4TIFGBn+KbSLGIKaOxfJrJ31n105TRSA=; b=XUp3CBUdBhSOJyTgIx3qRsedWNoUxCpgi+VPtQHmyiEOcPsJmDp6c2NMfejvZSIVgQmSaI r4RQ6OW6OtuqimZmGkqu76wYiqgxDIv+pvoZxw36jh/fIPglGmlvdep/oJs4iXoc3P1h4N hl/OVF6Vzu3eNl8M0ZvfrsKtjZxGb0U= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795934; 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=VcYoCfnD6Ya4TIFGBn+KbSLGIKaOxfJrJ31n105TRSA=; b=ZWWE9ZwioCNY53K3c25EFxIJgax2tXbnwFCCmOlrBfFW11mjURIm+Ec39Z1V2K2+aNSPHj Xf++I7jyCLIIPMDw== 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 C724813349; Thu, 2 Mar 2023 22:25:33 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id fsSeJ10iAWTFSQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:33 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 13/21] btrfs: Perform memory faults under locked extent Date: Thu, 2 Mar 2023 16:24:58 -0600 Message-Id: <1f8fe6c93e54b3bbf42c48c55884f3c7a56f1e94.1677793433.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues 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 2e835096e3ce..fe1f63456142 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1973,8 +1973,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 = round_down(vmf->pgoff, PAGE_SIZE); + 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 fb02b2b3ac2e..ed3553ff2c31 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -8132,7 +8132,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; @@ -8187,11 +8186,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; } @@ -8202,7 +8199,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); @@ -8235,7 +8231,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; } @@ -8255,7 +8250,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 Thu Mar 2 22:24:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157972 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 CA06DC678D4 for ; Thu, 2 Mar 2023 22:25:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230006AbjCBWZj (ORCPT ); Thu, 2 Mar 2023 17:25:39 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42694 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230000AbjCBWZi (ORCPT ); Thu, 2 Mar 2023 17:25:38 -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 D9C511EBDC for ; Thu, 2 Mar 2023 14:25:37 -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 976882006A; Thu, 2 Mar 2023 22:25:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795936; 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=rXW5FQGj9VNsz5SGumcDH4TmXBqBNvJ99X65t2v1X8c=; b=ezSeHnC8Ku0zTh9IHE7Gdd2MfSw16PiuVE/+/bOK6U9pEbKgC5BlTPMoznPGgv8yIv4jnS hA4kDCXhcRMlM98DWdtEHCQf2uhHJ5hdSSzo1or2W6e1WdlgcIYBoGtalnKFTiyvUwTviC dZy7elLAcN0X2aMNbAClRWMNnQl7gH8= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795936; 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=rXW5FQGj9VNsz5SGumcDH4TmXBqBNvJ99X65t2v1X8c=; b=LouYuMCE95ipcXvQAJ6JrPQW+QXnDpR/iKA5qgjfrHuKu2mstk/xXTi9gnwLuPXwP7nAjr wk37I6rWL5KerrDQ== 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 5358A13349; Thu, 2 Mar 2023 22:25:36 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id axXtDGAiAWTVSQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:36 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Josef Bacik Subject: [PATCH 14/21] btrfs: writepage fixup lock rearrangement Date: Thu, 2 Mar 2023 16:24:59 -0600 Message-Id: <0513454915b54ca4572e30c5d42915fa987ad245.1677793433.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues 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 ed3553ff2c31..f879c65ee8cc 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2722,6 +2722,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; @@ -2733,9 +2734,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); /* @@ -2778,19 +2786,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); btrfs_put_ordered_extent(ordered); + goto again; } @@ -2813,7 +2820,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 Thu Mar 2 22:25:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157973 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 2F2A0C6FA8E for ; Thu, 2 Mar 2023 22:25:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230008AbjCBWZm (ORCPT ); Thu, 2 Mar 2023 17:25:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42746 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230000AbjCBWZl (ORCPT ); Thu, 2 Mar 2023 17:25:41 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 359301EBDC for ; Thu, 2 Mar 2023 14:25:40 -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 EA8EA2006A; Thu, 2 Mar 2023 22:25:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795938; 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=qNMnYZjtpI1sknuwdOT3eQNI4Fbqyn71ytbQ6Splzt4=; b=1hRK3lqSOeoORL9ZFC+Cybe8BRFkkL66W4YD0WqVFf/sXezQ1kxmGbr6mMyPQhu9YIpVCy fIu48x84741O+ilE3M2+LMSP11JHWeYMn+jAe0LmE2IFN7n4GN8sthdDtBcZVCQNArqFr/ FxnTnZOqs/UQyAkt66xAqHVsPl5YulI= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795938; 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=qNMnYZjtpI1sknuwdOT3eQNI4Fbqyn71ytbQ6Splzt4=; b=3Ke6GW8k4NLG8T3NbCXetxD8SI5h5vKqAlWAeofxhf+k13GxugKFBSEakCgorPNHzYw6m5 lgGB4XdKwCOiq8Bw== 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 94B1113349; Thu, 2 Mar 2023 22:25:38 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id iePoHGIiAWTZSQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:38 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Josef Bacik Subject: [PATCH 15/21] btrfs: lock extent before pages for encoded read ioctls Date: Thu, 2 Mar 2023 16:25:00 -0600 Message-Id: <476ceb4477d4ffa7a2cebfc3cc0119bfa48637f9.1677793433.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues 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 f879c65ee8cc..729def5969d8 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -9839,13 +9839,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; @@ -9907,9 +9905,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) @@ -10003,11 +9998,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; @@ -10029,10 +10022,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; @@ -10075,7 +10064,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); @@ -10126,7 +10114,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; } @@ -10179,9 +10167,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; @@ -10189,8 +10174,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: @@ -10199,11 +10183,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 Thu Mar 2 22:25:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157974 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 32574C678D4 for ; Thu, 2 Mar 2023 22:25:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230009AbjCBWZo (ORCPT ); Thu, 2 Mar 2023 17:25:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42798 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230000AbjCBWZn (ORCPT ); Thu, 2 Mar 2023 17:25:43 -0500 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A47BB28874 for ; Thu, 2 Mar 2023 14:25:42 -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 662FA2237D; Thu, 2 Mar 2023 22:25:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795941; 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=Gpu09xd6U5oQFkn+SQpqbDOt7WLajxoD4F1GGmazUog=; b=FrQ/sVCKfLTs+0UWkWTEH3IB+Mm254ISFFst0GeFUySPQt59Yhkcx4+FX0qsXJ9H0Hs5mU Ho5dIUs12f3W1Pls+vUUuAcMeLqIfT5ywPsQg00pot2iDWiAy6GoFeM0DbeyOcKhp03afY r4fuNlQ+M5gD+bB+/AjpbzZovHpry1c= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795941; 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=Gpu09xd6U5oQFkn+SQpqbDOt7WLajxoD4F1GGmazUog=; b=fSe6Kt2uaKaRe+mxAwdf0PetAP9qo80grE6ACgx2+MouD3UZaRPMUyTar5BWU5K+ljlQv3 B+nwYkTWNyJGB4CA== 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 F01AF13349; Thu, 2 Mar 2023 22:25:40 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id OKffLGQiAWTfSQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:40 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues , Josef Bacik Subject: [PATCH 16/21] btrfs: lock extent before pages in encoded write Date: Thu, 2 Mar 2023 16:25:01 -0600 Message-Id: <747c039e512fbfa55d862e57e727a9d10a4859db.1677793433.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues 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 729def5969d8..70cf852a3efd 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -10289,37 +10289,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 && @@ -10331,6 +10312,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. @@ -10389,8 +10390,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, @@ -10400,6 +10399,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; @@ -10419,14 +10421,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 Thu Mar 2 22:25:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157975 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 743BCC678D4 for ; Thu, 2 Mar 2023 22:25:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230018AbjCBWZs (ORCPT ); Thu, 2 Mar 2023 17:25:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42864 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230015AbjCBWZp (ORCPT ); Thu, 2 Mar 2023 17:25:45 -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 04FBF234DA for ; Thu, 2 Mar 2023 14:25: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-out1.suse.de (Postfix) with ESMTPS id B25692237D; Thu, 2 Mar 2023 22:25:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795943; 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=Y5Keo3uOIRWd2QQtlffm4dxJ8jVIoJZoS/Ta0DgpzJg=; b=BE5oABYEquxmDkr0yQ8U48f9+s6IRncMjy9iJFS+fZFfhVUkJna8uUnTtn/zIbde/NBpMR Vh5r0lftxTSdS2e2RFDNoZXmXZdfibvz9Q+hBoAhlOebB/gJn3YTYEdiV5Nq2obKzgyL+c EF0hibEgjx88dXYvzD+6AeESvNrS054= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795943; 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=Y5Keo3uOIRWd2QQtlffm4dxJ8jVIoJZoS/Ta0DgpzJg=; b=Np+/PPxeJOMp6kJtuDZpGAEoYqavu64Qs6pzZRU1mfa+yMuUNIax+wYqlg5e/YlxediFjV o8Yd43Yg1iN2HBCw== 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 6BA0B13349; Thu, 2 Mar 2023 22:25:43 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id NE/dDWciAWTmSQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:43 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 17/21] btrfs: btree_writepages lock extents before pages Date: Thu, 2 Mar 2023 16:25:02 -0600 Message-Id: <409ec63c5aec1f140c60e6ae354f9461995a648f.1677793433.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues 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 c2b954134851..5164bb9f6e2d 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -725,8 +725,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) { @@ -741,7 +758,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) From patchwork Thu Mar 2 22:25:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157976 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 132B7C7EE30 for ; Thu, 2 Mar 2023 22:25:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230022AbjCBWZt (ORCPT ); Thu, 2 Mar 2023 17:25:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42904 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230015AbjCBWZs (ORCPT ); Thu, 2 Mar 2023 17:25:48 -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 B73A528865 for ; Thu, 2 Mar 2023 14:25: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 732E42237B; Thu, 2 Mar 2023 22:25:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795946; 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=B5ZbVhdR6Id5JadXe5L6hsSKzXfhgcUDStfY2TU6GPI=; b=NbrD8Iicua/sGTGAOxKzcmiLFE7/5tJsKVanWbSFQ9qXF26c8Suda/4Cvmt/nYza0icPK3 SHbGg+QkGhrJMzBb8g7ZIBfkMhTwxtEZ/CXewY9koV4mw+UppIUlfO6IBXVXjDxO2Ntw36 BaEgShJhe+OSVYBPcbMfZyzr1BSELdM= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795946; 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=B5ZbVhdR6Id5JadXe5L6hsSKzXfhgcUDStfY2TU6GPI=; b=XMRQJzFIbxPQTneiG/VAojRr2cr33madlzBbsv8tx7JAW6vXuMMUXnaWYz1LjDB1F3RupM OdgPn43LqqttkUAw== 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 2CD9313349; Thu, 2 Mar 2023 22:25:46 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id US4SA2oiAWTuSQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:46 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 18/21] btrfs: check if writeback pages exist before starting writeback Date: Thu, 2 Mar 2023 16:25:03 -0600 Message-Id: <3499da06f72955091f63c15bfe454f77b72e4300.1677793433.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues Check if there are still pages to writeback after locking. This avoids calls to check for extents. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/inode.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 70cf852a3efd..c4e5eb5d9ee4 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7773,6 +7773,11 @@ static int btrfs_writepages_async(struct btrfs_inode *inode, struct writeback_co lock_extent(&inode->io_tree, start, end, NULL); + if (!filemap_range_has_writeback(inode->vfs_inode.i_mapping, start, end)) { + unlock_extent(&inode->io_tree, start, end, NULL); + return 0; + } + while (cur_start < end) { bool found; last_start = cur_start; From patchwork Thu Mar 2 22:25:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157977 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 8C65AC7EE30 for ; Thu, 2 Mar 2023 22:25:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230031AbjCBWZx (ORCPT ); Thu, 2 Mar 2023 17:25:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43032 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230020AbjCBWZw (ORCPT ); Thu, 2 Mar 2023 17:25:52 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C8BB428874 for ; Thu, 2 Mar 2023 14:25:50 -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 89C692006A; Thu, 2 Mar 2023 22:25:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795949; 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=cevwE62oedduoKyp7E+ilufz29r5dFRRDlg0n8a5c/w=; b=eDEbhO9W1gQiQuyRYnS2DBQyd1pLQEZu1vz7KLnjYmug8dcLuQEZ07ADOm1yuz04i2vbI4 hPHpE8R+n0pVjgWaAIrX9UduOHIyYx0H8up4Flw+cjs1bwJ0b/vbhbQjssKZDtTD+3EG1/ IiH4NEZnecxocMW3dF8qAIyGu3PUmdU= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795949; 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=cevwE62oedduoKyp7E+ilufz29r5dFRRDlg0n8a5c/w=; b=aEOJ9iZoQ9s4BCscX60WoHvAeF6GUTSbY7ThNTYbLOp0unMe1VekNKkgwNM5F3hPSwTo19 AKINjUjHgdn0WTBw== 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 4389B13349; Thu, 2 Mar 2023 22:25:49 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id E+9pCG0iAWTwSQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:49 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 19/21] btrfs: lock extents before pages in relocation Date: Thu, 2 Mar 2023 16:25:04 -0600 Message-Id: <8864239884312377b62a36bfa65f1f8f66351855.1677793433.git.rgoldwyn@suse.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues While relocating extents, lock the extents first. The locking is performed before setup_relocation_extent() and unlocked after all pages have been set as dirty. All allocation is consolidated into one call to reserve metadata. Call balance dirty pages outside of locks. Q: This rearranges the sequence of calls. Not sure if this is correct. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/relocation.c | 44 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index ef13a9d4e370..f15e9b1bfc45 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -2911,7 +2911,6 @@ static noinline_for_stack int setup_relocation_extent_mapping(struct inode *inod u64 start, u64 end, u64 block_start) { struct extent_map *em; - struct extent_state *cached_state = NULL; int ret = 0; em = alloc_extent_map(); @@ -2924,9 +2923,7 @@ static noinline_for_stack int setup_relocation_extent_mapping(struct inode *inod em->block_start = block_start; set_bit(EXTENT_FLAG_PINNED, &em->flags); - lock_extent(&BTRFS_I(inode)->io_tree, start, end, &cached_state); ret = btrfs_replace_extent_map_range(BTRFS_I(inode), em, false); - unlock_extent(&BTRFS_I(inode)->io_tree, start, end, &cached_state); free_extent_map(em); return ret; @@ -2971,8 +2968,6 @@ static int relocate_one_page(struct inode *inode, struct file_ra_state *ra, ASSERT(page_index <= last_index); page = find_lock_page(inode->i_mapping, page_index); if (!page) { - page_cache_sync_readahead(inode->i_mapping, ra, NULL, - page_index, last_index + 1 - page_index); page = find_or_create_page(inode->i_mapping, page_index, mask); if (!page) return -ENOMEM; @@ -2981,11 +2976,6 @@ static int relocate_one_page(struct inode *inode, struct file_ra_state *ra, if (ret < 0) goto release_page; - if (PageReadahead(page)) - page_cache_async_readahead(inode->i_mapping, ra, NULL, - page_folio(page), page_index, - last_index + 1 - page_index); - if (!PageUptodate(page)) { btrfs_read_folio(NULL, page_folio(page)); lock_page(page); @@ -3012,16 +3002,7 @@ static int relocate_one_page(struct inode *inode, struct file_ra_state *ra, u64 clamped_end = min(page_end, extent_end); u32 clamped_len = clamped_end + 1 - clamped_start; - /* Reserve metadata for this range */ - ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), - clamped_len, clamped_len, - false); - if (ret) - goto release_page; - /* Mark the range delalloc and dirty for later writeback */ - lock_extent(&BTRFS_I(inode)->io_tree, clamped_start, clamped_end, - &cached_state); ret = btrfs_set_extent_delalloc(BTRFS_I(inode), clamped_start, clamped_end, 0, &cached_state); if (ret) { @@ -3055,9 +3036,6 @@ static int relocate_one_page(struct inode *inode, struct file_ra_state *ra, boundary_start, boundary_end, EXTENT_BOUNDARY); } - unlock_extent(&BTRFS_I(inode)->io_tree, clamped_start, clamped_end, - &cached_state); - btrfs_delalloc_release_extents(BTRFS_I(inode), clamped_len); cur += clamped_len; /* Crossed extent end, go to next extent */ @@ -3071,7 +3049,6 @@ static int relocate_one_page(struct inode *inode, struct file_ra_state *ra, unlock_page(page); put_page(page); - balance_dirty_pages_ratelimited(inode->i_mapping); btrfs_throttle(fs_info); if (btrfs_should_cancel_balance(fs_info)) ret = -ECANCELED; @@ -3092,6 +3069,10 @@ static int relocate_file_extent_cluster(struct inode *inode, struct file_ra_state *ra; int cluster_nr = 0; int ret = 0; + u64 start = cluster->start - offset; + u64 end = cluster->end - offset; + loff_t len = end + 1 - start; + struct extent_state *cached_state = NULL; if (!cluster->nr) return 0; @@ -3106,17 +3087,30 @@ static int relocate_file_extent_cluster(struct inode *inode, file_ra_state_init(ra, inode->i_mapping); - ret = setup_relocation_extent_mapping(inode, cluster->start - offset, - cluster->end - offset, cluster->start); + page_cache_sync_readahead(inode->i_mapping, ra, NULL, + start >> PAGE_SHIFT, len >> PAGE_SHIFT); + + ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), len, len , false); if (ret) goto out; + lock_extent(&BTRFS_I(inode)->io_tree, start, end, &cached_state); + + ret = setup_relocation_extent_mapping(inode, start, end, cluster->start); + if (ret) + goto unlock; + last_index = (cluster->end - offset) >> PAGE_SHIFT; for (index = (cluster->start - offset) >> PAGE_SHIFT; index <= last_index && !ret; index++) ret = relocate_one_page(inode, ra, cluster, &cluster_nr, index); if (ret == 0) WARN_ON(cluster_nr != cluster->nr); +unlock: + unlock_extent(&BTRFS_I(inode)->io_tree, start, end, &cached_state); + btrfs_delalloc_release_extents(BTRFS_I(inode), len); + + balance_dirty_pages_ratelimited(inode->i_mapping); out: kfree(ra); return ret; From patchwork Thu Mar 2 22:25:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157978 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 008F3C678D4 for ; Thu, 2 Mar 2023 22:25:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230048AbjCBWZ6 (ORCPT ); Thu, 2 Mar 2023 17:25:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43140 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230038AbjCBWZy (ORCPT ); Thu, 2 Mar 2023 17:25:54 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3F257303CE for ; Thu, 2 Mar 2023 14:25:53 -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 E0CB42006B; Thu, 2 Mar 2023 22:25:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795951; 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=7T12swTc5dwKhsvLTQeh51cvZRrZ1mkPwvm42hkHB+Q=; b=JwD8UQfZWuu6uEPfEI3QnO0v0Rs3d87JDvAdSldu0srlt5nNUch4OSaeOK9uyoI9YNiN91 U+vwf/fFptk7Cw/h03Dx6RAX75f8OLzB4fWO3Cu3ASyY5aU5LzDWmAmhMZxqUpRjut6ltW UOypV5WHwtmSQYt1K8SzWubd2P4N9QY= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795951; 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=7T12swTc5dwKhsvLTQeh51cvZRrZ1mkPwvm42hkHB+Q=; b=uswocf1aULctJ9BXKF8DTA9LGycjXiB06vOZnLAI2nD6xCSYWYFuGZBHuPNrvq+hy98JMW Rse0V5+22DHTCcAg== 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 96AC713349; Thu, 2 Mar 2023 22:25:51 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id epIVHW8iAWT2SQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:51 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 20/21] btrfs: Add inode->i_count instead of calling ihold() Date: Thu, 2 Mar 2023 16:25:05 -0600 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues I am not sure of this patch, but put it to avoid the WARN_ON() in ihold(). I am not sure why the i_count would drop below one at this point of time since this is still called within writepages context. Perhaps, there is a better way to solve this? --- fs/btrfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index c4e5eb5d9ee4..b5f5c1896dbb 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -1535,7 +1535,7 @@ static int cow_file_range_async(struct btrfs_inode *inode, * igrab is called higher up in the call chain, take only the * lightweight reference for the callback lifetime */ - ihold(&inode->vfs_inode); + atomic_inc(&inode->vfs_inode.i_count); async_chunk[i].async_cow = ctx; async_chunk[i].inode = inode; async_chunk[i].start = start; From patchwork Thu Mar 2 22:25:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Goldwyn Rodrigues X-Patchwork-Id: 13157979 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 4A912C6FA8E for ; Thu, 2 Mar 2023 22:26:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230038AbjCBW0A (ORCPT ); Thu, 2 Mar 2023 17:26:00 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43254 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230037AbjCBWZ6 (ORCPT ); Thu, 2 Mar 2023 17:25:58 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B142B33462 for ; Thu, 2 Mar 2023 14:25:55 -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 6C3632006A; Thu, 2 Mar 2023 22:25:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1677795954; 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=F7C2xhp9MLIt0v3/UeQF+fgDVwDd7TAsxBhvuW4XL0s=; b=xuA/8OiaJf+clzqLD7p1MX2nFiTKAvFyjsu35BTEtKwakGDjn3tKquRwW3qYP3Ql5ZQlMS KF701yfFjPCX4oZcY+bqOZRKdO1ZKzvsCJE2KuGSmqA+2M/2GvRev7fBjt5h0Hmf27R29P 4gNxMpyKTvsM2sJYmu7Pkegnyz22s+k= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1677795954; 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=F7C2xhp9MLIt0v3/UeQF+fgDVwDd7TAsxBhvuW4XL0s=; b=i+w/cqdM4bAQb8w9Osdnh8mwpO83OKifkoPzDEGIvV87vkZuCXKZ5yfK0UTUs0dmZJK9bp 2m53UG7846ItePAg== 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 1C24413349; Thu, 2 Mar 2023 22:25:53 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id ZLn5OnEiAWT6SQAAMHmgww (envelope-from ); Thu, 02 Mar 2023 22:25:53 +0000 From: Goldwyn Rodrigues To: linux-btrfs@vger.kernel.org Cc: Goldwyn Rodrigues Subject: [PATCH 21/21] btrfs: debug extent locking Date: Thu, 2 Mar 2023 16:25:06 -0600 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Goldwyn Rodrigues This is the patch I used to figure out who locked the extent before the deadlock. While this patch is not required, it may be helpful to debug extent based deadlocks. Signed-off-by: Goldwyn Rodrigues --- fs/btrfs/extent-io-tree.c | 27 +++++++++++---------- fs/btrfs/extent-io-tree.h | 46 +++++++++++++++++++++--------------- fs/btrfs/extent_io.c | 2 +- fs/btrfs/extent_map.c | 2 +- fs/btrfs/inode.c | 4 ++-- fs/btrfs/ordered-data.c | 8 +++---- fs/btrfs/ordered-data.h | 3 ++- include/trace/events/btrfs.h | 18 +++++++++----- 8 files changed, 63 insertions(+), 47 deletions(-) diff --git a/fs/btrfs/extent-io-tree.c b/fs/btrfs/extent-io-tree.c index d467c614c84e..25faf587f050 100644 --- a/fs/btrfs/extent-io-tree.c +++ b/fs/btrfs/extent-io-tree.c @@ -545,7 +545,7 @@ static struct extent_state *clear_state_bit(struct extent_io_tree *tree, * * This takes the tree lock, and returns 0 on success and < 0 on error. */ -int __clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, +int __clear_extent_bit(struct extent_io_tree *tree, const char *func, u64 start, u64 end, u32 bits, struct extent_state **cached_state, gfp_t mask, struct extent_changeset *changeset) { @@ -559,7 +559,7 @@ int __clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, int delete = (bits & EXTENT_CLEAR_ALL_BITS); btrfs_debug_check_extent_io_range(tree, start, end); - trace_btrfs_clear_extent_bit(tree, start, end - start + 1, bits); + trace_btrfs_clear_extent_bit(tree, func, start, end - start + 1, bits); if (delete) bits |= ~EXTENT_CTLBITS; @@ -965,7 +965,7 @@ bool btrfs_find_delalloc_range(struct extent_io_tree *tree, u64 *start, * * [start, end] is inclusive This takes the tree lock. */ -static int __set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, +static int __set_extent_bit(struct extent_io_tree *tree, const char *func, u64 start, u64 end, u32 bits, u64 *failed_start, struct extent_state **failed_state, struct extent_state **cached_state, @@ -981,7 +981,7 @@ static int __set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, u32 exclusive_bits = (bits & EXTENT_LOCKED); btrfs_debug_check_extent_io_range(tree, start, end); - trace_btrfs_set_extent_bit(tree, start, end - start + 1, bits); + trace_btrfs_set_extent_bit(tree, func, start, end - start + 1, bits); if (exclusive_bits) ASSERT(failed_start); @@ -1188,10 +1188,10 @@ static int __set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, } -int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, +int set_extent_bit(struct extent_io_tree *tree, const char *func, u64 start, u64 end, u32 bits, struct extent_state **cached_state, gfp_t mask) { - return __set_extent_bit(tree, start, end, bits, NULL, NULL, + return __set_extent_bit(tree, func, start, end, bits, NULL, NULL, cached_state, NULL, mask); } @@ -1688,7 +1688,7 @@ int set_record_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, */ ASSERT(!(bits & EXTENT_LOCKED)); - return __set_extent_bit(tree, start, end, bits, NULL, NULL, NULL, + return __set_extent_bit(tree, NULL, start, end, bits, NULL, NULL, NULL, changeset, GFP_NOFS); } @@ -1701,19 +1701,20 @@ int clear_record_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, */ ASSERT(!(bits & EXTENT_LOCKED)); - return __clear_extent_bit(tree, start, end, bits, NULL, GFP_NOFS, + return __clear_extent_bit(tree, __func__, start, end, bits, NULL, GFP_NOFS, changeset); } -int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end, +int __try_lock_extent(struct extent_io_tree *tree, const char *func, u64 start, u64 end, struct extent_state **cached) { int err; u64 failed_start; WARN_ON(start > end); - err = __set_extent_bit(tree, start, end, EXTENT_LOCKED, &failed_start, + err = __set_extent_bit(tree, func, start, end, EXTENT_LOCKED, &failed_start, NULL, cached, NULL, GFP_NOFS); + if (err == -EEXIST) { if (failed_start > start) clear_extent_bit(tree, start, failed_start - 1, @@ -1727,7 +1728,7 @@ int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end, * Either insert or lock state struct between start and end use mask to tell * us if waiting is desired. */ -int lock_extent(struct extent_io_tree *tree, u64 start, u64 end, +int __lock_extent(struct extent_io_tree *tree, const char *func, u64 start, u64 end, struct extent_state **cached_state) { struct extent_state *failed_state = NULL; @@ -1735,7 +1736,7 @@ int lock_extent(struct extent_io_tree *tree, u64 start, u64 end, u64 failed_start; WARN_ON(start > end); - err = __set_extent_bit(tree, start, end, EXTENT_LOCKED, &failed_start, + err = __set_extent_bit(tree, func, start, end, EXTENT_LOCKED, &failed_start, &failed_state, cached_state, NULL, GFP_NOFS); while (err == -EEXIST) { if (failed_start != start) @@ -1744,7 +1745,7 @@ int lock_extent(struct extent_io_tree *tree, u64 start, u64 end, wait_extent_bit(tree, failed_start, end, EXTENT_LOCKED, &failed_state); - err = __set_extent_bit(tree, start, end, EXTENT_LOCKED, + err = __set_extent_bit(tree, func, start, end, EXTENT_LOCKED, &failed_start, &failed_state, cached_state, NULL, GFP_NOFS); } diff --git a/fs/btrfs/extent-io-tree.h b/fs/btrfs/extent-io-tree.h index 21766e49ec02..2ad38b43baaf 100644 --- a/fs/btrfs/extent-io-tree.h +++ b/fs/btrfs/extent-io-tree.h @@ -107,12 +107,15 @@ void extent_io_tree_init(struct btrfs_fs_info *fs_info, struct extent_io_tree *tree, unsigned int owner); void extent_io_tree_release(struct extent_io_tree *tree); -int lock_extent(struct extent_io_tree *tree, u64 start, u64 end, +int __lock_extent(struct extent_io_tree *tree, const char *func, u64 start, u64 end, struct extent_state **cached); -int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end, +int __try_lock_extent(struct extent_io_tree *tree, const char *func, u64 start, u64 end, struct extent_state **cached); +#define lock_extent(t, s, e, c) __lock_extent(t, __func__, s, e, c) +#define try_lock_extent(t, s, e, c) __try_lock_extent(t, __func__, s, e, c) + int __init extent_state_init_cachep(void); void __cold extent_state_free_cachep(void); @@ -126,25 +129,30 @@ int test_range_bit(struct extent_io_tree *tree, u64 start, u64 end, u32 bits, int filled, struct extent_state *cached_state); int clear_record_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, u32 bits, struct extent_changeset *changeset); -int __clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, +int __clear_extent_bit(struct extent_io_tree *tree, const char *func, u64 start, u64 end, u32 bits, struct extent_state **cached, gfp_t mask, struct extent_changeset *changeset); -static inline int clear_extent_bit(struct extent_io_tree *tree, u64 start, - u64 end, u32 bits, - struct extent_state **cached) +#define clear_extent_bit(t, s, e, b, c) __clear_extent_bit(t, __func__, s, e, b, c, GFP_NOFS, NULL) + +static inline int __unlock_extent(struct extent_io_tree *tree, const char *func, u64 start, u64 end, + struct extent_state **cached) { - return __clear_extent_bit(tree, start, end, bits, cached, + return __clear_extent_bit(tree, func, start, end, EXTENT_LOCKED, cached, GFP_NOFS, NULL); } -static inline int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end, - struct extent_state **cached) +static inline int __unlock_extent_atomic(struct extent_io_tree *tree, const char *func, u64 start, + u64 end, struct extent_state **cached) { - return __clear_extent_bit(tree, start, end, EXTENT_LOCKED, cached, - GFP_NOFS, NULL); + return __clear_extent_bit(tree, func, start, end, EXTENT_LOCKED, cached, + GFP_ATOMIC, NULL); } +#define unlock_extent(t, s, e, c) __unlock_extent(t, __func__, s, e, c) +#define unlock_extent_atomic(t, s, e, c) __unlock_extent_atomic(t, __func__, s, e, c) + + static inline int clear_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, u32 bits) { @@ -153,32 +161,32 @@ static inline int clear_extent_bits(struct extent_io_tree *tree, u64 start, int set_record_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, u32 bits, struct extent_changeset *changeset); -int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, +int set_extent_bit(struct extent_io_tree *tree, const char *func, u64 start, u64 end, u32 bits, struct extent_state **cached_state, gfp_t mask); static inline int set_extent_bits_nowait(struct extent_io_tree *tree, u64 start, u64 end, u32 bits) { - return set_extent_bit(tree, start, end, bits, NULL, GFP_NOWAIT); + return set_extent_bit(tree, __func__, start, end, bits, NULL, GFP_NOWAIT); } static inline int set_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, u32 bits) { - return set_extent_bit(tree, start, end, bits, NULL, GFP_NOFS); + return set_extent_bit(tree, __func__, start, end, bits, NULL, GFP_NOFS); } static inline int clear_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end, struct extent_state **cached_state) { - return __clear_extent_bit(tree, start, end, EXTENT_UPTODATE, + return __clear_extent_bit(tree, __func__, start, end, EXTENT_UPTODATE, cached_state, GFP_NOFS, NULL); } static inline int set_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask) { - return set_extent_bit(tree, start, end, EXTENT_DIRTY, NULL, mask); + return set_extent_bit(tree, __func__, start, end, EXTENT_DIRTY, NULL, mask); } static inline int clear_extent_dirty(struct extent_io_tree *tree, u64 start, @@ -197,7 +205,7 @@ static inline int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end, u32 extra_bits, struct extent_state **cached_state) { - return set_extent_bit(tree, start, end, + return set_extent_bit(tree, __func__, start, end, EXTENT_DELALLOC | extra_bits, cached_state, GFP_NOFS); } @@ -205,7 +213,7 @@ static inline int set_extent_delalloc(struct extent_io_tree *tree, u64 start, static inline int set_extent_defrag(struct extent_io_tree *tree, u64 start, u64 end, struct extent_state **cached_state) { - return set_extent_bit(tree, start, end, + return set_extent_bit(tree, __func__, start, end, EXTENT_DELALLOC | EXTENT_DEFRAG, cached_state, GFP_NOFS); } @@ -213,7 +221,7 @@ static inline int set_extent_defrag(struct extent_io_tree *tree, u64 start, static inline int set_extent_new(struct extent_io_tree *tree, u64 start, u64 end) { - return set_extent_bit(tree, start, end, EXTENT_NEW, NULL, GFP_NOFS); + return set_extent_bit(tree, __func__, start, end, EXTENT_NEW, NULL, GFP_NOFS); } int find_first_extent_bit(struct extent_io_tree *tree, u64 start, diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 12aa7eaf12c5..fa2fedc9577f 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -2772,7 +2772,7 @@ static int try_release_extent_state(struct extent_io_tree *tree, * The delalloc new bit will be cleared by ordered extent * completion. */ - ret = __clear_extent_bit(tree, start, end, clear_bits, NULL, + ret = __clear_extent_bit(tree, __func__, start, end, clear_bits, NULL, mask, NULL); /* if clear_extent_bit failed for enomem reasons, diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index be94030e1dfb..d255d31130db 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -379,7 +379,7 @@ static void extent_map_device_clear_bits(struct extent_map *em, unsigned bits) struct btrfs_io_stripe *stripe = &map->stripes[i]; struct btrfs_device *device = stripe->dev; - __clear_extent_bit(&device->alloc_state, stripe->physical, + __clear_extent_bit(&device->alloc_state, __func__, stripe->physical, stripe->physical + stripe_size - 1, bits, NULL, GFP_NOWAIT, NULL); } diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index b5f5c1896dbb..eebced86bd70 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2663,7 +2663,7 @@ static int btrfs_find_new_delalloc_bytes(struct btrfs_inode *inode, if (em_len > search_len) em_len = search_len; - ret = set_extent_bit(&inode->io_tree, search_start, + ret = set_extent_bit(&inode->io_tree, __func__, search_start, search_start + em_len - 1, EXTENT_DELALLOC_NEW, cached_state, GFP_NOFS); @@ -4779,7 +4779,7 @@ int btrfs_truncate_block(struct btrfs_inode *inode, loff_t from, loff_t len, btrfs_page_set_dirty(fs_info, page, block_start, block_end + 1 - block_start); if (only_release_metadata) - set_extent_bit(&inode->io_tree, block_start, block_end, + set_extent_bit(&inode->io_tree, __func__, block_start, block_end, EXTENT_NORESERVE, NULL, GFP_NOFS); out_unlock: diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 6c24b69e2d0a..9854494d3bcf 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -231,8 +231,8 @@ int btrfs_add_ordered_extent(struct btrfs_inode *inode, u64 file_offset, &entry->rb_node); if (node) btrfs_panic(fs_info, -EEXIST, - "inconsistency in ordered tree at offset %llu", - file_offset); + "inconsistency in ordered tree ino %lu at offset %llu", + inode->vfs_inode.i_ino, file_offset); spin_unlock_irq(&tree->lock); spin_lock(&root->ordered_extent_lock); @@ -1032,7 +1032,7 @@ struct btrfs_ordered_extent *btrfs_lookup_first_ordered_range( * Always return with the given range locked, ensuring after it's called no * order extent can be pending. */ -void btrfs_lock_and_flush_ordered_range(struct btrfs_inode *inode, u64 start, +void __btrfs_lock_and_flush_ordered_range(struct btrfs_inode *inode, const char *func, u64 start, u64 end, struct extent_state **cached_state) { @@ -1044,7 +1044,7 @@ void btrfs_lock_and_flush_ordered_range(struct btrfs_inode *inode, u64 start, cachedp = cached_state; while (1) { - lock_extent(&inode->io_tree, start, end, cachedp); + __lock_extent(&inode->io_tree, func, start, end, cachedp); ordered = btrfs_lookup_ordered_range(inode, start, end - start + 1); if (!ordered) { diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h index eb40cb39f842..e426aeda71d5 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h @@ -202,9 +202,10 @@ u64 btrfs_wait_ordered_extents(struct btrfs_root *root, u64 nr, const u64 range_start, const u64 range_len); void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, u64 nr, const u64 range_start, const u64 range_len); -void btrfs_lock_and_flush_ordered_range(struct btrfs_inode *inode, u64 start, +void __btrfs_lock_and_flush_ordered_range(struct btrfs_inode *inode, const char *func, u64 start, u64 end, struct extent_state **cached_state); +#define btrfs_lock_and_flush_ordered_range(i, s, e, c) __btrfs_lock_and_flush_ordered_range(i, __func__, s, e, c) bool btrfs_try_lock_ordered_range(struct btrfs_inode *inode, u64 start, u64 end, struct extent_state **cached_state); int btrfs_split_ordered_extent(struct btrfs_ordered_extent *ordered, u64 pre, diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h index 8ea9cea9bfeb..d4f4a415d085 100644 --- a/include/trace/events/btrfs.h +++ b/include/trace/events/btrfs.h @@ -2059,12 +2059,14 @@ DEFINE_EVENT(btrfs__block_group, btrfs_skip_unused_block_group, TRACE_EVENT(btrfs_set_extent_bit, TP_PROTO(const struct extent_io_tree *tree, + const char *func, u64 start, u64 len, unsigned set_bits), - TP_ARGS(tree, start, len, set_bits), + TP_ARGS(tree, func, start, len, set_bits), TP_STRUCT__entry_btrfs( __field( unsigned, owner ) + __string( func, func ) __field( u64, ino ) __field( u64, rootid ) __field( u64, start ) @@ -2083,26 +2085,29 @@ TRACE_EVENT(btrfs_set_extent_bit, __entry->ino = 0; __entry->rootid = 0; } + __assign_str(func, func); __entry->start = start; __entry->len = len; __entry->set_bits = set_bits; ), TP_printk_btrfs( - "io_tree=%s ino=%llu root=%llu start=%llu len=%llu set_bits=%s", - __print_symbolic(__entry->owner, IO_TREE_OWNER), __entry->ino, + "io_tree=%s func=%s ino=%llu root=%llu start=%llu len=%llu set_bits=%s", + __print_symbolic(__entry->owner, IO_TREE_OWNER), __get_str(func), __entry->ino, __entry->rootid, __entry->start, __entry->len, __print_flags(__entry->set_bits, "|", EXTENT_FLAGS)) ); TRACE_EVENT(btrfs_clear_extent_bit, TP_PROTO(const struct extent_io_tree *tree, + const char *func, u64 start, u64 len, unsigned clear_bits), - TP_ARGS(tree, start, len, clear_bits), + TP_ARGS(tree, func, start, len, clear_bits), TP_STRUCT__entry_btrfs( __field( unsigned, owner ) + __string( func, func ) __field( u64, ino ) __field( u64, rootid ) __field( u64, start ) @@ -2121,14 +2126,15 @@ TRACE_EVENT(btrfs_clear_extent_bit, __entry->ino = 0; __entry->rootid = 0; } + __assign_str(func, func) __entry->start = start; __entry->len = len; __entry->clear_bits = clear_bits; ), TP_printk_btrfs( - "io_tree=%s ino=%llu root=%llu start=%llu len=%llu clear_bits=%s", - __print_symbolic(__entry->owner, IO_TREE_OWNER), __entry->ino, + "io_tree=%s func=%s ino=%llu root=%llu start=%llu len=%llu clear_bits=%s", + __print_symbolic(__entry->owner, IO_TREE_OWNER), __get_str(func), __entry->ino, __entry->rootid, __entry->start, __entry->len, __print_flags(__entry->clear_bits, "|", EXTENT_FLAGS)) );