mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v6 0/2] btrfs: fix sleep from invalid context bug in update_qgroup_limit_item()
@ 2022-11-16 14:23 ChenXiaoSong
  2022-11-16 14:23 ` [PATCH v6 1/2] btrfs: add might_sleep() to some places " ChenXiaoSong
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: ChenXiaoSong @ 2022-11-16 14:23 UTC (permalink / raw)
  To: clm, josef, dsterba
  Cc: linux-btrfs, linux-kernel, chenxiaosong2, zhangxiaoxu5, yanaijie,
	quwenruo.btrfs, wqu

At least 3 places might sleep in update_qgroup_limit_item(), as shown below:

  update_qgroup_limit_item
    btrfs_alloc_path
      /* allocate memory non-atomically, might sleep */
      kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS)
    btrfs_search_slot
      setup_nodes_for_search
        reada_for_balance
          btrfs_readahead_node_child
            btrfs_readahead_tree_block
              btrfs_find_create_tree_block
                alloc_extent_buffer
                  kmem_cache_zalloc
                    /* allocate memory non-atomically, might sleep */
                    kmem_cache_alloc(GFP_NOFS|__GFP_NOFAIL|__GFP_ZERO)
              read_extent_buffer_pages
                submit_extent_page
                  /* disk IO, might sleep */
                  submit_one_bio

Fix this by calling qgroup_dirty() on @dstqgroup, and update limit item in
btrfs_run_qgroups() later.

By the way, add might_sleep() to some places.

ChenXiaoSong (2):
  btrfs: add might_sleep() to some places in update_qgroup_limit_item()
  btrfs: qgroup: fix sleep from invalid context bug in
    update_qgroup_limit_item()

 fs/btrfs/ctree.c  | 4 ++++
 fs/btrfs/qgroup.c | 9 +--------
 2 files changed, 5 insertions(+), 8 deletions(-)

-- 
2.31.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v6 1/2] btrfs: add might_sleep() to some places in update_qgroup_limit_item()
  2022-11-16 14:23 [PATCH v6 0/2] btrfs: fix sleep from invalid context bug in update_qgroup_limit_item() ChenXiaoSong
@ 2022-11-16 14:23 ` ChenXiaoSong
  2022-11-16 14:23 ` [PATCH v6 2/2] btrfs: qgroup: fix sleep from invalid context bug " ChenXiaoSong
  2022-11-18 16:37 ` [PATCH v6 0/2] btrfs: " David Sterba
  2 siblings, 0 replies; 5+ messages in thread
From: ChenXiaoSong @ 2022-11-16 14:23 UTC (permalink / raw)
  To: clm, josef, dsterba
  Cc: linux-btrfs, linux-kernel, chenxiaosong2, zhangxiaoxu5, yanaijie,
	quwenruo.btrfs, wqu

At least 3 places might sleep in update_qgroup_limit_item(), as shown below:

  update_qgroup_limit_item
    btrfs_alloc_path
      /* allocate memory non-atomically, might sleep */
      kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS)
    btrfs_search_slot
      setup_nodes_for_search
        reada_for_balance
          btrfs_readahead_node_child
            btrfs_readahead_tree_block
              btrfs_find_create_tree_block
                alloc_extent_buffer
                  kmem_cache_zalloc
                    /* allocate memory non-atomically, might sleep */
                    kmem_cache_alloc(GFP_NOFS|__GFP_NOFAIL|__GFP_ZERO)
              read_extent_buffer_pages
                submit_extent_page
                  /* disk IO, might sleep */
                  submit_one_bio

As the potential sleeping under spin lock is hard to spot, we should add
might_sleep() to btrfs_alloc_path() and btrfs_search_slot().

Signed-off-by: ChenXiaoSong <chenxiaosong2@huawei.com>
---
 fs/btrfs/ctree.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index a9543f01184c..1cd0d00ef328 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -78,6 +78,8 @@ size_t __attribute_const__ btrfs_get_num_csums(void)
 
 struct btrfs_path *btrfs_alloc_path(void)
 {
+	might_sleep();
+
 	return kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS);
 }
 
@@ -1934,6 +1936,8 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
 	int min_write_lock_level;
 	int prev_cmp;
 
+	might_sleep();
+
 	lowest_level = p->lowest_level;
 	WARN_ON(lowest_level && ins_len > 0);
 	WARN_ON(p->nodes[0] != NULL);
-- 
2.31.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v6 2/2] btrfs: qgroup: fix sleep from invalid context bug in update_qgroup_limit_item()
  2022-11-16 14:23 [PATCH v6 0/2] btrfs: fix sleep from invalid context bug in update_qgroup_limit_item() ChenXiaoSong
  2022-11-16 14:23 ` [PATCH v6 1/2] btrfs: add might_sleep() to some places " ChenXiaoSong
@ 2022-11-16 14:23 ` ChenXiaoSong
  2022-11-16 23:16   ` Qu Wenruo
  2022-11-18 16:37 ` [PATCH v6 0/2] btrfs: " David Sterba
  2 siblings, 1 reply; 5+ messages in thread
From: ChenXiaoSong @ 2022-11-16 14:23 UTC (permalink / raw)
  To: clm, josef, dsterba
  Cc: linux-btrfs, linux-kernel, chenxiaosong2, zhangxiaoxu5, yanaijie,
	quwenruo.btrfs, wqu

Syzkaller reported BUG as follows:

  BUG: sleeping function called from invalid context at
       include/linux/sched/mm.h:274
  Call Trace:
   <TASK>
   dump_stack_lvl+0xcd/0x134
   __might_resched.cold+0x222/0x26b
   kmem_cache_alloc+0x2e7/0x3c0
   update_qgroup_limit_item+0xe1/0x390
   btrfs_qgroup_inherit+0x147b/0x1ee0
   create_subvol+0x4eb/0x1710
   btrfs_mksubvol+0xfe5/0x13f0
   __btrfs_ioctl_snap_create+0x2b0/0x430
   btrfs_ioctl_snap_create_v2+0x25a/0x520
   btrfs_ioctl+0x2a1c/0x5ce0
   __x64_sys_ioctl+0x193/0x200
   do_syscall_64+0x35/0x80

Fix this by calling qgroup_dirty() on @dstqgroup, and update limit item in
btrfs_run_qgroups() later.

Signed-off-by: ChenXiaoSong <chenxiaosong2@huawei.com>
---
 fs/btrfs/qgroup.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 9334c3157c22..b74105a10f16 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -2951,14 +2951,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid,
 		dstgroup->rsv_rfer = inherit->lim.rsv_rfer;
 		dstgroup->rsv_excl = inherit->lim.rsv_excl;
 
-		ret = update_qgroup_limit_item(trans, dstgroup);
-		if (ret) {
-			qgroup_mark_inconsistent(fs_info);
-			btrfs_info(fs_info,
-				   "unable to update quota limit for %llu",
-				   dstgroup->qgroupid);
-			goto unlock;
-		}
+		qgroup_dirty(fs_info, dstgroup);
 	}
 
 	if (srcid) {
-- 
2.31.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v6 2/2] btrfs: qgroup: fix sleep from invalid context bug in update_qgroup_limit_item()
  2022-11-16 14:23 ` [PATCH v6 2/2] btrfs: qgroup: fix sleep from invalid context bug " ChenXiaoSong
@ 2022-11-16 23:16   ` Qu Wenruo
  0 siblings, 0 replies; 5+ messages in thread
From: Qu Wenruo @ 2022-11-16 23:16 UTC (permalink / raw)
  To: ChenXiaoSong, clm, josef, dsterba
  Cc: linux-btrfs, linux-kernel, zhangxiaoxu5, yanaijie, wqu



On 2022/11/16 22:23, ChenXiaoSong wrote:
> Syzkaller reported BUG as follows:
> 
>    BUG: sleeping function called from invalid context at
>         include/linux/sched/mm.h:274
>    Call Trace:
>     <TASK>
>     dump_stack_lvl+0xcd/0x134
>     __might_resched.cold+0x222/0x26b
>     kmem_cache_alloc+0x2e7/0x3c0
>     update_qgroup_limit_item+0xe1/0x390
>     btrfs_qgroup_inherit+0x147b/0x1ee0
>     create_subvol+0x4eb/0x1710
>     btrfs_mksubvol+0xfe5/0x13f0
>     __btrfs_ioctl_snap_create+0x2b0/0x430
>     btrfs_ioctl_snap_create_v2+0x25a/0x520
>     btrfs_ioctl+0x2a1c/0x5ce0
>     __x64_sys_ioctl+0x193/0x200
>     do_syscall_64+0x35/0x80
> 
> Fix this by calling qgroup_dirty() on @dstqgroup, and update limit item in
> btrfs_run_qgroups() later.
> 
> Signed-off-by: ChenXiaoSong <chenxiaosong2@huawei.com>

Reviewed-by: Qu Wenruo <wqu@suse.com>

Thanks,
Qu
> ---
>   fs/btrfs/qgroup.c | 9 +--------
>   1 file changed, 1 insertion(+), 8 deletions(-)
> 
> diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
> index 9334c3157c22..b74105a10f16 100644
> --- a/fs/btrfs/qgroup.c
> +++ b/fs/btrfs/qgroup.c
> @@ -2951,14 +2951,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid,
>   		dstgroup->rsv_rfer = inherit->lim.rsv_rfer;
>   		dstgroup->rsv_excl = inherit->lim.rsv_excl;
>   
> -		ret = update_qgroup_limit_item(trans, dstgroup);
> -		if (ret) {
> -			qgroup_mark_inconsistent(fs_info);
> -			btrfs_info(fs_info,
> -				   "unable to update quota limit for %llu",
> -				   dstgroup->qgroupid);
> -			goto unlock;
> -		}
> +		qgroup_dirty(fs_info, dstgroup);
>   	}
>   
>   	if (srcid) {

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v6 0/2] btrfs: fix sleep from invalid context bug in update_qgroup_limit_item()
  2022-11-16 14:23 [PATCH v6 0/2] btrfs: fix sleep from invalid context bug in update_qgroup_limit_item() ChenXiaoSong
  2022-11-16 14:23 ` [PATCH v6 1/2] btrfs: add might_sleep() to some places " ChenXiaoSong
  2022-11-16 14:23 ` [PATCH v6 2/2] btrfs: qgroup: fix sleep from invalid context bug " ChenXiaoSong
@ 2022-11-18 16:37 ` David Sterba
  2 siblings, 0 replies; 5+ messages in thread
From: David Sterba @ 2022-11-18 16:37 UTC (permalink / raw)
  To: ChenXiaoSong
  Cc: clm, josef, dsterba, linux-btrfs, linux-kernel, zhangxiaoxu5,
	yanaijie, quwenruo.btrfs, wqu

On Wed, Nov 16, 2022 at 10:23:52PM +0800, ChenXiaoSong wrote:
> At least 3 places might sleep in update_qgroup_limit_item(), as shown below:
> 
>   update_qgroup_limit_item
>     btrfs_alloc_path
>       /* allocate memory non-atomically, might sleep */
>       kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS)
>     btrfs_search_slot
>       setup_nodes_for_search
>         reada_for_balance
>           btrfs_readahead_node_child
>             btrfs_readahead_tree_block
>               btrfs_find_create_tree_block
>                 alloc_extent_buffer
>                   kmem_cache_zalloc
>                     /* allocate memory non-atomically, might sleep */
>                     kmem_cache_alloc(GFP_NOFS|__GFP_NOFAIL|__GFP_ZERO)
>               read_extent_buffer_pages
>                 submit_extent_page
>                   /* disk IO, might sleep */
>                   submit_one_bio
> 
> Fix this by calling qgroup_dirty() on @dstqgroup, and update limit item in
> btrfs_run_qgroups() later.
> 
> By the way, add might_sleep() to some places.
> 
> ChenXiaoSong (2):
>   btrfs: add might_sleep() to some places in update_qgroup_limit_item()
>   btrfs: qgroup: fix sleep from invalid context bug in
>     update_qgroup_limit_item()

Added to misc-next with updated subjects and changelogs, thanks.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-11-18 16:37 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-16 14:23 [PATCH v6 0/2] btrfs: fix sleep from invalid context bug in update_qgroup_limit_item() ChenXiaoSong
2022-11-16 14:23 ` [PATCH v6 1/2] btrfs: add might_sleep() to some places " ChenXiaoSong
2022-11-16 14:23 ` [PATCH v6 2/2] btrfs: qgroup: fix sleep from invalid context bug " ChenXiaoSong
2022-11-16 23:16   ` Qu Wenruo
2022-11-18 16:37 ` [PATCH v6 0/2] btrfs: " David Sterba

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®