btrfs: stop setting PageError in the data I/O path
authorChristoph Hellwig <hch@lst.de>
Wed, 31 May 2023 06:04:57 +0000 (08:04 +0200)
committerDavid Sterba <dsterba@suse.com>
Mon, 19 Jun 2023 11:59:35 +0000 (13:59 +0200)
PageError is not used by the VFS/MM and deprecated because it uses up a
page bit and has no coherent rules.  Instead read errors are usually
propagated by not setting or clearing the uptodate bit, and write errors
are propagated through the address_space.  Btrfs now only sets the flag
and never clears it for data pages, so just remove all places setting it,
and the subpage error bit.

Note that the error propagation for superblock writes that work on the
block device mapping still uses PageError for now, but that will be
addressed in a separate series.

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/compression.c
fs/btrfs/extent_io.c
fs/btrfs/inode.c
fs/btrfs/subpage.c
fs/btrfs/subpage.h

index 04cd5de..bb2d1a4 100644 (file)
@@ -211,8 +211,6 @@ static noinline void end_compressed_writeback(const struct compressed_bio *cb)
                for (i = 0; i < ret; i++) {
                        struct folio *folio = fbatch.folios[i];
 
-                       if (errno)
-                               folio_set_error(folio);
                        btrfs_page_clamp_clear_writeback(fs_info, &folio->page,
                                                         cb->start, cb->len);
                }
index 33e5f0a..b7f26a4 100644 (file)
@@ -223,8 +223,6 @@ static int process_one_page(struct btrfs_fs_info *fs_info,
 
        if (page_ops & PAGE_SET_ORDERED)
                btrfs_page_clamp_set_ordered(fs_info, page, start, len);
-       if (page_ops & PAGE_SET_ERROR)
-               btrfs_page_clamp_set_error(fs_info, page, start, len);
        if (page_ops & PAGE_START_WRITEBACK) {
                btrfs_page_clamp_clear_dirty(fs_info, page, start, len);
                btrfs_page_clamp_set_writeback(fs_info, page, start, len);
@@ -497,12 +495,10 @@ static void end_page_read(struct page *page, bool uptodate, u64 start, u32 len)
        ASSERT(page_offset(page) <= start &&
               start + len <= page_offset(page) + PAGE_SIZE);
 
-       if (uptodate && btrfs_verify_page(page, start)) {
+       if (uptodate && btrfs_verify_page(page, start))
                btrfs_page_set_uptodate(fs_info, page, start, len);
-       } else {
+       else
                btrfs_page_clear_uptodate(fs_info, page, start, len);
-               btrfs_page_set_error(fs_info, page, start, len);
-       }
 
        if (!btrfs_is_subpage(fs_info, page))
                unlock_page(page);
@@ -530,7 +526,6 @@ void end_extent_writepage(struct page *page, int err, u64 start, u64 end)
                len = end + 1 - start;
 
                btrfs_page_clear_uptodate(fs_info, page, start, len);
-               btrfs_page_set_error(fs_info, page, start, len);
                ret = err < 0 ? err : -EIO;
                mapping_set_error(page->mapping, ret);
        }
@@ -1059,7 +1054,6 @@ static int btrfs_do_readpage(struct page *page, struct extent_map **em_cached,
        ret = set_page_extent_mapped(page);
        if (ret < 0) {
                unlock_extent(tree, start, end, NULL);
-               btrfs_page_set_error(fs_info, page, start, PAGE_SIZE);
                unlock_page(page);
                return ret;
        }
@@ -1263,11 +1257,9 @@ static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode,
                }
                ret = btrfs_run_delalloc_range(inode, page, delalloc_start,
                                delalloc_end, &page_started, &nr_written, wbc);
-               if (ret) {
-                       btrfs_page_set_error(inode->root->fs_info, page,
-                                            page_offset(page), PAGE_SIZE);
+               if (ret)
                        return ret;
-               }
+
                /*
                 * delalloc_end is already one less than the total length, so
                 * we don't subtract one from PAGE_SIZE
@@ -1420,7 +1412,6 @@ static noinline_for_stack int __extent_writepage_io(struct btrfs_inode *inode,
 
                em = btrfs_get_extent(inode, NULL, 0, cur, end - cur + 1);
                if (IS_ERR(em)) {
-                       btrfs_page_set_error(fs_info, page, cur, end - cur + 1);
                        ret = PTR_ERR_OR_ZERO(em);
                        goto out_error;
                }
@@ -1519,9 +1510,6 @@ static int __extent_writepage(struct page *page, struct btrfs_bio_ctrl *bio_ctrl
 
        WARN_ON(!PageLocked(page));
 
-       btrfs_page_clear_error(btrfs_sb(inode->i_sb), page,
-                              page_offset(page), PAGE_SIZE);
-
        pg_offset = offset_in_page(i_size);
        if (page->index > end_index ||
           (page->index == end_index && !pg_offset)) {
@@ -1534,10 +1522,8 @@ static int __extent_writepage(struct page *page, struct btrfs_bio_ctrl *bio_ctrl
                memzero_page(page, pg_offset, PAGE_SIZE - pg_offset);
 
        ret = set_page_extent_mapped(page);
-       if (ret < 0) {
-               SetPageError(page);
+       if (ret < 0)
                goto done;
-       }
 
        if (!bio_ctrl->extent_locked) {
                ret = writepage_delalloc(BTRFS_I(inode), page, bio_ctrl->wbc);
index 4633cca..14e9aa9 100644 (file)
@@ -1153,8 +1153,6 @@ static int submit_uncompressed_range(struct btrfs_inode *inode,
                        const u64 page_start = page_offset(locked_page);
                        const u64 page_end = page_start + PAGE_SIZE - 1;
 
-                       btrfs_page_set_error(inode->root->fs_info, locked_page,
-                                            page_start, PAGE_SIZE);
                        set_page_writeback(locked_page);
                        end_page_writeback(locked_page);
                        end_extent_writepage(locked_page, ret, page_start, page_end);
@@ -2942,7 +2940,6 @@ out_page:
                mapping_set_error(page->mapping, ret);
                end_extent_writepage(page, ret, page_start, page_end);
                clear_page_dirty_for_io(page);
-               SetPageError(page);
        }
        btrfs_page_clear_checked(inode->root->fs_info, page, page_start, PAGE_SIZE);
        unlock_page(page);
index 74bc430..1b999c6 100644 (file)
@@ -100,9 +100,6 @@ void btrfs_init_subpage_info(struct btrfs_subpage_info *subpage_info, u32 sector
        subpage_info->uptodate_offset = cur;
        cur += nr_bits;
 
-       subpage_info->error_offset = cur;
-       cur += nr_bits;
-
        subpage_info->dirty_offset = cur;
        cur += nr_bits;
 
@@ -416,35 +413,6 @@ void btrfs_subpage_clear_uptodate(const struct btrfs_fs_info *fs_info,
        spin_unlock_irqrestore(&subpage->lock, flags);
 }
 
-void btrfs_subpage_set_error(const struct btrfs_fs_info *fs_info,
-               struct page *page, u64 start, u32 len)
-{
-       struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
-       unsigned int start_bit = subpage_calc_start_bit(fs_info, page,
-                                                       error, start, len);
-       unsigned long flags;
-
-       spin_lock_irqsave(&subpage->lock, flags);
-       bitmap_set(subpage->bitmaps, start_bit, len >> fs_info->sectorsize_bits);
-       SetPageError(page);
-       spin_unlock_irqrestore(&subpage->lock, flags);
-}
-
-void btrfs_subpage_clear_error(const struct btrfs_fs_info *fs_info,
-               struct page *page, u64 start, u32 len)
-{
-       struct btrfs_subpage *subpage = (struct btrfs_subpage *)page->private;
-       unsigned int start_bit = subpage_calc_start_bit(fs_info, page,
-                                                       error, start, len);
-       unsigned long flags;
-
-       spin_lock_irqsave(&subpage->lock, flags);
-       bitmap_clear(subpage->bitmaps, start_bit, len >> fs_info->sectorsize_bits);
-       if (subpage_test_bitmap_all_zero(fs_info, subpage, error))
-               ClearPageError(page);
-       spin_unlock_irqrestore(&subpage->lock, flags);
-}
-
 void btrfs_subpage_set_dirty(const struct btrfs_fs_info *fs_info,
                struct page *page, u64 start, u32 len)
 {
@@ -606,7 +574,6 @@ bool btrfs_subpage_test_##name(const struct btrfs_fs_info *fs_info, \
        return ret;                                                     \
 }
 IMPLEMENT_BTRFS_SUBPAGE_TEST_OP(uptodate);
-IMPLEMENT_BTRFS_SUBPAGE_TEST_OP(error);
 IMPLEMENT_BTRFS_SUBPAGE_TEST_OP(dirty);
 IMPLEMENT_BTRFS_SUBPAGE_TEST_OP(writeback);
 IMPLEMENT_BTRFS_SUBPAGE_TEST_OP(ordered);
@@ -674,7 +641,6 @@ bool btrfs_page_clamp_test_##name(const struct btrfs_fs_info *fs_info,      \
 }
 IMPLEMENT_BTRFS_PAGE_OPS(uptodate, SetPageUptodate, ClearPageUptodate,
                         PageUptodate);
-IMPLEMENT_BTRFS_PAGE_OPS(error, SetPageError, ClearPageError, PageError);
 IMPLEMENT_BTRFS_PAGE_OPS(dirty, set_page_dirty, clear_page_dirty_for_io,
                         PageDirty);
 IMPLEMENT_BTRFS_PAGE_OPS(writeback, set_page_writeback, end_page_writeback,
@@ -769,7 +735,6 @@ void __cold btrfs_subpage_dump_bitmap(const struct btrfs_fs_info *fs_info,
 
        spin_lock_irqsave(&subpage->lock, flags);
        GET_SUBPAGE_BITMAP(subpage, subpage_info, uptodate, &uptodate_bitmap);
-       GET_SUBPAGE_BITMAP(subpage, subpage_info, error, &error_bitmap);
        GET_SUBPAGE_BITMAP(subpage, subpage_info, dirty, &dirty_bitmap);
        GET_SUBPAGE_BITMAP(subpage, subpage_info, writeback, &writeback_bitmap);
        GET_SUBPAGE_BITMAP(subpage, subpage_info, ordered, &ordered_bitmap);
index 5905cae..5cbf67c 100644 (file)
@@ -8,17 +8,17 @@
 /*
  * Extra info for subpapge bitmap.
  *
- * For subpage we pack all uptodate/error/dirty/writeback/ordered bitmaps into
+ * For subpage we pack all uptodate/dirty/writeback/ordered bitmaps into
  * one larger bitmap.
  *
  * This structure records how they are organized in the bitmap:
  *
- * /- uptodate_offset  /- error_offset /- dirty_offset
+ * /- uptodate_offset  /- dirty_offset /- ordered_offset
  * |                   |               |
  * v                   v               v
- * |u|u|u|u|........|u|u|e|e|.......|e|e| ...  |o|o|
+ * |u|u|u|u|........|u|u|d|d|.......|d|d|o|o|.......|o|o|
  * |<- bitmap_nr_bits ->|
- * |<--------------- total_nr_bits ---------------->|
+ * |<----------------- total_nr_bits ------------------>|
  */
 struct btrfs_subpage_info {
        /* Number of bits for each bitmap */
@@ -32,7 +32,6 @@ struct btrfs_subpage_info {
         * @bitmap_size, which is calculated from PAGE_SIZE / sectorsize.
         */
        unsigned int uptodate_offset;
-       unsigned int error_offset;
        unsigned int dirty_offset;
        unsigned int writeback_offset;
        unsigned int ordered_offset;
@@ -141,7 +140,6 @@ bool btrfs_page_clamp_test_##name(const struct btrfs_fs_info *fs_info,      \
                struct page *page, u64 start, u32 len);
 
 DECLARE_BTRFS_SUBPAGE_OPS(uptodate);
-DECLARE_BTRFS_SUBPAGE_OPS(error);
 DECLARE_BTRFS_SUBPAGE_OPS(dirty);
 DECLARE_BTRFS_SUBPAGE_OPS(writeback);
 DECLARE_BTRFS_SUBPAGE_OPS(ordered);