diff mbox series

[07/14] btrfs: extent_io: make set/clear_extent_buffer_uptodate() to support subpage size

Message ID 20201118085319.56668-8-wqu@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs: add read-only support for subpage sector size | expand

Commit Message

Qu Wenruo Nov. 18, 2020, 8:53 a.m. UTC
For those functions, to support subpage size they just need the follow work:
- set/clear uptodate bitmap
- set page Uptodate if the full range of the page is uptodate

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/extent_io.c | 40 ++++++++++++++++++++++++++++++++++++----
 fs/btrfs/extent_io.h |  1 +
 2 files changed, 37 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 090acf0e6a59..b3edd7fba5c8 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -5663,10 +5663,24 @@  bool set_extent_buffer_dirty(struct extent_buffer *eb)
 
 void clear_extent_buffer_uptodate(struct extent_buffer *eb)
 {
-	int i;
-	struct page *page;
+	struct btrfs_fs_info *fs_info = eb->fs_info;
+	struct page *page = eb->pages[0];
 	int num_pages;
+	int i;
+
+	if (btrfs_is_subpage(fs_info)) {
+		struct btrfs_subpage *subpage;
+		int bit_start = (eb->start - page_offset(page)) >>
+				fs_info->sectorsize_bits;
+		int nbits = fs_info->nodesize >>
+				fs_info->sectorsize_bits;
 
+		subpage = (struct btrfs_subpage *)page->private;
+
+		spin_lock_bh(&subpage->lock);
+		bitmap_clear(subpage->uptodate_bitmap, bit_start, nbits);
+		spin_unlock_bh(&subpage->lock);
+	}
 	clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
 	num_pages = num_extent_pages(eb);
 	for (i = 0; i < num_pages; i++) {
@@ -5678,11 +5692,29 @@  void clear_extent_buffer_uptodate(struct extent_buffer *eb)
 
 void set_extent_buffer_uptodate(struct extent_buffer *eb)
 {
-	int i;
-	struct page *page;
+	struct btrfs_fs_info *fs_info = eb->fs_info;
+	struct page *page = eb->pages[0];
 	int num_pages;
+	int i;
 
 	set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
+	if (btrfs_is_subpage(fs_info)) {
+		struct btrfs_subpage *subpage;
+		int bit_start = (eb->start - page_offset(page)) >>
+				fs_info->sectorsize_bits;
+		int nbits = fs_info->nodesize >>
+				fs_info->sectorsize_bits;
+
+		subpage = (struct btrfs_subpage *)page->private;
+
+		spin_lock_bh(&subpage->lock);
+		bitmap_set(subpage->uptodate_bitmap, bit_start, nbits);
+		if (bitmap_full(subpage->uptodate_bitmap,
+				BTRFS_SUBPAGE_BITMAP_SIZE))
+			SetPageUptodate(page);
+		spin_unlock_bh(&subpage->lock);
+		return;
+	}
 	num_pages = num_extent_pages(eb);
 	for (i = 0; i < num_pages; i++) {
 		page = eb->pages[i];
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 4251bef25aac..11e1e013cb8c 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -311,6 +311,7 @@  blk_status_t btrfs_submit_read_repair(struct inode *inode,
 struct btrfs_subpage {
 	spinlock_t lock;
 	DECLARE_BITMAP(tree_block_bitmap, BTRFS_SUBPAGE_BITMAP_SIZE);
+	DECLARE_BITMAP(uptodate_bitmap, BTRFS_SUBPAGE_BITMAP_SIZE);
 };
 
 int btrfs_attach_subpage(struct btrfs_fs_info *fs_info, struct page *page);