Commit 38a39ac7 authored by Qu Wenruo's avatar Qu Wenruo Committed by David Sterba
Browse files

btrfs: pass btrfs_inode to btrfs_writepage_endio_finish_ordered()



There is a pretty bad abuse of btrfs_writepage_endio_finish_ordered() in
end_compressed_bio_write().

It passes compressed pages to btrfs_writepage_endio_finish_ordered(),
which is only supposed to accept inode pages.

Thankfully the important info here is the inode, so let's pass
btrfs_inode directly into btrfs_writepage_endio_finish_ordered(), and
make @page parameter optional.

By this, end_compressed_bio_write() can happily pass page=NULL while
still getting everything done properly.

Also, to cooperate with such modification, replace @page parameter for
trace_btrfs_writepage_end_io_hook() with btrfs_inode.
Although this removes page_index info, the existing start/len should be
enough for most usage.

Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent fa04c165
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -349,12 +349,10 @@ static void end_compressed_bio_write(struct bio *bio)
	 * call back into the FS and do all the end_io operations
	 */
	inode = cb->inode;
	cb->compressed_pages[0]->mapping = cb->inode->i_mapping;
	btrfs_record_physical_zoned(inode, cb->start, bio);
	btrfs_writepage_endio_finish_ordered(cb->compressed_pages[0],
	btrfs_writepage_endio_finish_ordered(BTRFS_I(inode), NULL,
			cb->start, cb->start + cb->len - 1,
			bio->bi_status == BLK_STS_OK);
	cb->compressed_pages[0]->mapping = NULL;

	end_compressed_writeback(inode, cb);
	/* note, our inode could be gone now */
+2 −1
Original line number Diff line number Diff line
@@ -3196,7 +3196,8 @@ int btrfs_run_delalloc_range(struct btrfs_inode *inode, struct page *locked_page
		u64 start, u64 end, int *page_started, unsigned long *nr_written,
		struct writeback_control *wbc);
int btrfs_writepage_cow_fixup(struct page *page, u64 start, u64 end);
void btrfs_writepage_endio_finish_ordered(struct page *page, u64 start,
void btrfs_writepage_endio_finish_ordered(struct btrfs_inode *inode,
					  struct page *page, u64 start,
					  u64 end, int uptodate);
extern const struct dentry_operations btrfs_dentry_operations;
extern const struct iomap_ops btrfs_dio_iomap_ops;
+10 −6
Original line number Diff line number Diff line
@@ -2756,10 +2756,13 @@ static blk_status_t submit_read_repair(struct inode *inode,

void end_extent_writepage(struct page *page, int err, u64 start, u64 end)
{
	struct btrfs_inode *inode;
	int uptodate = (err == 0);
	int ret = 0;

	btrfs_writepage_endio_finish_ordered(page, start, end, uptodate);
	ASSERT(page && page->mapping);
	inode = BTRFS_I(page->mapping->host);
	btrfs_writepage_endio_finish_ordered(inode, page, start, end, uptodate);

	if (!uptodate) {
		ClearPageUptodate(page);
@@ -3794,7 +3797,8 @@ static noinline_for_stack int __extent_writepage_io(struct btrfs_inode *inode,
		u32 iosize;

		if (cur >= i_size) {
			btrfs_writepage_endio_finish_ordered(page, cur, end, 1);
			btrfs_writepage_endio_finish_ordered(inode, page, cur,
							     end, 1);
			break;
		}
		em = btrfs_get_extent(inode, NULL, 0, cur, end - cur + 1);
@@ -3832,8 +3836,8 @@ static noinline_for_stack int __extent_writepage_io(struct btrfs_inode *inode,
			if (compressed)
				nr++;
			else
				btrfs_writepage_endio_finish_ordered(page, cur,
							cur + iosize - 1, 1);
				btrfs_writepage_endio_finish_ordered(inode,
						page, cur, cur + iosize - 1, 1);
			cur += iosize;
			continue;
		}
@@ -4892,8 +4896,8 @@ int extent_write_locked_range(struct inode *inode, u64 start, u64 end,
		if (clear_page_dirty_for_io(page))
			ret = __extent_writepage(page, &wbc_writepages, &epd);
		else {
			btrfs_writepage_endio_finish_ordered(page, start,
						    start + PAGE_SIZE - 1, 1);
			btrfs_writepage_endio_finish_ordered(BTRFS_I(inode),
					page, start, start + PAGE_SIZE - 1, 1);
			unlock_page(page);
		}
		put_page(page);
+5 −4
Original line number Diff line number Diff line
@@ -946,7 +946,8 @@ static noinline void submit_compressed_extents(struct async_chunk *async_chunk)
			const u64 end = start + async_extent->ram_size - 1;

			p->mapping = inode->vfs_inode.i_mapping;
			btrfs_writepage_endio_finish_ordered(p, start, end, 0);
			btrfs_writepage_endio_finish_ordered(inode, p, start,
							     end, 0);

			p->mapping = NULL;
			extent_clear_unlock_delalloc(inode, start, end, NULL, 0,
@@ -3038,15 +3039,15 @@ static void finish_ordered_fn(struct btrfs_work *work)
	btrfs_finish_ordered_io(ordered_extent);
}

void btrfs_writepage_endio_finish_ordered(struct page *page, u64 start,
void btrfs_writepage_endio_finish_ordered(struct btrfs_inode *inode,
					  struct page *page, u64 start,
					  u64 end, int uptodate)
{
	struct btrfs_inode *inode = BTRFS_I(page->mapping->host);
	struct btrfs_fs_info *fs_info = inode->root->fs_info;
	struct btrfs_ordered_extent *ordered_extent = NULL;
	struct btrfs_workqueue *wq;

	trace_btrfs_writepage_end_io_hook(page, start, end, uptodate);
	trace_btrfs_writepage_end_io_hook(inode, start, end, uptodate);

	ClearPagePrivate2(page);
	if (!btrfs_dec_test_ordered_pending(inode, &ordered_extent, start,
+8 −12
Original line number Diff line number Diff line
@@ -654,34 +654,30 @@ DEFINE_EVENT(btrfs__writepage, __extent_writepage,

TRACE_EVENT(btrfs_writepage_end_io_hook,

	TP_PROTO(const struct page *page, u64 start, u64 end, int uptodate),
	TP_PROTO(const struct btrfs_inode *inode, u64 start, u64 end,
		 int uptodate),

	TP_ARGS(page, start, end, uptodate),
	TP_ARGS(inode, start, end, uptodate),

	TP_STRUCT__entry_btrfs(
		__field(	u64,	 ino		)
		__field(	unsigned long, index	)
		__field(	u64,	 start		)
		__field(	u64,	 end		)
		__field(	int,	 uptodate	)
		__field(	u64,    root_objectid	)
	),

	TP_fast_assign_btrfs(btrfs_sb(page->mapping->host->i_sb),
		__entry->ino	= btrfs_ino(BTRFS_I(page->mapping->host));
		__entry->index	= page->index;
	TP_fast_assign_btrfs(inode->root->fs_info,
		__entry->ino	= btrfs_ino(inode);
		__entry->start	= start;
		__entry->end	= end;
		__entry->uptodate = uptodate;
		__entry->root_objectid	=
			 BTRFS_I(page->mapping->host)->root->root_key.objectid;
		__entry->root_objectid = inode->root->root_key.objectid;
	),

	TP_printk_btrfs("root=%llu(%s) ino=%llu page_index=%lu start=%llu "
		  "end=%llu uptodate=%d",
	TP_printk_btrfs("root=%llu(%s) ino=%llu start=%llu end=%llu uptodate=%d",
		  show_root_type(__entry->root_objectid),
		  __entry->ino, __entry->index,
		  __entry->start,
		  __entry->ino, __entry->start,
		  __entry->end, __entry->uptodate)
);