]> git.hungrycats.org Git - linux/commitdiff
Revert "btrfs: use btrfs_start_delalloc_roots in shrink_delalloc (no btrfs_writeback_...
authorZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Wed, 9 Dec 2020 15:31:50 +0000 (10:31 -0500)
committerZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Wed, 9 Dec 2020 15:31:50 +0000 (10:31 -0500)
This reverts commit ec2681aa7cdb9ba53fb46ff5dfa83ca2a1763a0f.

fs/btrfs/space-info.c

index 590feec3e8be0f751519f6b79de45456d51d1bd4..475968ccbd1d1be3a93d1f256d685a6e28264f8a 100644 (file)
@@ -476,6 +476,28 @@ again:
        up_read(&info->groups_sem);
 }
 
+static void btrfs_writeback_inodes_sb_nr(struct btrfs_fs_info *fs_info,
+                                        unsigned long nr_pages, int nr_items)
+{
+       struct super_block *sb = fs_info->sb;
+
+       if (down_read_trylock(&sb->s_umount)) {
+               writeback_inodes_sb_nr(sb, nr_pages, WB_REASON_FS_FREE_SPACE);
+               up_read(&sb->s_umount);
+       } else {
+               /*
+                * We needn't worry the filesystem going from r/w to r/o though
+                * we don't acquire ->s_umount mutex, because the filesystem
+                * should guarantee the delalloc inodes list be empty after
+                * the filesystem is readonly(all dirty pages are written to
+                * the disk).
+                */
+               btrfs_start_delalloc_roots(fs_info, nr_items);
+               if (!current->journal_info)
+                       btrfs_wait_ordered_roots(fs_info, nr_items, 0, (u64)-1);
+       }
+}
+
 static inline u64 calc_reclaim_items_nr(struct btrfs_fs_info *fs_info,
                                        u64 to_reclaim)
 {
@@ -501,8 +523,10 @@ static void shrink_delalloc(struct btrfs_fs_info *fs_info, u64 to_reclaim,
        struct btrfs_trans_handle *trans;
        u64 delalloc_bytes;
        u64 dio_bytes;
+       u64 async_pages;
        u64 items;
        long time_left;
+       unsigned long nr_pages;
        int loops;
 
        /* Calc the number of the pages we need flush for space reservation */
@@ -533,8 +557,37 @@ static void shrink_delalloc(struct btrfs_fs_info *fs_info, u64 to_reclaim,
 
        loops = 0;
        while ((delalloc_bytes || dio_bytes) && loops < 3) {
-               btrfs_start_delalloc_roots(fs_info, items);
+               nr_pages = min(delalloc_bytes, to_reclaim) >> PAGE_SHIFT;
+
+               /*
+                * Triggers inode writeback for up to nr_pages. This will invoke
+                * ->writepages callback and trigger delalloc filling
+                *  (btrfs_run_delalloc_range()).
+                */
+               btrfs_writeback_inodes_sb_nr(fs_info, nr_pages, items);
+
+               /*
+                * We need to wait for the compressed pages to start before
+                * we continue.
+                */
+               async_pages = atomic_read(&fs_info->async_delalloc_pages);
+               if (!async_pages)
+                       goto skip_async;
+
+               /*
+                * Calculate how many compressed pages we want to be written
+                * before we continue. I.e if there are more async pages than we
+                * require wait_event will wait until nr_pages are written.
+                */
+               if (async_pages <= nr_pages)
+                       async_pages = 0;
+               else
+                       async_pages -= nr_pages;
 
+               wait_event(fs_info->async_submit_wait,
+                          atomic_read(&fs_info->async_delalloc_pages) <=
+                          (int)async_pages);
+skip_async:
                spin_lock(&space_info->lock);
                if (list_empty(&space_info->tickets) &&
                    list_empty(&space_info->priority_tickets)) {