mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	dbuf_sync_leaf: check DB_READ in state assertions
Block cloning introduced a new state transition from DB_NOFILL to DB_READ. This occurs when a block is cloned and then read on the current txg. In this case, the clone will move the dbuf to DB_NOFILL, and then the read will be issued for the overidden block pointer. If that read is still outstanding when it comes time to write, the dbuf will be in DB_READ, which is not handled by the checks in dbuf_sync_leaf, thus tripping the assertions. This updates those checks to allow DB_READ as a valid state iff the dirty record is for a BRT write and there is a override block pointer. This is a safe situation because the block already exists, so there's nothing that could change from underneath the read. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Kay Pedersen <mail@mkwg.de> Signed-off-by: Rob Norris <rob.norris@klarasystems.com> Original-patch-by: Kay Pedersen <mail@mkwg.de> Sponsored-By: OpenDrives Inc. Sponsored-By: Klara Inc. Closes #15050
This commit is contained in:
		
							parent
							
								
									0426e13271
								
							
						
					
					
						commit
						a3ea8c8ee6
					
				@ -4457,6 +4457,15 @@ dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
 | 
			
		||||
	} else if (db->db_state == DB_FILL) {
 | 
			
		||||
		/* This buffer was freed and is now being re-filled */
 | 
			
		||||
		ASSERT(db->db.db_data != dr->dt.dl.dr_data);
 | 
			
		||||
	} else if (db->db_state == DB_READ) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * This buffer has a clone we need to write, and an in-flight
 | 
			
		||||
		 * read on the BP we're about to clone. Its safe to issue the
 | 
			
		||||
		 * write here because the read has already been issued and the
 | 
			
		||||
		 * contents won't change.
 | 
			
		||||
		 */
 | 
			
		||||
		ASSERT(dr->dt.dl.dr_brtwrite &&
 | 
			
		||||
		    dr->dt.dl.dr_override_state == DR_OVERRIDDEN);
 | 
			
		||||
	} else {
 | 
			
		||||
		ASSERT(db->db_state == DB_CACHED || db->db_state == DB_NOFILL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user