forked from mirrors/linux
		
	Btrfs: fix divide error upon chunk's stripe_len
The struct 'map_lookup' uses type int for @stripe_len, while btrfs_chunk_stripe_len() can return a u64 value, and it may end up with @stripe_len being undefined value and it can lead to 'divide error' in __btrfs_map_block(). This changes 'map_lookup' to use type u64 for stripe_len, also right now we only use BTRFS_STRIPE_LEN for stripe_len, so this adds a valid checker for BTRFS_STRIPE_LEN. Reported-by: Vegard Nossum <vegard.nossum@oracle.com> Reported-by: Quentin Casasnovas <quentin.casasnovas@oracle.com> Signed-off-by: Liu Bo <bo.li.liu@oracle.com> Reviewed-by: David Sterba <dsterba@suse.com> [ folded division fix to scrub_raid56_parity ] Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
		
							parent
							
								
									ee17fc8005
								
							
						
					
					
						commit
						3d8da67817
					
				
					 3 changed files with 3 additions and 3 deletions
				
			
		| 
						 | 
					@ -2860,7 +2860,7 @@ static noinline_for_stack int scrub_raid56_parity(struct scrub_ctx *sctx,
 | 
				
			||||||
	int extent_mirror_num;
 | 
						int extent_mirror_num;
 | 
				
			||||||
	int stop_loop = 0;
 | 
						int stop_loop = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nsectors = map->stripe_len / root->sectorsize;
 | 
						nsectors = div_u64(map->stripe_len, root->sectorsize);
 | 
				
			||||||
	bitmap_len = scrub_calc_parity_bitmap_len(nsectors);
 | 
						bitmap_len = scrub_calc_parity_bitmap_len(nsectors);
 | 
				
			||||||
	sparity = kzalloc(sizeof(struct scrub_parity) + 2 * bitmap_len,
 | 
						sparity = kzalloc(sizeof(struct scrub_parity) + 2 * bitmap_len,
 | 
				
			||||||
			  GFP_NOFS);
 | 
								  GFP_NOFS);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6254,7 +6254,7 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
 | 
				
			||||||
			"invalid chunk length %llu", length);
 | 
								"invalid chunk length %llu", length);
 | 
				
			||||||
		return -EIO;
 | 
							return -EIO;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (!is_power_of_2(stripe_len)) {
 | 
						if (!is_power_of_2(stripe_len) || stripe_len != BTRFS_STRIPE_LEN) {
 | 
				
			||||||
		btrfs_err(root->fs_info, "invalid chunk stripe length: %llu",
 | 
							btrfs_err(root->fs_info, "invalid chunk stripe length: %llu",
 | 
				
			||||||
			  stripe_len);
 | 
								  stripe_len);
 | 
				
			||||||
		return -EIO;
 | 
							return -EIO;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -347,7 +347,7 @@ struct map_lookup {
 | 
				
			||||||
	u64 type;
 | 
						u64 type;
 | 
				
			||||||
	int io_align;
 | 
						int io_align;
 | 
				
			||||||
	int io_width;
 | 
						int io_width;
 | 
				
			||||||
	int stripe_len;
 | 
						u64 stripe_len;
 | 
				
			||||||
	int sector_size;
 | 
						int sector_size;
 | 
				
			||||||
	int num_stripes;
 | 
						int num_stripes;
 | 
				
			||||||
	int sub_stripes;
 | 
						int sub_stripes;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue