forked from mirrors/linux
		
	btrfs: log messages at unpin_extent_range() during unexpected cases
At unpin_extent_range() we trigger a WARN_ON() when we don't find an extent map or we find one with a start offset not matching the start offset of the target range. This however isn't very useful for debugging because: 1) We don't know which condition was triggered, as they are both in the same WARN_ON() call; 2) We don't know which inode was affected, from which root, for which range, what's the start offset of the extent map, and so on. So trigger a separate warning for each case and log a message for each case providing information about the inode, its root, the target range, the generation and the start offset of the extent map we found. Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
		
							parent
							
								
									d224d2ef95
								
							
						
					
					
						commit
						00deaf04df
					
				
					 3 changed files with 18 additions and 8 deletions
				
			
		| 
						 | 
					@ -280,7 +280,7 @@ static void try_merge_map(struct extent_map_tree *tree, struct extent_map *em)
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Unpin an extent from the cache.
 | 
					 * Unpin an extent from the cache.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @tree:	tree to unpin the extent in
 | 
					 * @inode:	the inode from which we are unpinning an extent range
 | 
				
			||||||
 * @start:	logical offset in the file
 | 
					 * @start:	logical offset in the file
 | 
				
			||||||
 * @len:	length of the extent
 | 
					 * @len:	length of the extent
 | 
				
			||||||
 * @gen:	generation that this extent has been modified in
 | 
					 * @gen:	generation that this extent has been modified in
 | 
				
			||||||
| 
						 | 
					@ -289,9 +289,10 @@ static void try_merge_map(struct extent_map_tree *tree, struct extent_map *em)
 | 
				
			||||||
 * to the generation that actually added the file item to the inode so we know
 | 
					 * to the generation that actually added the file item to the inode so we know
 | 
				
			||||||
 * we need to sync this extent when we call fsync().
 | 
					 * we need to sync this extent when we call fsync().
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len,
 | 
					int unpin_extent_cache(struct btrfs_inode *inode, u64 start, u64 len, u64 gen)
 | 
				
			||||||
		       u64 gen)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct btrfs_fs_info *fs_info = inode->root->fs_info;
 | 
				
			||||||
 | 
						struct extent_map_tree *tree = &inode->extent_tree;
 | 
				
			||||||
	int ret = 0;
 | 
						int ret = 0;
 | 
				
			||||||
	struct extent_map *em;
 | 
						struct extent_map *em;
 | 
				
			||||||
	bool prealloc = false;
 | 
						bool prealloc = false;
 | 
				
			||||||
| 
						 | 
					@ -299,10 +300,19 @@ int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len,
 | 
				
			||||||
	write_lock(&tree->lock);
 | 
						write_lock(&tree->lock);
 | 
				
			||||||
	em = lookup_extent_mapping(tree, start, len);
 | 
						em = lookup_extent_mapping(tree, start, len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	WARN_ON(!em || em->start != start);
 | 
						if (WARN_ON(!em)) {
 | 
				
			||||||
 | 
							btrfs_warn(fs_info,
 | 
				
			||||||
	if (!em)
 | 
					"no extent map found for inode %llu (root %lld) when unpinning extent range [%llu, %llu), generation %llu",
 | 
				
			||||||
 | 
								   btrfs_ino(inode), btrfs_root_id(inode->root),
 | 
				
			||||||
 | 
								   start, len, gen);
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (WARN_ON(em->start != start))
 | 
				
			||||||
 | 
							btrfs_warn(fs_info,
 | 
				
			||||||
 | 
					"found extent map for inode %llu (root %lld) with unexpected start offset %llu when unpinning extent range [%llu, %llu), generation %llu",
 | 
				
			||||||
 | 
								   btrfs_ino(inode), btrfs_root_id(inode->root),
 | 
				
			||||||
 | 
								   em->start, start, len, gen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	em->generation = gen;
 | 
						em->generation = gen;
 | 
				
			||||||
	clear_bit(EXTENT_FLAG_PINNED, &em->flags);
 | 
						clear_bit(EXTENT_FLAG_PINNED, &em->flags);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,7 +82,7 @@ struct extent_map *alloc_extent_map(void);
 | 
				
			||||||
void free_extent_map(struct extent_map *em);
 | 
					void free_extent_map(struct extent_map *em);
 | 
				
			||||||
int __init extent_map_init(void);
 | 
					int __init extent_map_init(void);
 | 
				
			||||||
void __cold extent_map_exit(void);
 | 
					void __cold extent_map_exit(void);
 | 
				
			||||||
int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, u64 gen);
 | 
					int unpin_extent_cache(struct btrfs_inode *inode, u64 start, u64 len, u64 gen);
 | 
				
			||||||
void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em);
 | 
					void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em);
 | 
				
			||||||
struct extent_map *search_extent_mapping(struct extent_map_tree *tree,
 | 
					struct extent_map *search_extent_mapping(struct extent_map_tree *tree,
 | 
				
			||||||
					 u64 start, u64 len);
 | 
										 u64 start, u64 len);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3127,7 +3127,7 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent)
 | 
				
			||||||
						ordered_extent->disk_num_bytes);
 | 
											ordered_extent->disk_num_bytes);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	unpin_extent_cache(&inode->extent_tree, ordered_extent->file_offset,
 | 
						unpin_extent_cache(inode, ordered_extent->file_offset,
 | 
				
			||||||
			   ordered_extent->num_bytes, trans->transid);
 | 
								   ordered_extent->num_bytes, trans->transid);
 | 
				
			||||||
	if (ret < 0) {
 | 
						if (ret < 0) {
 | 
				
			||||||
		btrfs_abort_transaction(trans, ret);
 | 
							btrfs_abort_transaction(trans, ret);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue