/*
  * Return 0 if we have submitted or queued the sector for submission.
- * Return <0 for critical errors.
+ * Return <0 for critical errors, and the sector will have its dirty flag cleared.
  *
  * Caller should make sure filepos < i_size and handle filepos >= i_size case.
  */
        ASSERT(filepos < i_size);
 
        em = btrfs_get_extent(inode, NULL, filepos, sectorsize);
-       if (IS_ERR(em))
+       if (IS_ERR(em)) {
+               /*
+                * When submission failed, we should still clear the folio dirty.
+                * Or the folio will be written back again but without any
+                * ordered extent.
+                */
+               btrfs_folio_clear_dirty(fs_info, folio, filepos, sectorsize);
+               btrfs_folio_set_writeback(fs_info, folio, filepos, sectorsize);
+               btrfs_folio_clear_writeback(fs_info, folio, filepos, sectorsize);
                return PTR_ERR(em);
+       }
 
        extent_offset = filepos - em->start;
        em_end = btrfs_extent_map_end(em);
         * Here we set writeback and clear for the range. If the full folio
         * is no longer dirty then we clear the PAGECACHE_TAG_DIRTY tag.
         *
-        * If we hit any error, the corresponding sector will still be dirty
-        * thus no need to clear PAGECACHE_TAG_DIRTY.
+        * If we hit any error, the corresponding sector will have its dirty
+        * flag cleared and writeback finished, thus no need to handle the error case.
         */
        if (!submitted_io && !error) {
                btrfs_folio_set_writeback(fs_info, folio, start, len);