mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	Add prefetch property
ZFS prefetch is currently governed by the zfs_prefetch_disable tunable. However, this is a module-wide settings - if a specific dataset benefits from prefetch, while others have issue with it, an optimal solution does not exists. This commit introduce the "prefetch" tri-state property, which enable granular control (at dataset/volume level) for prefetching. This patch does not remove the zfs_prefetch_disable, which remains a system-wide switch for enable/disable prefetch. However, to avoid duplication, it would be preferable to deprecate and then remove the module tunable. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Ameer Hamza <ahamza@ixsystems.com> Signed-off-by: Gionatan Danti <g.danti@assyoma.it> Co-authored-by: Gionatan Danti <g.danti@assyoma.it> Closes #15237 Closes #15436
This commit is contained in:
		
							parent
							
								
									706307445e
								
							
						
					
					
						commit
						61f3638a34
					
				| @ -132,6 +132,7 @@ struct objset { | ||||
| 	zfs_logbias_op_t os_logbias; | ||||
| 	zfs_cache_type_t os_primary_cache; | ||||
| 	zfs_cache_type_t os_secondary_cache; | ||||
| 	zfs_prefetch_type_t os_prefetch; | ||||
| 	zfs_sync_type_t os_sync; | ||||
| 	zfs_redundant_metadata_type_t os_redundant_metadata; | ||||
| 	uint64_t os_recordsize; | ||||
|  | ||||
| @ -191,6 +191,7 @@ typedef enum { | ||||
| 	ZFS_PROP_REDACTED, | ||||
| 	ZFS_PROP_REDACT_SNAPS, | ||||
| 	ZFS_PROP_SNAPSHOTS_CHANGED, | ||||
| 	ZFS_PROP_PREFETCH, | ||||
| 	ZFS_NUM_PROPS | ||||
| } zfs_prop_t; | ||||
| 
 | ||||
| @ -546,6 +547,12 @@ typedef enum zfs_key_location { | ||||
| 	ZFS_KEYLOCATION_LOCATIONS | ||||
| } zfs_keylocation_t; | ||||
| 
 | ||||
| typedef enum { | ||||
| 	ZFS_PREFETCH_NONE = 0, | ||||
| 	ZFS_PREFETCH_METADATA = 1, | ||||
| 	ZFS_PREFETCH_ALL = 2 | ||||
| } zfs_prefetch_type_t; | ||||
| 
 | ||||
| #define	DEFAULT_PBKDF2_ITERATIONS 350000 | ||||
| #define	MIN_PBKDF2_ITERATIONS 100000 | ||||
| 
 | ||||
|  | ||||
| @ -1867,7 +1867,8 @@ | ||||
|       <enumerator name='ZFS_PROP_REDACTED' value='93'/> | ||||
|       <enumerator name='ZFS_PROP_REDACT_SNAPS' value='94'/> | ||||
|       <enumerator name='ZFS_PROP_SNAPSHOTS_CHANGED' value='95'/> | ||||
|       <enumerator name='ZFS_NUM_PROPS' value='96'/> | ||||
|       <enumerator name='ZFS_PROP_PREFETCH' value='96'/> | ||||
|       <enumerator name='ZFS_NUM_PROPS' value='97'/> | ||||
|     </enum-decl> | ||||
|     <typedef-decl name='zfs_prop_t' type-id='4b000d60' id='58603c44'/> | ||||
|     <enum-decl name='zprop_source_t' naming-typedef-id='a2256d42' id='5903f80e'> | ||||
|  | ||||
| @ -1613,6 +1613,23 @@ If this property is set to | ||||
| then only metadata is cached. | ||||
| The default value is | ||||
| .Sy all . | ||||
| .It Sy prefetch Ns = Ns Sy all Ns | Ns Sy none Ns | Ns Sy metadata | ||||
| Controls what speculative prefetch does. | ||||
| If this property is set to | ||||
| .Sy all , | ||||
| then both user data and metadata are prefetched. | ||||
| If this property is set to | ||||
| .Sy none , | ||||
| then neither user data nor metadata are prefetched. | ||||
| If this property is set to | ||||
| .Sy metadata , | ||||
| then only metadata are prefetched. | ||||
| The default value is | ||||
| .Sy all . | ||||
| .Pp | ||||
| Please note that the module parameter zfs_disable_prefetch=1 can | ||||
| be used to totally disable speculative prefetch, bypassing anything | ||||
| this property does. | ||||
| .It Sy setuid Ns = Ns Sy on Ns | Ns Sy off | ||||
| Controls whether the setuid bit is respected for the file system. | ||||
| The default value is | ||||
|  | ||||
| @ -345,6 +345,13 @@ zfs_prop_init(void) | ||||
| 		{ NULL } | ||||
| 	}; | ||||
| 
 | ||||
| 	static const zprop_index_t prefetch_table[] = { | ||||
| 		{ "none",	ZFS_PREFETCH_NONE }, | ||||
| 		{ "metadata",	ZFS_PREFETCH_METADATA }, | ||||
| 		{ "all",	ZFS_PREFETCH_ALL }, | ||||
| 		{ NULL } | ||||
| 	}; | ||||
| 
 | ||||
| 	static const zprop_index_t sync_table[] = { | ||||
| 		{ "standard",	ZFS_SYNC_STANDARD }, | ||||
| 		{ "always",	ZFS_SYNC_ALWAYS }, | ||||
| @ -453,6 +460,10 @@ zfs_prop_init(void) | ||||
| 	    ZFS_CACHE_ALL, PROP_INHERIT, | ||||
| 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME, | ||||
| 	    "all | none | metadata", "SECONDARYCACHE", cache_table, sfeatures); | ||||
| 	zprop_register_index(ZFS_PROP_PREFETCH, "prefetch", | ||||
| 	    ZFS_PREFETCH_ALL, PROP_INHERIT, | ||||
| 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME, | ||||
| 	    "none | metadata | all", "PREFETCH", prefetch_table, sfeatures); | ||||
| 	zprop_register_index(ZFS_PROP_LOGBIAS, "logbias", ZFS_LOGBIAS_LATENCY, | ||||
| 	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, | ||||
| 	    "latency | throughput", "LOGBIAS", logbias_table, sfeatures); | ||||
|  | ||||
| @ -263,6 +263,19 @@ secondary_cache_changed_cb(void *arg, uint64_t newval) | ||||
| 	os->os_secondary_cache = newval; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| prefetch_changed_cb(void *arg, uint64_t newval) | ||||
| { | ||||
| 	objset_t *os = arg; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Inheritance should have been done by now. | ||||
| 	 */ | ||||
| 	ASSERT(newval == ZFS_PREFETCH_ALL || newval == ZFS_PREFETCH_NONE || | ||||
| 	    newval == ZFS_PREFETCH_METADATA); | ||||
| 	os->os_prefetch = newval; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| sync_changed_cb(void *arg, uint64_t newval) | ||||
| { | ||||
| @ -562,6 +575,11 @@ dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, | ||||
| 			    zfs_prop_to_name(ZFS_PROP_SECONDARYCACHE), | ||||
| 			    secondary_cache_changed_cb, os); | ||||
| 		} | ||||
| 		if (err == 0) { | ||||
| 			err = dsl_prop_register(ds, | ||||
| 			    zfs_prop_to_name(ZFS_PROP_PREFETCH), | ||||
| 			    prefetch_changed_cb, os); | ||||
| 		} | ||||
| 		if (!ds->ds_is_snapshot) { | ||||
| 			if (err == 0) { | ||||
| 				err = dsl_prop_register(ds, | ||||
| @ -635,6 +653,7 @@ dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, | ||||
| 		os->os_primary_cache = ZFS_CACHE_ALL; | ||||
| 		os->os_secondary_cache = ZFS_CACHE_ALL; | ||||
| 		os->os_dnodesize = DNODE_MIN_SIZE; | ||||
| 		os->os_prefetch = ZFS_PREFETCH_ALL; | ||||
| 	} | ||||
| 
 | ||||
| 	if (ds == NULL || !ds->ds_is_snapshot) | ||||
|  | ||||
| @ -471,9 +471,14 @@ dmu_zfetch_prepare(zfetch_t *zf, uint64_t blkid, uint64_t nblks, | ||||
| { | ||||
| 	zstream_t *zs; | ||||
| 	spa_t *spa = zf->zf_dnode->dn_objset->os_spa; | ||||
| 	zfs_prefetch_type_t os_prefetch = zf->zf_dnode->dn_objset->os_prefetch; | ||||
| 
 | ||||
| 	if (zfs_prefetch_disable) | ||||
| 	if (zfs_prefetch_disable || os_prefetch == ZFS_PREFETCH_NONE) | ||||
| 		return (NULL); | ||||
| 
 | ||||
| 	if (os_prefetch == ZFS_PREFETCH_METADATA) | ||||
| 		fetch_data = B_FALSE; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * If we haven't yet loaded the indirect vdevs' mappings, we | ||||
| 	 * can only read from blocks that we carefully ensure are on | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Brian Behlendorf
						Brian Behlendorf