On Mon, Apr 19, 2021 at 04:41:02PM +0900, Johannes Thumshirn wrote:
> +void btrfs_reclaim_bgs_work(struct work_struct *work)
> +{
> +     struct btrfs_fs_info *fs_info =
> +             container_of(work, struct btrfs_fs_info, reclaim_bgs_work);
> +     struct btrfs_block_group *bg;
> +     struct btrfs_space_info *space_info;
> +     int ret;
> +
> +     if (!test_bit(BTRFS_FS_OPEN, &fs_info->flags))
> +             return;
> +
> +     if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_BALANCE))
> +             return;
> +
> +     mutex_lock(&fs_info->reclaim_bgs_lock);
> +     spin_lock(&fs_info->unused_bgs_lock);
> +     while (!list_empty(&fs_info->reclaim_bgs)) {
> +             bg = list_first_entry(&fs_info->reclaim_bgs,
> +                                   struct btrfs_block_group,
> +                                   bg_list);
> +             list_del_init(&bg->bg_list);
> +
> +             space_info = bg->space_info;
> +             spin_unlock(&fs_info->unused_bgs_lock);
> +
> +             /* Don't want to race with allocators so take the groups_sem */
> +             down_write(&space_info->groups_sem);
> +
> +             spin_lock(&bg->lock);
> +             if (bg->reserved || bg->pinned || bg->ro) {
> +                     /*
> +                      * We want to bail if we made new allocations or have
> +                      * outstanding allocations in this block group.  We do
> +                      * the ro check in case balance is currently acting on
> +                      * this block group.
> +                      */
> +                     spin_unlock(&bg->lock);
> +                     up_write(&space_info->groups_sem);
> +                     goto next;
> +             }
> +             spin_unlock(&bg->lock);
> +
> +             /* Get out fast, in case we're unmounting the FS. */
> +             if (btrfs_fs_closing(fs_info)) {
> +                     up_write(&space_info->groups_sem);
> +                     goto next;
> +             }
> +
> +             ret = inc_block_group_ro(bg, 0);
> +             up_write(&space_info->groups_sem);
> +             if (ret < 0)
> +                     goto next;
> +
> +             btrfs_info(fs_info, "reclaiming chunk %llu", bg->start);

This could state the bg usage ratio, bg->used / bg->length .

> +             trace_btrfs_reclaim_block_group(bg);
> +             ret = btrfs_relocate_chunk(fs_info, bg->start);
> +             if (ret)
> +                     btrfs_err(fs_info, "error relocating chunk %llu",
> +                               bg->start);
> +
> +next:
> +             btrfs_put_block_group(bg);
> +             spin_lock(&fs_info->unused_bgs_lock);
> +     }
> +     spin_unlock(&fs_info->unused_bgs_lock);
> +     mutex_unlock(&fs_info->reclaim_bgs_lock);
> +     btrfs_exclop_finish(fs_info);
> +}

Reply via email to