[PATCH] bcachefs: bch2_fs_read_write_early needs to hold write lock

Edward Adam Davis posted 1 patch 1 year, 6 months ago
fs/bcachefs/snapshot.c | 2 ++
1 file changed, 2 insertions(+)
[PATCH] bcachefs: bch2_fs_read_write_early needs to hold write lock
Posted by Edward Adam Davis 1 year, 6 months ago
bch2_fs_read_write_early() needs to hold state_lock to pretect and sync data.

Reported-by: syzbot+4366624c0b5aac4906cf@syzkaller.appspotmail.com
Signed-off-by: Edward Adam Davis <eadavis@qq.com>
---
 fs/bcachefs/snapshot.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/bcachefs/snapshot.c b/fs/bcachefs/snapshot.c
index 51918acfd726..b27a4327274d 100644
--- a/fs/bcachefs/snapshot.c
+++ b/fs/bcachefs/snapshot.c
@@ -1566,7 +1566,9 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
 		return 0;
 
 	if (!test_bit(BCH_FS_started, &c->flags)) {
+		down_write(&c->state_lock);
 		ret = bch2_fs_read_write_early(c);
+		up_write(&c->state_lock);
 		bch_err_msg(c, ret, "deleting dead snapshots: error going rw");
 		if (ret)
 			return ret;
-- 
2.43.0
Re: [PATCH] bcachefs: bch2_fs_read_write_early needs to hold write lock
Posted by Kent Overstreet 1 year, 6 months ago
On Sat, Jun 15, 2024 at 07:44:04PM +0800, Edward Adam Davis wrote:
> bch2_fs_read_write_early() needs to hold state_lock to pretect and sync data.
> 
> Reported-by: syzbot+4366624c0b5aac4906cf@syzkaller.appspotmail.com
> Signed-off-by: Edward Adam Davis <eadavis@qq.com>

this is incorrect - delete_dead_snapshots() may be called synchronously
or asynchronously, and if it's called asynchronously we do hold
state_lock, so this will deadlock

> ---
>  fs/bcachefs/snapshot.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/fs/bcachefs/snapshot.c b/fs/bcachefs/snapshot.c
> index 51918acfd726..b27a4327274d 100644
> --- a/fs/bcachefs/snapshot.c
> +++ b/fs/bcachefs/snapshot.c
> @@ -1566,7 +1566,9 @@ int bch2_delete_dead_snapshots(struct bch_fs *c)
>  		return 0;
>  
>  	if (!test_bit(BCH_FS_started, &c->flags)) {
> +		down_write(&c->state_lock);
>  		ret = bch2_fs_read_write_early(c);
> +		up_write(&c->state_lock);
>  		bch_err_msg(c, ret, "deleting dead snapshots: error going rw");
>  		if (ret)
>  			return ret;
> -- 
> 2.43.0
>