mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	microzap: set hard upper limit of 1M
The count of chunks in a microzap block is stored as an uint16_t (mze_chunkid). Each chunk is 64 bytes, and the first is used to store a header, so there are 32767 usable chunks, which is just under 2M. 1M is the largest power-2-rounded block size under 2M, so we must set the limit there. If it goes higher, the loop in mzap_addent can overflow and fall into the PANIC case. Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Reviewed-by: Alexander Motin <mav@FreeBSD.org> Signed-off-by: Rob Norris <rob.norris@klarasystems.com> Closes #16888
This commit is contained in:
		
							parent
							
								
									1acd246964
								
							
						
					
					
						commit
						c37a2ddaaa
					
				@ -54,14 +54,25 @@
 | 
				
			|||||||
 * machinery to understand not to try to split a microzap block).
 | 
					 * machinery to understand not to try to split a microzap block).
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * If large_microzap is enabled, this value will be clamped to
 | 
					 * If large_microzap is enabled, this value will be clamped to
 | 
				
			||||||
 * spa_maxblocksize(). If not, it will be clamped to SPA_OLD_MAXBLOCKSIZE.
 | 
					 * spa_maxblocksize(), up to 1M. If not, it will be clamped to
 | 
				
			||||||
 | 
					 * SPA_OLD_MAXBLOCKSIZE.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int zap_micro_max_size = SPA_OLD_MAXBLOCKSIZE;
 | 
					static int zap_micro_max_size = SPA_OLD_MAXBLOCKSIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * The 1M upper limit is necessary because the count of chunks in a microzap
 | 
				
			||||||
 | 
					 * block is stored as a uint16_t (mze_chunkid). Each chunk is 64 bytes, and the
 | 
				
			||||||
 | 
					 * first is used to store a header, so there are 32767 usable chunks, which is
 | 
				
			||||||
 | 
					 * just under 2M. 1M is the largest power-2-rounded block size under 2M, so we
 | 
				
			||||||
 | 
					 * must set the limit there.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define	MZAP_MAX_SIZE	(1048576)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint64_t
 | 
					uint64_t
 | 
				
			||||||
zap_get_micro_max_size(spa_t *spa)
 | 
					zap_get_micro_max_size(spa_t *spa)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint64_t maxsz = P2ROUNDUP(zap_micro_max_size, SPA_MINBLOCKSIZE);
 | 
						uint64_t maxsz = MIN(MZAP_MAX_SIZE,
 | 
				
			||||||
 | 
						    P2ROUNDUP(zap_micro_max_size, SPA_MINBLOCKSIZE));
 | 
				
			||||||
	if (maxsz <= SPA_OLD_MAXBLOCKSIZE)
 | 
						if (maxsz <= SPA_OLD_MAXBLOCKSIZE)
 | 
				
			||||||
		return (maxsz);
 | 
							return (maxsz);
 | 
				
			||||||
	if (spa_feature_is_enabled(spa, SPA_FEATURE_LARGE_MICROZAP))
 | 
						if (spa_feature_is_enabled(spa, SPA_FEATURE_LARGE_MICROZAP))
 | 
				
			||||||
@ -2031,5 +2042,6 @@ EXPORT_SYMBOL(zap_cursor_init_serialized);
 | 
				
			|||||||
EXPORT_SYMBOL(zap_get_stats);
 | 
					EXPORT_SYMBOL(zap_get_stats);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ZFS_MODULE_PARAM(zfs, , zap_micro_max_size, INT, ZMOD_RW,
 | 
					ZFS_MODULE_PARAM(zfs, , zap_micro_max_size, INT, ZMOD_RW,
 | 
				
			||||||
	"Maximum micro ZAP size, before converting to a fat ZAP, in bytes");
 | 
						"Maximum micro ZAP size before converting to a fat ZAP, "
 | 
				
			||||||
 | 
						    "in bytes (max 1M)");
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user