mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-03 18:20:25 +02:00 
			
		
		
		
	btrfs: add extra sanity checks for create_io_em()
The function create_io_em() is called before we submit an IO, to update
the in-memory extent map for the involved range.
This patch changes the following aspects:
- Does not allow BTRFS_ORDERED_NOCOW type
  For real NOCOW (excluding NOCOW writes into preallocated ranges)
  writes, we never call create_io_em(), as we does not need to update
  the extent map at all.
  So remove the sanity check allowing BTRFS_ORDERED_NOCOW type.
- Add extra sanity checks
  * PREALLOC
    - @block_len == len
      For uncompressed writes.
  * REGULAR
    - @block_len == @orig_block_len == @ram_bytes == @len
      We're creating a new uncompressed extent, and referring all of it.
    - @orig_start == @start
      We haven no offset inside the extent.
  * COMPRESSED
    - valid @compress_type
    - @len <= @ram_bytes
      This is to co-operate with encoded writes, which can cause a new
      file extent referring only part of a uncompressed extent.
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
							
								
									4bdc558bf9
								
							
						
					
					
						commit
						e98bf64f7a
					
				
					 1 changed files with 39 additions and 1 deletions
				
			
		| 
						 | 
					@ -7258,11 +7258,49 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
 | 
				
			||||||
	struct extent_map *em;
 | 
						struct extent_map *em;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Note the missing NOCOW type.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * For pure NOCOW writes, we should not create an io extent map, but
 | 
				
			||||||
 | 
						 * just reusing the existing one.
 | 
				
			||||||
 | 
						 * Only PREALLOC writes (NOCOW write into preallocated range) can
 | 
				
			||||||
 | 
						 * create an io extent map.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	ASSERT(type == BTRFS_ORDERED_PREALLOC ||
 | 
						ASSERT(type == BTRFS_ORDERED_PREALLOC ||
 | 
				
			||||||
	       type == BTRFS_ORDERED_COMPRESSED ||
 | 
						       type == BTRFS_ORDERED_COMPRESSED ||
 | 
				
			||||||
	       type == BTRFS_ORDERED_NOCOW ||
 | 
					 | 
				
			||||||
	       type == BTRFS_ORDERED_REGULAR);
 | 
						       type == BTRFS_ORDERED_REGULAR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (type) {
 | 
				
			||||||
 | 
						case BTRFS_ORDERED_PREALLOC:
 | 
				
			||||||
 | 
							/* Uncompressed extents. */
 | 
				
			||||||
 | 
							ASSERT(block_len == len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* We're only referring part of a larger preallocated extent. */
 | 
				
			||||||
 | 
							ASSERT(block_len <= ram_bytes);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case BTRFS_ORDERED_REGULAR:
 | 
				
			||||||
 | 
							/* Uncompressed extents. */
 | 
				
			||||||
 | 
							ASSERT(block_len == len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* COW results a new extent matching our file extent size. */
 | 
				
			||||||
 | 
							ASSERT(orig_block_len == len);
 | 
				
			||||||
 | 
							ASSERT(ram_bytes == len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Since it's a new extent, we should not have any offset. */
 | 
				
			||||||
 | 
							ASSERT(orig_start == start);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case BTRFS_ORDERED_COMPRESSED:
 | 
				
			||||||
 | 
							/* Must be compressed. */
 | 
				
			||||||
 | 
							ASSERT(compress_type != BTRFS_COMPRESS_NONE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Encoded write can make us to refer to part of the
 | 
				
			||||||
 | 
							 * uncompressed extent.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							ASSERT(len <= ram_bytes);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	em = alloc_extent_map();
 | 
						em = alloc_extent_map();
 | 
				
			||||||
	if (!em)
 | 
						if (!em)
 | 
				
			||||||
		return ERR_PTR(-ENOMEM);
 | 
							return ERR_PTR(-ENOMEM);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue