From nobody Sat Feb 7 16:39:21 2026 Received: from out-177.mta1.migadu.com (out-177.mta1.migadu.com [95.215.58.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 704D621A459 for ; Fri, 7 Mar 2025 13:49:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741355386; cv=none; b=Vh07C1Z/qsXHbbrXX61mKqtoI5CdDbq3j5OoTghY6cZpTEpvZTWylPQ4bTpS+sPg+PVavKlesstnijpBaL0lERhcdv+lXYrbOguMK/1pBO7pOHBgVTwx+kLK99x5IAqaisTa1wq/eBVi5jKJ6DW7mtmVX7+B1G9N8aOiEpALnzg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741355386; c=relaxed/simple; bh=iqUZqMNZwCs/gqnoYp7jDJzINAsGqfxLoyvMoVunZo0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ktFV0IfOxrBqUel9tEWfVOOM0kDRm+aYb0nSBjmH6HcBeOuActK+vOXUCvCdf42/LtsUofB44Iiv18GnDdcg0q8pDc0kDszPkM7viXpMWQdD028HYbk714NfHNySwy2FvtZJ3bjFTnejA36bptJhwyUMntCLmfD6ZAs66N7iEhQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=FlwrBN6U; arc=none smtp.client-ip=95.215.58.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="FlwrBN6U" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1741355381; h=from:from:reply-to:subject:subject: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=AksTGtuR6KF8fONDLpLWWigfgzOmf10rgW9ti3SLMsM=; b=FlwrBN6UGcsnS6kJUccauG85YURzDDC9h7rg54vbqr91eMBIim7TtTTybqym9iAMY3rBRS SUo6cquTCarWdbRbwjvZxFF4shO1gJzhZf70OtP/cSVu363HsSBPjIvy6JQHS5ODj9gGoB bR0qot/hFPXXak/Zc+oZfC05NzDLDYU= From: Kent Overstreet To: linux-bcachefs@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Kent Overstreet , Alexander Viro , Christian Brauner , Jan Kara Subject: [PATCH 1/7] fs: export invalidate_inodes() Date: Fri, 7 Mar 2025 08:49:25 -0500 Message-ID: <20250307134933.1033872-2-kent.overstreet@linux.dev> In-Reply-To: <20250307134933.1033872-1-kent.overstreet@linux.dev> References: <20250307134933.1033872-1-kent.overstreet@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Needed in bcachefs for implementing blk_holder_ops.mark_dead, since we can't use the standard fs holder ops (whicth assume a single block device filesystem). Cc: Alexander Viro Cc: Christian Brauner Cc: Jan Kara Signed-off-by: Kent Overstreet --- fs/inode.c | 1 + fs/internal.h | 1 - include/linux/fs.h | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/inode.c b/fs/inode.c index 5587aabdaa5e..6364779a7006 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -939,6 +939,7 @@ void invalidate_inodes(struct super_block *sb) =20 dispose_list(&dispose); } +EXPORT_SYMBOL_GPL(invalidate_inodes); =20 /* * Isolate the inode from the LRU in preparation for freeing it. diff --git a/fs/internal.h b/fs/internal.h index e7f02ae1e098..7cb515cede3f 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -207,7 +207,6 @@ bool in_group_or_capable(struct mnt_idmap *idmap, * fs-writeback.c */ extern long get_nr_dirty_inodes(void); -void invalidate_inodes(struct super_block *sb); =20 /* * dcache.c diff --git a/include/linux/fs.h b/include/linux/fs.h index be3ad155ec9f..5196317598ac 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3251,6 +3251,7 @@ extern void unlock_new_inode(struct inode *); extern void discard_new_inode(struct inode *); extern unsigned int get_next_ino(void); extern void evict_inodes(struct super_block *sb); +extern void invalidate_inodes(struct super_block *sb); void dump_mapping(const struct address_space *); =20 /* --=20 2.47.2 From nobody Sat Feb 7 16:39:21 2026 Received: from out-171.mta1.migadu.com (out-171.mta1.migadu.com [95.215.58.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 100352770B for ; Fri, 7 Mar 2025 13:49:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741355386; cv=none; b=MLmkDiHtEyXSpQrKx1mE7oq/V2IgERGgt1XStvMMbK2tuXub5kAZjt7EA22G6+KlmN2BaEuJwANfpsIMfo06g+wrP4tPeXk1a99H+pnVLXxqVsVUEJEC//n5WFeEENUtwwqTgH0JLRkLg6FwcpTSzFUcdG7ncPsMB9AIWS5TOxk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741355386; c=relaxed/simple; bh=uHfIl+XtJQaM2mwQ2nmLKVutMlRrkvXxNhGAJWUVCag=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SArfeADYHrZ5Tj4CYhJX2qebvRlnoBXwPT/QlHfM9Xnu1EmtkfSbxbi8lSAFU+OvBwsuWHUe+dx5BQsVQdw8911ZLXBYiU6N0XO1kmVhcq7AC+rDecJfNvv6n+sWtLbN4TrlcW3voFj1974Peg8WBE1cpNS85GeehIINdqTwIVk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=O1eVYFfU; arc=none smtp.client-ip=95.215.58.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="O1eVYFfU" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1741355382; h=from:from:reply-to:subject:subject: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=c535oA3Yx9kl5Xew9DyL4TIYFQS0wpeyp4RaMoxr9dc=; b=O1eVYFfUHOolbCOF8mXDENoV4syM6fmyl3g9K4cjZrhhOpa7ss/5x6CAWppBusrU8jeDmD 8u5FHO+ESj+Z3uhoc8wqIeKhqHyboEo4AJuj8ups6syh9owif8VWYunlYXs3Zw7e9nIHIi gHMUvNGpMrsIuD/7HLXD3GngkU3WRv0= From: Kent Overstreet To: linux-bcachefs@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Kent Overstreet Subject: [PATCH 2/7] bcachefs: Stash a pointer to the filesystem for blk_holder_ops Date: Fri, 7 Mar 2025 08:49:26 -0500 Message-ID: <20250307134933.1033872-3-kent.overstreet@linux.dev> In-Reply-To: <20250307134933.1033872-1-kent.overstreet@linux.dev> References: <20250307134933.1033872-1-kent.overstreet@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Note that we open block devices before we allocate bch_fs, but once attached to a filesystem they will be closed before the bch_fs is torn down - so stashing a pointer without a refcount looks incorrect but it's not. Signed-off-by: Kent Overstreet --- fs/bcachefs/super-io.c | 2 +- fs/bcachefs/super.c | 7 +++++++ fs/bcachefs/super_types.h | 8 +++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c index 28724aee2c09..bd24b4f7eeb6 100644 --- a/fs/bcachefs/super-io.c +++ b/fs/bcachefs/super-io.c @@ -748,7 +748,7 @@ static int __bch2_read_super(const char *path, struct b= ch_opts *opts, memset(sb, 0, sizeof(*sb)); sb->mode =3D BLK_OPEN_READ; sb->have_bio =3D true; - sb->holder =3D kmalloc(1, GFP_KERNEL); + sb->holder =3D kzalloc(sizeof(*sb->holder), GFP_KERNEL); if (!sb->holder) return -ENOMEM; =20 diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index 10c281ad96eb..b653dd480591 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -1431,6 +1431,13 @@ static int __bch2_dev_attach_bdev(struct bch_dev *ca= , struct bch_sb_handle *sb) ca->disk_sb =3D *sb; memset(sb, 0, sizeof(*sb)); =20 + /* + * Stash pointer to the filesystem for blk_holder_ops - note that once + * attached to a filesystem, we will always close the block device + * before tearing down the filesystem object. + */ + ca->disk_sb.holder->c =3D ca->fs; + ca->dev =3D ca->disk_sb.bdev->bd_dev; =20 percpu_ref_reinit(&ca->io_ref); diff --git a/fs/bcachefs/super_types.h b/fs/bcachefs/super_types.h index 368a63d938cf..3a899f799d1d 100644 --- a/fs/bcachefs/super_types.h +++ b/fs/bcachefs/super_types.h @@ -2,13 +2,19 @@ #ifndef _BCACHEFS_SUPER_TYPES_H #define _BCACHEFS_SUPER_TYPES_H =20 +struct bch_fs; + +struct bch_sb_handle_holder { + struct bch_fs *c; +}; + struct bch_sb_handle { struct bch_sb *sb; struct file *s_bdev_file; struct block_device *bdev; char *sb_name; struct bio *bio; - void *holder; + struct bch_sb_handle_holder *holder; size_t buffer_size; blk_mode_t mode; unsigned have_layout:1; --=20 2.47.2 From nobody Sat Feb 7 16:39:21 2026 Received: from out-179.mta1.migadu.com (out-179.mta1.migadu.com [95.215.58.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C424121ABC3 for ; Fri, 7 Mar 2025 13:49:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741355387; cv=none; b=ZuU1MIM+DKRLRPp04WZjV8aslQDT8kalJNryl8MpSQ0ju9JkEXrLHe1Es0zukBybFtaxAbghcZKwFDe20y31WaPkGh6AsOJao7kPYOmIn8lkkIn9ItFoh5H+kgV6AMdUbipe3iIDbAb5mRaMCbKJ2YEH7VW17hXxeh51QxsbmKY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741355387; c=relaxed/simple; bh=6/9dePklkamGE2mIb0m9BJD4GTgSdC+9+BIK/NkFMw4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=o51LO/pkWiHbfafg25giRd+WqbF8RnaXRgD0MSezSxROG+HIHgqone8Zq3nLqs8eugROUubAj4Fzu/gZYbH9uXRiuN4Fj1otj4BuYQwf6xIFa/1PtxYBgENqrnRlmT4A4kp1dGWY3zPV/oP7JFkL8TItsF9lcEfXZuVWU296OAI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=PcEi05Wk; arc=none smtp.client-ip=95.215.58.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="PcEi05Wk" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1741355382; h=from:from:reply-to:subject:subject: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=DdISwa6vH5Zc+6gigrn+eRpFYfzF0XduhqRKofHcLvo=; b=PcEi05Wkd5VwVMLybQnLfJe8dPQDxc5/fAEeBjcFpP5lMz0eu9fY7Z5FnBHaaQAHZM6RX5 8pBtz3kxUZK4jnYM3hmtMz4cK5WqYmLib0v97a0oZaBvw95lT7AxhkaoxKFdbMQehKbd9Z RC1YbZsILToDhHH24N/QD1qDykHcb/s= From: Kent Overstreet To: linux-bcachefs@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Kent Overstreet Subject: [PATCH 3/7] bcachefs: Make sure c->vfs_sb is set before starting fs Date: Fri, 7 Mar 2025 08:49:27 -0500 Message-ID: <20250307134933.1033872-4-kent.overstreet@linux.dev> In-Reply-To: <20250307134933.1033872-1-kent.overstreet@linux.dev> References: <20250307134933.1033872-1-kent.overstreet@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" This is necessary for the new blk_holder_ops, which want the vfs super_block available for synchronization. Signed-off-by: Kent Overstreet --- fs/bcachefs/fs.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c index 2c011a465588..459ca8259fc0 100644 --- a/fs/bcachefs/fs.c +++ b/fs/bcachefs/fs.c @@ -2218,9 +2218,10 @@ static int bch2_fs_get_tree(struct fs_context *fc) =20 bch2_opts_apply(&c->opts, opts); =20 - ret =3D bch2_fs_start(c); - if (ret) - goto err_stop_fs; + /* + * need to initialise sb and set c->vfs_sb _before_ starting fs, + * for blk_holder_ops + */ =20 sb =3D sget(fc->fs_type, NULL, bch2_set_super, fc->sb_flags|SB_NOSEC, c); ret =3D PTR_ERR_OR_ZERO(sb); @@ -2282,6 +2283,10 @@ static int bch2_fs_get_tree(struct fs_context *fc) =20 sb->s_shrink->seeks =3D 0; =20 + ret =3D bch2_fs_start(c); + if (ret) + goto err_put_super; + vinode =3D bch2_vfs_inode_get(c, BCACHEFS_ROOT_SUBVOL_INUM); ret =3D PTR_ERR_OR_ZERO(vinode); bch_err_msg(c, ret, "mounting: error getting root inode"); --=20 2.47.2 From nobody Sat Feb 7 16:39:21 2026 Received: from out-180.mta1.migadu.com (out-180.mta1.migadu.com [95.215.58.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6C1AE219A81 for ; Fri, 7 Mar 2025 13:49:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741355387; cv=none; b=tjjAMMq5fNIxpWpTZzNp4n3+YC9dNWfQtAc+iQRBw4gFHXe+C9EeceBoIvXoD5y08yEd3hovxSp0rur7D6QGb2mZ8uoRZppXDZwgMH1BP1bdog2I+Z0OY5RN+mLiMxX3yBq1v66/jTtK0m8Ee3ZBwCaFnt6klhB2pjPh9oMdlq0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741355387; c=relaxed/simple; bh=zh5le6Hk0IC6liNliAEcDtVoAZPfkDLXdIbmjjiPhiY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QjMIOsppuUcxcGiIS/QJ6tRpqL/jIFxXiQmjxkgrWOcOPT2o+IBMpgaFNZdRkUNkx5CzptVNqAzgL/lsOWsbRJ9TxpjhrrA27/giFbMfK2F1pvQagE/klCoBpkuIYJb9FqstGoUFSpUyLw5Pd7EXIyTIvyf3qG2A5iOlKO6uqaw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=ICcPpJyL; arc=none smtp.client-ip=95.215.58.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="ICcPpJyL" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1741355383; h=from:from:reply-to:subject:subject: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=NwljdDtq7nkUuYkVfOdGvy8BRX+vk42k62VOJkp6OfU=; b=ICcPpJyL7CNsC6grbF3ZtzCtam4+ngOXzLOhrn6CkV0df0Y1ISMeSsjwYsfTufc6ililWb g9IbPF6hF+5wmLoBaWLYSDW/RGAzGtNvx8K8sOs22iS47T0xoqjvJxH32tnpmVhfklfS7Z tPqAwGF6xo3UAW5PTaWmjL5mmCmOWZ0= From: Kent Overstreet To: linux-bcachefs@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Kent Overstreet Subject: [PATCH 4/7] bcachefs: Implement blk_holder_ops Date: Fri, 7 Mar 2025 08:49:28 -0500 Message-ID: <20250307134933.1033872-5-kent.overstreet@linux.dev> In-Reply-To: <20250307134933.1033872-1-kent.overstreet@linux.dev> References: <20250307134933.1033872-1-kent.overstreet@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" We can't use the standard fs_holder_ops because they're meant for single device filesystems - fs_bdev_mark_dead() in particular - and they assume that the blk_holder is the super_block, which also doesn't work for a multi device filesystem. These generally follow the standard fs_holder_ops; the locking/refcounting is a bit simplified because c->ro_ref suffices, and bch2_fs_bdev_mark_dead() is not necessarily shutting down the entire filesystem. Signed-off-by: Kent Overstreet --- fs/bcachefs/super-io.c | 3 -- fs/bcachefs/super.c | 97 ++++++++++++++++++++++++++++++++++++++++++ fs/bcachefs/super.h | 2 + 3 files changed, 99 insertions(+), 3 deletions(-) diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c index bd24b4f7eeb6..dcb69c72555e 100644 --- a/fs/bcachefs/super-io.c +++ b/fs/bcachefs/super-io.c @@ -25,9 +25,6 @@ #include #include =20 -static const struct blk_holder_ops bch2_sb_handle_bdev_ops =3D { -}; - struct bch2_metadata_version { u16 version; const char *name; diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index b653dd480591..05a2dc5ef513 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -1075,6 +1075,7 @@ int bch2_fs_start(struct bch_fs *c) } =20 set_bit(BCH_FS_started, &c->flags); + wake_up(&c->ro_ref_wait); =20 if (c->opts.read_only) { bch2_fs_read_only(c); @@ -2023,6 +2024,102 @@ struct bch_dev *bch2_dev_lookup(struct bch_fs *c, c= onst char *name) return ERR_PTR(-BCH_ERR_ENOENT_dev_not_found); } =20 +/* blk_holder_ops: */ + +static struct bch_fs *bdev_get_fs(struct block_device *bdev) + __releases(&bdev->bd_holder_lock) +{ + struct bch_sb_handle_holder *holder =3D bdev->bd_holder; + struct bch_fs *c =3D holder->c; + + if (c && !bch2_ro_ref_tryget(c)) + c =3D NULL; + + mutex_unlock(&bdev->bd_holder_lock); + + if (c) + wait_event(c->ro_ref_wait, test_bit(BCH_FS_started, &c->flags)); + return c; +} + +/* returns with ref on ca->ref */ +static struct bch_dev *bdev_to_bch_dev(struct bch_fs *c, struct block_devi= ce *bdev) +{ + for_each_member_device(c, ca) + if (ca->disk_sb.bdev =3D=3D bdev) + return ca; + return NULL; +} + +static void bch2_fs_bdev_mark_dead(struct block_device *bdev, bool surpris= e) +{ + struct bch_fs *c =3D bdev_get_fs(bdev); + if (!c) + return; + + struct super_block *sb =3D c->vfs_sb; + if (sb) { + /* + * Not necessary, c->ro_ref guards against the filesystem being + * unmounted - we only take this to avoid a warning in + * sync_filesystem: + */ + down_read(&sb->s_umount); + } + + down_write(&c->state_lock); + struct bch_dev *ca =3D bdev_to_bch_dev(c, bdev); + if (!ca) + goto unlock; + + if (bch2_dev_state_allowed(c, ca, BCH_MEMBER_STATE_failed, BCH_FORCE_IF_D= EGRADED)) { + __bch2_dev_offline(c, ca); + } else { + if (sb) { + if (!surprise) + sync_filesystem(sb); + shrink_dcache_sb(sb); + invalidate_inodes(sb); + } + + bch2_journal_flush(&c->journal); + bch2_fs_emergency_read_only(c); + } + + bch2_dev_put(ca); +unlock: + if (sb) + up_read(&sb->s_umount); + up_write(&c->state_lock); + bch2_ro_ref_put(c); +} + +static void bch2_fs_bdev_sync(struct block_device *bdev) +{ + struct bch_fs *c =3D bdev_get_fs(bdev); + if (!c) + return; + + struct super_block *sb =3D c->vfs_sb; + if (sb) { + /* + * Not necessary, c->ro_ref guards against the filesystem being + * unmounted - we only take this to avoid a warning in + * sync_filesystem: + */ + down_read(&sb->s_umount); + sync_filesystem(sb); + up_read(&sb->s_umount); + } + + bch2_ro_ref_put(c); +} + +const struct blk_holder_ops bch2_sb_handle_bdev_ops =3D { + .mark_dead =3D bch2_fs_bdev_mark_dead, + .sync =3D bch2_fs_bdev_sync, +}; + /* Filesystem open: */ =20 static inline int sb_cmp(struct bch_sb *l, struct bch_sb *r) diff --git a/fs/bcachefs/super.h b/fs/bcachefs/super.h index 04f8287eff5c..23533bce5709 100644 --- a/fs/bcachefs/super.h +++ b/fs/bcachefs/super.h @@ -42,4 +42,6 @@ void bch2_fs_stop(struct bch_fs *); int bch2_fs_start(struct bch_fs *); struct bch_fs *bch2_fs_open(char * const *, unsigned, struct bch_opts); =20 +extern const struct blk_holder_ops bch2_sb_handle_bdev_ops; + #endif /* _BCACHEFS_SUPER_H */ --=20 2.47.2 From nobody Sat Feb 7 16:39:21 2026 Received: from out-174.mta1.migadu.com (out-174.mta1.migadu.com [95.215.58.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 76ABC21A457 for ; Fri, 7 Mar 2025 13:49:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741355388; cv=none; b=uM4//2bHUTHJGINahLXrypSOPffcNFvE3T41oCGpLPMARERPWUTtbrPAmYFN7CJ3hO2lz47ZkLh44jn4wi80N0Md9LPORExk/FjkMBSKWWf5urY9TGaM8IP35iHxabDAZ4H+WUFuLnsvm4FcVLO7oPzUpmXmeNu/XgR55EHHQiE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741355388; c=relaxed/simple; bh=InaRiDUojOac4guj1Yr+eepxCQXdYBLxgKV1QnPhPGc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FLRfB830pziYqlTnWh8cJ2ZjtK8tuS1xj4Bxix3wuvKr2Hdc6tWk5SBIPB3D61EN/4boPy6Fu32dByD9+Kuebi3iLxcLj89EWIiYqaI6OQAj+UOYY9zYLTFxbW3IdkEM/iqrenM7hEshI4hVRrTMvugmOoXp/uRTI+CiDMW4zAI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=laysMbSC; arc=none smtp.client-ip=95.215.58.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="laysMbSC" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1741355384; h=from:from:reply-to:subject:subject: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=HQZ/tKmcgdmcTNJfV9yVK+/0PpX1kq2uk26+/6rks2M=; b=laysMbSCva2OK953UNbnga084ukzXwuxisGIjtVp3dmqH+TIHS/mjh6ANu1R4TeOr8zA1f Ao2KFIXRt0DcjXPkUZudAAjYjXzu2TEnPu57ugqgOfP1jgqioV5LisMf1hcohoHC1Gy4ac Q93rEAOtiHSJNXqwGiBzvmjUkiioeew= From: Kent Overstreet To: linux-bcachefs@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Kent Overstreet Subject: [PATCH 5/7] bcachefs: Fix btree_node_scan io_ref handling Date: Fri, 7 Mar 2025 08:49:29 -0500 Message-ID: <20250307134933.1033872-6-kent.overstreet@linux.dev> In-Reply-To: <20250307134933.1033872-1-kent.overstreet@linux.dev> References: <20250307134933.1033872-1-kent.overstreet@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" This was completely fubar; it's now simplified a bit as well. Note that for_each_online_member() takes and releases io_refs as it iterates, so we need to release that if we break. Signed-off-by: Kent Overstreet --- fs/bcachefs/btree_node_scan.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/fs/bcachefs/btree_node_scan.c b/fs/bcachefs/btree_node_scan.c index fb73ec77c099..678161321e42 100644 --- a/fs/bcachefs/btree_node_scan.c +++ b/fs/bcachefs/btree_node_scan.c @@ -270,7 +270,7 @@ static int read_btree_nodes_worker(void *p) err: bio_put(bio); free_page((unsigned long) buf); - percpu_ref_get(&ca->io_ref); + percpu_ref_put(&ca->io_ref); closure_put(w->cl); kfree(w); return 0; @@ -289,29 +289,28 @@ static int read_btree_nodes(struct find_btree_nodes *= f) continue; =20 struct find_btree_nodes_worker *w =3D kmalloc(sizeof(*w), GFP_KERNEL); - struct task_struct *t; - if (!w) { percpu_ref_put(&ca->io_ref); ret =3D -ENOMEM; goto err; } =20 - percpu_ref_get(&ca->io_ref); - closure_get(&cl); w->cl =3D &cl; w->f =3D f; w->ca =3D ca; =20 - t =3D kthread_run(read_btree_nodes_worker, w, "read_btree_nodes/%s", ca-= >name); + struct task_struct *t =3D kthread_create(read_btree_nodes_worker, w, "re= ad_btree_nodes/%s", ca->name); ret =3D PTR_ERR_OR_ZERO(t); if (ret) { percpu_ref_put(&ca->io_ref); - closure_put(&cl); - f->ret =3D ret; - bch_err(c, "error starting kthread: %i", ret); + kfree(w); + bch_err_msg(c, ret, "starting kthread"); break; } + + closure_get(&cl); + percpu_ref_get(&ca->io_ref); + wake_up_process(t); } err: closure_sync(&cl); --=20 2.47.2 From nobody Sat Feb 7 16:39:21 2026 Received: from out-183.mta1.migadu.com (out-183.mta1.migadu.com [95.215.58.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 43DFA21ADC5 for ; Fri, 7 Mar 2025 13:49:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.183 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741355389; cv=none; b=o6T7/wTCnKCHoxKpFGvGvWVPhhLMcjVcIJCzyNONwyvjpTMb9aV2GF+PFuUes9SW8jNmYCZ1EnzWkYH3apV+XfHhi/bzVT5FjHAKr84dNioGQI9ccaryDn/bsYjuCAXCI1pUWfYo19as/mcK8Eb0OL0VFHA9T+Fx7fJiEUvByN0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741355389; c=relaxed/simple; bh=0vfisFvZWc3TDxf4KIuWvz9VwUXntUOyx5Jk2l0flEg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ujg/8chA4dNKfk5/KhM/dPmHX4qUVTkH8sBvSiBeNRHAQPZFaYLvpWlSvtLU41xmiB+QvKKtK3KxfbZQ8HvOdPLsAf6ufgsn/XjNYOELFum7DLjKjkdD53kcBzFxW87MVgaZkewt+/3R/GvENeyjMOi/7RjKM3IYnXZzO8A4vjQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=rwlOVxqD; arc=none smtp.client-ip=95.215.58.183 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="rwlOVxqD" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1741355385; h=from:from:reply-to:subject:subject: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=0ye5CJIiV8Oaaj1k0e6DO2I7TmbvLc9zR2A4Ic21USE=; b=rwlOVxqDV671pBOSsM93GOO29n2esNhmcXQc9hpku4/najYGui5glqSdppYp79fKF1mLGY q/vou2LPuDXesclL9G8On57PeuFJkKzaQKwkGbnIvfarSODaJlgUdGYuZCkvGvL0q1huBd jVhgH6HOWTBnjmLFnNotqSD/Sfgrq/U= From: Kent Overstreet To: linux-bcachefs@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Kent Overstreet Subject: [PATCH 6/7] bcachefs: bch2_dev_get_ioref() may now sleep Date: Fri, 7 Mar 2025 08:49:30 -0500 Message-ID: <20250307134933.1033872-7-kent.overstreet@linux.dev> In-Reply-To: <20250307134933.1033872-1-kent.overstreet@linux.dev> References: <20250307134933.1033872-1-kent.overstreet@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" The next patch implementing freezing will change bch2_dev_get_ioref() to sleep if a device is currently frozen. Add an annotation and fix the journal code accordingly. Signed-off-by: Kent Overstreet --- fs/bcachefs/journal_io.c | 5 ++++- fs/bcachefs/sb-members.h | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/bcachefs/journal_io.c b/fs/bcachefs/journal_io.c index c12d9f9bd536..a510755a8364 100644 --- a/fs/bcachefs/journal_io.c +++ b/fs/bcachefs/journal_io.c @@ -1664,6 +1664,7 @@ static CLOSURE_CALLBACK(journal_write_done) } =20 bool completed =3D false; + bool do_discards =3D false; =20 for (seq =3D journal_last_unwritten_seq(j); seq <=3D journal_cur_seq(j); @@ -1676,7 +1677,6 @@ static CLOSURE_CALLBACK(journal_write_done) j->flushed_seq_ondisk =3D seq; j->last_seq_ondisk =3D w->last_seq; =20 - bch2_do_discards(c); closure_wake_up(&c->freelist_wait); bch2_reset_alloc_cursors(c); } @@ -1727,6 +1727,9 @@ static CLOSURE_CALLBACK(journal_write_done) */ bch2_journal_do_writes(j); spin_unlock(&j->lock); + + if (do_discards) + bch2_do_discards(c); } =20 static void journal_write_endio(struct bio *bio) diff --git a/fs/bcachefs/sb-members.h b/fs/bcachefs/sb-members.h index b29b6c6c21dd..df91b02ce575 100644 --- a/fs/bcachefs/sb-members.h +++ b/fs/bcachefs/sb-members.h @@ -283,6 +283,8 @@ static inline struct bch_dev *bch2_dev_iterate(struct b= ch_fs *c, struct bch_dev =20 static inline struct bch_dev *bch2_dev_get_ioref(struct bch_fs *c, unsigne= d dev, int rw) { + might_sleep(); + rcu_read_lock(); struct bch_dev *ca =3D bch2_dev_rcu(c, dev); if (ca && !percpu_ref_tryget(&ca->io_ref)) --=20 2.47.2 From nobody Sat Feb 7 16:39:21 2026 Received: from out-175.mta1.migadu.com (out-175.mta1.migadu.com [95.215.58.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A914721B181 for ; Fri, 7 Mar 2025 13:49:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741355389; cv=none; b=A1wi2t3DolSeKkg+nC2uE57MTJTH3DEaeVCcTgAfrY9rLAy8W6M7wgnkTCJ5bbRyhuIBHII5rla+uNJaDBHA0VdGWyw3djgVPARf6qmlhDQwDHon6XfuyHn7isXdmMWQ8sAGmRvpLPN8otI0HfhVaNCgCgETss/p75alU3/6elg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741355389; c=relaxed/simple; bh=UwCAiAJk8a0FhYx5e7ekQxVFl3kVmc4cgPx9AGzJKPE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Zmp6dxUmdbEn7ot3zttnyCok+Df+C3X+s5vZb9MEM0pX47Q9KkXChH/H90CPRdpkYxlUHTWV/T/ohAauBFxGX3NpgbK2AjyffSVZtO8785LJy+NwQTfr+XeBN/15MDvqukC7u0g4VSwt+fyIqS+atWP66+Z+f3rTA/JKuiWnMLo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=PX/DvRpY; arc=none smtp.client-ip=95.215.58.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="PX/DvRpY" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1741355385; h=from:from:reply-to:subject:subject: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=Z6jW7sIZDKGN//InFjXTx2v/9Ue/mZirsyApk04RQs8=; b=PX/DvRpYUiIzeQ+62kUuMgo3uryTn27izG4CBJg32R6KOXH+L60uXLejbov46XD+buMob3 s1HvlAPndIUZSF/0+4J8Sm15MrTnlLGlaJlFZC+cjLXtOjpe96nav0FI75MtnIKgekeZlQ 9CbXShlQft08UM3/XhUvuHNzXcTNAEU= From: Kent Overstreet To: linux-bcachefs@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Kent Overstreet Subject: [PATCH 7/7] bcachefs: Implement freeze/thaw Date: Fri, 7 Mar 2025 08:49:31 -0500 Message-ID: <20250307134933.1033872-8-kent.overstreet@linux.dev> In-Reply-To: <20250307134933.1033872-1-kent.overstreet@linux.dev> References: <20250307134933.1033872-1-kent.overstreet@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" This fills out our blk_holders_ops with freeze and thaw callbacks, for shutting down IO (generally during a system suspend). This is implemented completely differently as on other filesystems since we have a low level synchronization object which conveniently works well for us - bch_dev.io_ref, normally used for guarding against a device being offlined while in use. bch2_dev_get_ioref() now checks if a freeze is in progress if it fails to get ca->io_ref, and sleeps until complete and ca->io_ref is alive. We also need a bit of synchronization for freeze/suspend vs. device online/offline, done with the new bch_dev.io_ref_statechange_lock. Signed-off-by: Kent Overstreet --- fs/bcachefs/bcachefs.h | 3 ++ fs/bcachefs/journal_io.c | 2 +- fs/bcachefs/sb-members.c | 49 ++++++++++++++++++++++ fs/bcachefs/sb-members.h | 20 +-------- fs/bcachefs/super.c | 87 +++++++++++++++++++++++++++++++++++++--- 5 files changed, 136 insertions(+), 25 deletions(-) diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h index d2c3f59a668f..d03aa62907ad 100644 --- a/fs/bcachefs/bcachefs.h +++ b/fs/bcachefs/bcachefs.h @@ -526,6 +526,9 @@ struct bch_dev { struct completion ref_completion; struct percpu_ref io_ref; struct completion io_ref_completion; + struct mutex io_ref_statechange_lock; + unsigned frozen; + wait_queue_head_t frozen_wait; =20 struct bch_fs *fs; =20 diff --git a/fs/bcachefs/journal_io.c b/fs/bcachefs/journal_io.c index a510755a8364..6979fef5c128 100644 --- a/fs/bcachefs/journal_io.c +++ b/fs/bcachefs/journal_io.c @@ -1769,7 +1769,7 @@ static CLOSURE_CALLBACK(journal_write_submit) struct bch_dev *ca =3D bch2_dev_get_ioref(c, ptr->dev, WRITE); if (!ca) { /* XXX: fix this */ - bch_err(c, "missing device for journal write\n"); + bch_err(c, "missing device for journal write"); continue; } =20 diff --git a/fs/bcachefs/sb-members.c b/fs/bcachefs/sb-members.c index 116131f95815..2363367cb32d 100644 --- a/fs/bcachefs/sb-members.c +++ b/fs/bcachefs/sb-members.c @@ -9,6 +9,55 @@ #include "sb-members.h" #include "super-io.h" =20 +/* + * Use of bch2_dev_get_ioref() is subject to deadlocks if used incorrectly= , and + * we cannot write asserts for correct usage, so: pay attention, because t= his is + * where we implement freeze. + * + * Waiting on an outstanding freeze to complete will indirectly wait on all + * other outstanding io_refs to be released. That means: + * + * - Don't use bch2_dev_get_ioref() if you already have an io_ref, use + * percpu_ref_get(). Since dev_get_ioref() has tryget() semantics, that'= s what + * you should be doing anyways. + * + * - All io_refs must be released without blocking on locks that might be = held + * while calling dev_get_ioref(). This is easy to obey since we generally + * release io_refs from endio functions. + * + */ +struct bch_dev *bch2_dev_get_ioref(struct bch_fs *c, unsigned dev, int rw) +{ + might_sleep(); +again: + rcu_read_lock(); + struct bch_dev *ca =3D bch2_dev_rcu(c, dev); + if (likely(ca)) { + if (unlikely(!percpu_ref_tryget(&ca->io_ref))) { + smp_mb(); + if (ca->frozen) { + bch2_dev_get(ca); + rcu_read_unlock(); + + wait_event(ca->frozen_wait, !ca->frozen); + bch2_dev_put(ca); + goto again; + } + ca =3D NULL; + } + } + rcu_read_unlock(); + + if (ca && + (ca->mi.state =3D=3D BCH_MEMBER_STATE_rw || + (ca->mi.state =3D=3D BCH_MEMBER_STATE_ro && rw =3D=3D READ))) + return ca; + + if (ca) + percpu_ref_put(&ca->io_ref); + return NULL; +} + void bch2_dev_missing(struct bch_fs *c, unsigned dev) { if (dev !=3D BCH_SB_MEMBER_INVALID) diff --git a/fs/bcachefs/sb-members.h b/fs/bcachefs/sb-members.h index df91b02ce575..b3359ee63b0e 100644 --- a/fs/bcachefs/sb-members.h +++ b/fs/bcachefs/sb-members.h @@ -281,25 +281,7 @@ static inline struct bch_dev *bch2_dev_iterate(struct = bch_fs *c, struct bch_dev return bch2_dev_tryget(c, dev_idx); } =20 -static inline struct bch_dev *bch2_dev_get_ioref(struct bch_fs *c, unsigne= d dev, int rw) -{ - might_sleep(); - - rcu_read_lock(); - struct bch_dev *ca =3D bch2_dev_rcu(c, dev); - if (ca && !percpu_ref_tryget(&ca->io_ref)) - ca =3D NULL; - rcu_read_unlock(); - - if (ca && - (ca->mi.state =3D=3D BCH_MEMBER_STATE_rw || - (ca->mi.state =3D=3D BCH_MEMBER_STATE_ro && rw =3D=3D READ))) - return ca; - - if (ca) - percpu_ref_put(&ca->io_ref); - return NULL; -} +struct bch_dev *bch2_dev_get_ioref(struct bch_fs *, unsigned, int); =20 /* XXX kill, move to struct bch_fs */ static inline struct bch_devs_mask bch2_online_devs(struct bch_fs *c) diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index 05a2dc5ef513..dfdeab7d847c 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -1236,6 +1236,22 @@ static void bch2_dev_free(struct bch_dev *ca) kobject_put(&ca->kobj); } =20 +static void bch2_dev_io_ref_stop(struct bch_dev *ca) +{ + lockdep_assert_held(&ca->io_ref_statechange_lock); + + reinit_completion(&ca->io_ref_completion); + percpu_ref_kill(&ca->io_ref); + wait_for_completion(&ca->io_ref_completion); +} + +static void bch2_dev_io_ref_start(struct bch_dev *ca) +{ + lockdep_assert_held(&ca->io_ref_statechange_lock); + + percpu_ref_reinit(&ca->io_ref); +} + static void __bch2_dev_offline(struct bch_fs *c, struct bch_dev *ca) { =20 @@ -1246,13 +1262,14 @@ static void __bch2_dev_offline(struct bch_fs *c, st= ruct bch_dev *ca) =20 __bch2_dev_read_only(c, ca); =20 - reinit_completion(&ca->io_ref_completion); - percpu_ref_kill(&ca->io_ref); - wait_for_completion(&ca->io_ref_completion); - bch2_dev_unlink(ca); =20 + mutex_lock(&ca->io_ref_statechange_lock); + bch2_dev_io_ref_stop(ca); + bch2_free_super(&ca->disk_sb); + mutex_unlock(&ca->io_ref_statechange_lock); + bch2_dev_journal_exit(ca); } =20 @@ -1334,6 +1351,8 @@ static struct bch_dev *__bch2_dev_alloc(struct bch_fs= *c, kobject_init(&ca->kobj, &bch2_dev_ktype); init_completion(&ca->ref_completion); init_completion(&ca->io_ref_completion); + mutex_init(&ca->io_ref_statechange_lock); + init_waitqueue_head(&ca->frozen_wait); =20 INIT_WORK(&ca->io_error_work, bch2_io_error_work); =20 @@ -1428,6 +1447,8 @@ static int __bch2_dev_attach_bdev(struct bch_dev *ca,= struct bch_sb_handle *sb) if (ret) return ret; =20 + mutex_lock(&ca->io_ref_statechange_lock); + /* Commit: */ ca->disk_sb =3D *sb; memset(sb, 0, sizeof(*sb)); @@ -1441,7 +1462,9 @@ static int __bch2_dev_attach_bdev(struct bch_dev *ca,= struct bch_sb_handle *sb) =20 ca->dev =3D ca->disk_sb.bdev->bd_dev; =20 - percpu_ref_reinit(&ca->io_ref); + if (!ca->frozen) + bch2_dev_io_ref_start(ca); + mutex_unlock(&ca->io_ref_statechange_lock); =20 return 0; } @@ -2115,9 +2138,63 @@ static void bch2_fs_bdev_sync(struct block_device *b= dev) bch2_ro_ref_put(c); } =20 +static int bch2_fs_bdev_freeze(struct block_device *bdev) +{ + int ret =3D -EINVAL; + struct bch_fs *c =3D bdev_get_fs(bdev); + if (!c) + return ret; + + struct bch_dev *ca =3D bdev_to_bch_dev(c, bdev); + if (!ca) + goto err; + + mutex_lock(&ca->io_ref_statechange_lock); + ca->frozen++; + smp_mb(); + bch2_dev_io_ref_stop(ca); + mutex_unlock(&ca->io_ref_statechange_lock); + + ret =3D sync_blockdev(bdev); + + bch2_dev_put(ca); +err: + bch2_ro_ref_put(c); + return ret; +} + +static int bch2_fs_bdev_thaw(struct block_device *bdev) +{ + int ret =3D -EINVAL; + struct bch_fs *c =3D bdev_get_fs(bdev); + if (!c) + return ret; + + struct bch_dev *ca =3D bdev_to_bch_dev(c, bdev); + if (!ca) + goto err; + + mutex_lock(&ca->io_ref_statechange_lock); + if (ca->disk_sb.bdev && + ca->frozen =3D=3D 1) + bch2_dev_io_ref_start(ca); + --ca->frozen; + wake_up(&ca->frozen_wait); + mutex_unlock(&ca->io_ref_statechange_lock); + + ret =3D 0; + + bch2_dev_put(ca); +err: + bch2_ro_ref_put(c); + return ret; +} + const struct blk_holder_ops bch2_sb_handle_bdev_ops =3D { .mark_dead =3D bch2_fs_bdev_mark_dead, .sync =3D bch2_fs_bdev_sync, + .freeze =3D bch2_fs_bdev_freeze, + .thaw =3D bch2_fs_bdev_thaw, }; =20 /* Filesystem open: */ --=20 2.47.2