blk_opf_t opf;
        btrfs_bio_end_io_t end_io_func;
        struct writeback_control *wbc;
-
-       /*
-        * Tell writepage not to lock the state bits for this range, it still
-        * does the unlocking.
-        */
-       bool extent_locked;
 };
 
 static void submit_one_bio(struct btrfs_bio_ctrl *bio_ctrl)
 {
        struct folio *folio = page_folio(page);
        struct inode *inode = page->mapping->host;
-       struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        const u64 page_start = page_offset(page);
        const u64 page_end = page_start + PAGE_SIZE - 1;
        int ret;
        if (ret < 0)
                goto done;
 
-       if (!bio_ctrl->extent_locked) {
-               ret = writepage_delalloc(BTRFS_I(inode), page, bio_ctrl->wbc);
-               if (ret == 1)
-                       return 0;
-               if (ret)
-                       goto done;
-       }
+       ret = writepage_delalloc(BTRFS_I(inode), page, bio_ctrl->wbc);
+       if (ret == 1)
+               return 0;
+       if (ret)
+               goto done;
 
        ret = __extent_writepage_io(BTRFS_I(inode), page, bio_ctrl, i_size, &nr);
        if (ret == 1)
        }
        if (ret)
                end_extent_writepage(page, ret, page_start, page_end);
-       if (bio_ctrl->extent_locked) {
-               struct writeback_control *wbc = bio_ctrl->wbc;
-
-               /*
-                * If bio_ctrl->extent_locked, it's from extent_write_locked_range(),
-                * the page can either be locked by lock_page() or
-                * process_one_page().
-                * Let btrfs_page_unlock_writer() handle both cases.
-                */
-               ASSERT(wbc);
-               btrfs_page_unlock_writer(fs_info, page, wbc->range_start,
-                                        wbc->range_end + 1 - wbc->range_start);
-       } else {
-               unlock_page(page);
-       }
+       unlock_page(page);
        ASSERT(ret <= 0);
        return ret;
 }
        int first_error = 0;
        int ret = 0;
        struct address_space *mapping = inode->i_mapping;
-       struct page *page;
+       struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
+       const u32 sectorsize = fs_info->sectorsize;
+       loff_t i_size = i_size_read(inode);
        u64 cur = start;
-       unsigned long nr_pages;
-       const u32 sectorsize = btrfs_sb(inode->i_sb)->sectorsize;
        struct writeback_control wbc_writepages = {
                .sync_mode      = WB_SYNC_ALL,
                .range_start    = start,
                /* We're called from an async helper function */
                .opf = REQ_OP_WRITE | REQ_BTRFS_CGROUP_PUNT |
                        wbc_to_write_flags(&wbc_writepages),
-               .extent_locked = 1,
        };
 
        ASSERT(IS_ALIGNED(start, sectorsize) && IS_ALIGNED(end + 1, sectorsize));
-       nr_pages = (round_up(end, PAGE_SIZE) - round_down(start, PAGE_SIZE)) >>
-                  PAGE_SHIFT;
-       wbc_writepages.nr_to_write = nr_pages * 2;
 
        wbc_attach_fdatawrite_inode(&wbc_writepages, inode);
        while (cur <= end) {
                u64 cur_end = min(round_down(cur, PAGE_SIZE) + PAGE_SIZE - 1, end);
+               struct page *page;
+               int nr = 0;
 
                page = find_get_page(mapping, cur >> PAGE_SHIFT);
                /*
                ASSERT(PageLocked(page));
                ASSERT(PageDirty(page));
                clear_page_dirty_for_io(page);
-               ret = __extent_writepage(page, &bio_ctrl);
-               ASSERT(ret <= 0);
+
+               ret = __extent_writepage_io(BTRFS_I(inode), page, &bio_ctrl,
+                                           i_size, &nr);
+               if (ret == 1)
+                       goto next_page;
+
+               /* Make sure the mapping tag for page dirty gets cleared. */
+               if (nr == 0) {
+                       set_page_writeback(page);
+                       end_page_writeback(page);
+               }
+               if (ret)
+                       end_extent_writepage(page, ret, cur, cur_end);
+               btrfs_page_unlock_writer(fs_info, page, cur, cur_end + 1 - cur);
                if (ret < 0) {
                        found_error = true;
                        first_error = ret;
                }
+next_page:
                put_page(page);
                cur = cur_end + 1;
        }
        struct btrfs_bio_ctrl bio_ctrl = {
                .wbc = wbc,
                .opf = REQ_OP_WRITE | wbc_to_write_flags(wbc),
-               .extent_locked = 0,
        };
 
        /*