btrfs: start readahead also in seed devices [Linux 4.9.185]

btrfs: start readahead also in seed devices [Linux 4.9.185]

This Linux kernel change "btrfs: start readahead also in seed devices" is included in the Linux 4.9.185 release. This change is authored by Naohiro Aota <naohiro.aota [at] wdc.com> on Thu Jun 6 16:54:44 2019 +0900. The commit for this change in Linux stable tree is ce8c476 (patch) which is from upstream commit c4e0540. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream c4e0540.

btrfs: start readahead also in seed devices

commit c4e0540d0ad49c8ceab06cceed1de27c4fe29f6e upstream.

Currently, btrfs does not consult seed devices to start readahead. As a
result, if readahead zone is added to the seed devices, btrfs_reada_wait()
indefinitely wait for the reada_ctl to finish.

You can reproduce the hung by modifying btrfs/163 to have larger initial
file size (e.g. xfs_io pwrite 4M instead of current 256K).

Fixes: 7414a03fbf9e ("btrfs: initial readahead code and prototypes")
Cc: stable@vger.kernel.org # 3.2+: ce7791ffee1e: Btrfs: fix race between readahead and device replace/removal
Cc: stable@vger.kernel.org # 3.2+
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

There are 5 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 fs/btrfs/reada.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/fs/btrfs/reada.c b/fs/btrfs/reada.c
index 75bab76..94441fd 100644
--- a/fs/btrfs/reada.c
+++ b/fs/btrfs/reada.c
@@ -759,6 +759,7 @@ static void __reada_start_machine(struct btrfs_fs_info *fs_info)
    u64 total = 0;
    int i;

+again:
    do {
        enqueued = 0;
        mutex_lock(&fs_devices->device_list_mutex);
@@ -771,6 +772,10 @@ static void __reada_start_machine(struct btrfs_fs_info *fs_info)
        mutex_unlock(&fs_devices->device_list_mutex);
        total += enqueued;
    } while (enqueued && total < 10000);
+   if (fs_devices->seed) {
+       fs_devices = fs_devices->seed;
+       goto again;
+   }

    if (enqueued == 0)
        return;

Leave a Reply

Your email address will not be published. Required fields are marked *