diff options
Diffstat (limited to 'fs/btrfs/subpage.c')
| -rw-r--r-- | fs/btrfs/subpage.c | 47 | 
1 files changed, 34 insertions, 13 deletions
| diff --git a/fs/btrfs/subpage.c b/fs/btrfs/subpage.c index 8c68059ac1b0..722acf768396 100644 --- a/fs/btrfs/subpage.c +++ b/fs/btrfs/subpage.c @@ -635,6 +635,28 @@ IMPLEMENT_BTRFS_PAGE_OPS(ordered, folio_set_ordered, folio_clear_ordered,  IMPLEMENT_BTRFS_PAGE_OPS(checked, folio_set_checked, folio_clear_checked,  			 folio_test_checked); +#define GET_SUBPAGE_BITMAP(subpage, fs_info, name, dst)			\ +{									\ +	const int sectors_per_page = fs_info->sectors_per_page;		\ +									\ +	ASSERT(sectors_per_page < BITS_PER_LONG);			\ +	*dst = bitmap_read(subpage->bitmaps,				\ +			   sectors_per_page * btrfs_bitmap_nr_##name,	\ +			   sectors_per_page);				\ +} + +#define SUBPAGE_DUMP_BITMAP(fs_info, folio, name, start, len)		\ +{									\ +	const struct btrfs_subpage *subpage = folio_get_private(folio);	\ +	unsigned long bitmap;						\ +									\ +	GET_SUBPAGE_BITMAP(subpage, fs_info, name, &bitmap);		\ +	btrfs_warn(fs_info,						\ +	"dumpping bitmap start=%llu len=%u folio=%llu " #name "_bitmap=%*pbl", \ +		   start, len, folio_pos(folio),			\ +		   fs_info->sectors_per_page, &bitmap);			\ +} +  /*   * Make sure not only the page dirty bit is cleared, but also subpage dirty bit   * is cleared. @@ -660,6 +682,10 @@ void btrfs_folio_assert_not_dirty(const struct btrfs_fs_info *fs_info,  	subpage = folio_get_private(folio);  	ASSERT(subpage);  	spin_lock_irqsave(&subpage->lock, flags); +	if (unlikely(!bitmap_test_range_all_zero(subpage->bitmaps, start_bit, nbits))) { +		SUBPAGE_DUMP_BITMAP(fs_info, folio, dirty, start, len); +		ASSERT(bitmap_test_range_all_zero(subpage->bitmaps, start_bit, nbits)); +	}  	ASSERT(bitmap_test_range_all_zero(subpage->bitmaps, start_bit, nbits));  	spin_unlock_irqrestore(&subpage->lock, flags);  } @@ -689,23 +715,16 @@ void btrfs_folio_set_lock(const struct btrfs_fs_info *fs_info,  	nbits = len >> fs_info->sectorsize_bits;  	spin_lock_irqsave(&subpage->lock, flags);  	/* Target range should not yet be locked. */ -	ASSERT(bitmap_test_range_all_zero(subpage->bitmaps, start_bit, nbits)); +	if (unlikely(!bitmap_test_range_all_zero(subpage->bitmaps, start_bit, nbits))) { +		SUBPAGE_DUMP_BITMAP(fs_info, folio, locked, start, len); +		ASSERT(bitmap_test_range_all_zero(subpage->bitmaps, start_bit, nbits)); +	}  	bitmap_set(subpage->bitmaps, start_bit, nbits);  	ret = atomic_add_return(nbits, &subpage->nr_locked);  	ASSERT(ret <= fs_info->sectors_per_page);  	spin_unlock_irqrestore(&subpage->lock, flags);  } -#define GET_SUBPAGE_BITMAP(subpage, fs_info, name, dst)			\ -{									\ -	const int sectors_per_page = fs_info->sectors_per_page;		\ -									\ -	ASSERT(sectors_per_page < BITS_PER_LONG);			\ -	*dst = bitmap_read(subpage->bitmaps,				\ -			   sectors_per_page * btrfs_bitmap_nr_##name,	\ -			   sectors_per_page);				\ -} -  void __cold btrfs_subpage_dump_bitmap(const struct btrfs_fs_info *fs_info,  				      struct folio *folio, u64 start, u32 len)  { @@ -716,6 +735,7 @@ void __cold btrfs_subpage_dump_bitmap(const struct btrfs_fs_info *fs_info,  	unsigned long writeback_bitmap;  	unsigned long ordered_bitmap;  	unsigned long checked_bitmap; +	unsigned long locked_bitmap;  	unsigned long flags;  	ASSERT(folio_test_private(folio) && folio_get_private(folio)); @@ -728,15 +748,16 @@ void __cold btrfs_subpage_dump_bitmap(const struct btrfs_fs_info *fs_info,  	GET_SUBPAGE_BITMAP(subpage, fs_info, writeback, &writeback_bitmap);  	GET_SUBPAGE_BITMAP(subpage, fs_info, ordered, &ordered_bitmap);  	GET_SUBPAGE_BITMAP(subpage, fs_info, checked, &checked_bitmap); -	GET_SUBPAGE_BITMAP(subpage, fs_info, locked, &checked_bitmap); +	GET_SUBPAGE_BITMAP(subpage, fs_info, locked, &locked_bitmap);  	spin_unlock_irqrestore(&subpage->lock, flags);  	dump_page(folio_page(folio, 0), "btrfs subpage dump");  	btrfs_warn(fs_info, -"start=%llu len=%u page=%llu, bitmaps uptodate=%*pbl dirty=%*pbl writeback=%*pbl ordered=%*pbl checked=%*pbl", +"start=%llu len=%u page=%llu, bitmaps uptodate=%*pbl dirty=%*pbl locked=%*pbl writeback=%*pbl ordered=%*pbl checked=%*pbl",  		    start, len, folio_pos(folio),  		    sectors_per_page, &uptodate_bitmap,  		    sectors_per_page, &dirty_bitmap, +		    sectors_per_page, &locked_bitmap,  		    sectors_per_page, &writeback_bitmap,  		    sectors_per_page, &ordered_bitmap,  		    sectors_per_page, &checked_bitmap); | 
