RISCV: configs: tizen_visionfive2: Enable DM_BOW feature
[platform/kernel/linux-starfive.git] / fs / btrfs / scrub.c
index b877203..1e3ff87 100644 (file)
@@ -1099,12 +1099,22 @@ out:
 static void scrub_read_endio(struct btrfs_bio *bbio)
 {
        struct scrub_stripe *stripe = bbio->private;
+       struct bio_vec *bvec;
+       int sector_nr = calc_sector_number(stripe, bio_first_bvec_all(&bbio->bio));
+       int num_sectors;
+       u32 bio_size = 0;
+       int i;
+
+       ASSERT(sector_nr < stripe->nr_sectors);
+       bio_for_each_bvec_all(bvec, &bbio->bio, i)
+               bio_size += bvec->bv_len;
+       num_sectors = bio_size >> stripe->bg->fs_info->sectorsize_bits;
 
        if (bbio->bio.bi_status) {
-               bitmap_set(&stripe->io_error_bitmap, 0, stripe->nr_sectors);
-               bitmap_set(&stripe->error_bitmap, 0, stripe->nr_sectors);
+               bitmap_set(&stripe->io_error_bitmap, sector_nr, num_sectors);
+               bitmap_set(&stripe->error_bitmap, sector_nr, num_sectors);
        } else {
-               bitmap_clear(&stripe->io_error_bitmap, 0, stripe->nr_sectors);
+               bitmap_clear(&stripe->io_error_bitmap, sector_nr, num_sectors);
        }
        bio_put(&bbio->bio);
        if (atomic_dec_and_test(&stripe->pending_io)) {
@@ -1640,6 +1650,9 @@ static void scrub_submit_initial_read(struct scrub_ctx *sctx,
 {
        struct btrfs_fs_info *fs_info = sctx->fs_info;
        struct btrfs_bio *bbio;
+       unsigned int nr_sectors = min_t(u64, BTRFS_STRIPE_LEN, stripe->bg->start +
+                                     stripe->bg->length - stripe->logical) >>
+                                 fs_info->sectorsize_bits;
        int mirror = stripe->mirror_num;
 
        ASSERT(stripe->bg);
@@ -1649,14 +1662,16 @@ static void scrub_submit_initial_read(struct scrub_ctx *sctx,
        bbio = btrfs_bio_alloc(SCRUB_STRIPE_PAGES, REQ_OP_READ, fs_info,
                               scrub_read_endio, stripe);
 
-       /* Read the whole stripe. */
        bbio->bio.bi_iter.bi_sector = stripe->logical >> SECTOR_SHIFT;
-       for (int i = 0; i < BTRFS_STRIPE_LEN >> PAGE_SHIFT; i++) {
+       /* Read the whole range inside the chunk boundary. */
+       for (unsigned int cur = 0; cur < nr_sectors; cur++) {
+               struct page *page = scrub_stripe_get_page(stripe, cur);
+               unsigned int pgoff = scrub_stripe_get_page_offset(stripe, cur);
                int ret;
 
-               ret = bio_add_page(&bbio->bio, stripe->pages[i], PAGE_SIZE, 0);
+               ret = bio_add_page(&bbio->bio, page, fs_info->sectorsize, pgoff);
                /* We should have allocated enough bio vectors. */
-               ASSERT(ret == PAGE_SIZE);
+               ASSERT(ret == fs_info->sectorsize);
        }
        atomic_inc(&stripe->pending_io);
 
@@ -1798,6 +1813,9 @@ static int queue_scrub_stripe(struct scrub_ctx *sctx, struct btrfs_block_group *
         */
        ASSERT(sctx->cur_stripe < SCRUB_TOTAL_STRIPES);
 
+       /* @found_logical_ret must be specified. */
+       ASSERT(found_logical_ret);
+
        stripe = &sctx->stripes[sctx->cur_stripe];
        scrub_reset_stripe(stripe);
        ret = scrub_find_fill_first_stripe(bg, &sctx->extent_path,
@@ -1806,8 +1824,7 @@ static int queue_scrub_stripe(struct scrub_ctx *sctx, struct btrfs_block_group *
        /* Either >0 as no more extents or <0 for error. */
        if (ret)
                return ret;
-       if (found_logical_ret)
-               *found_logical_ret = stripe->logical;
+       *found_logical_ret = stripe->logical;
        sctx->cur_stripe++;
 
        /* We filled one group, submit it. */
@@ -2010,7 +2027,7 @@ static int scrub_simple_mirror(struct scrub_ctx *sctx,
 
        /* Go through each extent items inside the logical range */
        while (cur_logical < logical_end) {
-               u64 found_logical;
+               u64 found_logical = U64_MAX;
                u64 cur_physical = physical + cur_logical - logical_start;
 
                /* Canceled? */
@@ -2045,6 +2062,8 @@ static int scrub_simple_mirror(struct scrub_ctx *sctx,
                if (ret < 0)
                        break;
 
+               /* queue_scrub_stripe() returned 0, @found_logical must be updated. */
+               ASSERT(found_logical != U64_MAX);
                cur_logical = found_logical + BTRFS_STRIPE_LEN;
 
                /* Don't hold CPU for too long time */