forked from mirrors/linux
		
	btrfs: add extra warning if delayed iput is added when it's not allowed
Since I have triggered the ASSERT() on the delayed iput too many times, now is the time to add some extra debug warnings for delayed iput. All delayed iputs should be queued after all ordered extents finish their IO and all involved workqueues are flushed. Thus after the btrfs_run_delayed_iputs() inside close_ctree(), there should be no more delayed puts added. So introduce a new BTRFS_FS_STATE_NO_DELAYED_IPUT, set after the above mentioned timing. And all btrfs_add_delayed_iput() will check that flag and give a WARN_ON_ONCE(). Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
		
							parent
							
								
									0aaaf10ae9
								
							
						
					
					
						commit
						19e60b2a95
					
				
					 3 changed files with 6 additions and 0 deletions
				
			
		|  | @ -4397,6 +4397,8 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info) | ||||||
| 	/* Ordered extents for free space inodes. */ | 	/* Ordered extents for free space inodes. */ | ||||||
| 	btrfs_flush_workqueue(fs_info->endio_freespace_worker); | 	btrfs_flush_workqueue(fs_info->endio_freespace_worker); | ||||||
| 	btrfs_run_delayed_iputs(fs_info); | 	btrfs_run_delayed_iputs(fs_info); | ||||||
|  | 	/* There should be no more workload to generate new delayed iputs. */ | ||||||
|  | 	set_bit(BTRFS_FS_STATE_NO_DELAYED_IPUT, &fs_info->fs_state); | ||||||
| 
 | 
 | ||||||
| 	cancel_work_sync(&fs_info->async_reclaim_work); | 	cancel_work_sync(&fs_info->async_reclaim_work); | ||||||
| 	cancel_work_sync(&fs_info->async_data_reclaim_work); | 	cancel_work_sync(&fs_info->async_data_reclaim_work); | ||||||
|  |  | ||||||
|  | @ -117,6 +117,9 @@ enum { | ||||||
| 	/* Indicates there was an error cleaning up a log tree. */ | 	/* Indicates there was an error cleaning up a log tree. */ | ||||||
| 	BTRFS_FS_STATE_LOG_CLEANUP_ERROR, | 	BTRFS_FS_STATE_LOG_CLEANUP_ERROR, | ||||||
| 
 | 
 | ||||||
|  | 	/* No more delayed iput can be queued. */ | ||||||
|  | 	BTRFS_FS_STATE_NO_DELAYED_IPUT, | ||||||
|  | 
 | ||||||
| 	BTRFS_FS_STATE_COUNT | 	BTRFS_FS_STATE_COUNT | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -3427,6 +3427,7 @@ void btrfs_add_delayed_iput(struct btrfs_inode *inode) | ||||||
| 	if (atomic_add_unless(&inode->vfs_inode.i_count, -1, 1)) | 	if (atomic_add_unless(&inode->vfs_inode.i_count, -1, 1)) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
|  | 	WARN_ON_ONCE(test_bit(BTRFS_FS_STATE_NO_DELAYED_IPUT, &fs_info->fs_state)); | ||||||
| 	atomic_inc(&fs_info->nr_delayed_iputs); | 	atomic_inc(&fs_info->nr_delayed_iputs); | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Need to be irq safe here because we can be called from either an irq | 	 * Need to be irq safe here because we can be called from either an irq | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Qu Wenruo
						Qu Wenruo