mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	Polish db_rwlock scope
dbuf_verify(): Don't need the lock, since we only compare pointers. dbuf_findbp(): Don't need the lock, since aside of unneeded assert we only produce the pointer, but don't de-reference it. dnode_next_offset_level(): When working on top level indirection should lock dnode buffer's db_rwlock, since it is our parent. If dnode has no buffer, then it is meta-dnode or one of quotas and we should lock the dataset's ds_bp_rwlock instead. Reviewed-by: Alan Somers <asomers@gmail.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Alexander Motin <mav@FreeBSD.org> Sponsored by: iXsystems, Inc. Closes #17441
This commit is contained in:
		
							parent
							
								
									3ff2eca0be
								
							
						
					
					
						commit
						4ae931aa93
					
				@ -1185,18 +1185,11 @@ dbuf_verify(dmu_buf_impl_t *db)
 | 
				
			|||||||
			ASSERT3U(db->db_parent->db_level, ==, db->db_level+1);
 | 
								ASSERT3U(db->db_parent->db_level, ==, db->db_level+1);
 | 
				
			||||||
			ASSERT3U(db->db_parent->db.db_object, ==,
 | 
								ASSERT3U(db->db_parent->db.db_object, ==,
 | 
				
			||||||
			    db->db.db_object);
 | 
								    db->db.db_object);
 | 
				
			||||||
			/*
 | 
					 | 
				
			||||||
			 * dnode_grow_indblksz() can make this fail if we don't
 | 
					 | 
				
			||||||
			 * have the parent's rwlock.  XXX indblksz no longer
 | 
					 | 
				
			||||||
			 * grows.  safe to do this now?
 | 
					 | 
				
			||||||
			 */
 | 
					 | 
				
			||||||
			if (RW_LOCK_HELD(&db->db_parent->db_rwlock)) {
 | 
					 | 
				
			||||||
			ASSERT3P(db->db_blkptr, ==,
 | 
								ASSERT3P(db->db_blkptr, ==,
 | 
				
			||||||
			    ((blkptr_t *)db->db_parent->db.db_data +
 | 
								    ((blkptr_t *)db->db_parent->db.db_data +
 | 
				
			||||||
			    db->db_blkid % epb));
 | 
								    db->db_blkid % epb));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if ((db->db_blkptr == NULL || BP_IS_HOLE(db->db_blkptr)) &&
 | 
						if ((db->db_blkptr == NULL || BP_IS_HOLE(db->db_blkptr)) &&
 | 
				
			||||||
	    (db->db_buf == NULL || db->db_buf->b_data) &&
 | 
						    (db->db_buf == NULL || db->db_buf->b_data) &&
 | 
				
			||||||
	    db->db.db_data && db->db_blkid != DMU_BONUS_BLKID &&
 | 
						    db->db.db_data && db->db_blkid != DMU_BONUS_BLKID &&
 | 
				
			||||||
@ -3381,12 +3374,8 @@ dbuf_findbp(dnode_t *dn, int level, uint64_t blkid, int fail_sparse,
 | 
				
			|||||||
			*parentp = NULL;
 | 
								*parentp = NULL;
 | 
				
			||||||
			return (err);
 | 
								return (err);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		rw_enter(&(*parentp)->db_rwlock, RW_READER);
 | 
					 | 
				
			||||||
		*bpp = ((blkptr_t *)(*parentp)->db.db_data) +
 | 
							*bpp = ((blkptr_t *)(*parentp)->db.db_data) +
 | 
				
			||||||
		    (blkid & ((1ULL << epbs) - 1));
 | 
							    (blkid & ((1ULL << epbs) - 1));
 | 
				
			||||||
		if (blkid > (dn->dn_phys->dn_maxblkid >> (level * epbs)))
 | 
					 | 
				
			||||||
			ASSERT(BP_IS_HOLE(*bpp));
 | 
					 | 
				
			||||||
		rw_exit(&(*parentp)->db_rwlock);
 | 
					 | 
				
			||||||
		return (0);
 | 
							return (0);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		/* the block is referenced from the dnode */
 | 
							/* the block is referenced from the dnode */
 | 
				
			||||||
 | 
				
			|||||||
@ -2559,6 +2559,11 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset,
 | 
				
			|||||||
		error = 0;
 | 
							error = 0;
 | 
				
			||||||
		epb = dn->dn_phys->dn_nblkptr;
 | 
							epb = dn->dn_phys->dn_nblkptr;
 | 
				
			||||||
		data = dn->dn_phys->dn_blkptr;
 | 
							data = dn->dn_phys->dn_blkptr;
 | 
				
			||||||
 | 
							if (dn->dn_dbuf != NULL)
 | 
				
			||||||
 | 
								rw_enter(&dn->dn_dbuf->db_rwlock, RW_READER);
 | 
				
			||||||
 | 
							else if (dmu_objset_ds(dn->dn_objset) != NULL)
 | 
				
			||||||
 | 
								rrw_enter(&dmu_objset_ds(dn->dn_objset)->ds_bp_rwlock,
 | 
				
			||||||
 | 
								    RW_READER, FTAG);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		uint64_t blkid = dbuf_whichblock(dn, lvl, *offset);
 | 
							uint64_t blkid = dbuf_whichblock(dn, lvl, *offset);
 | 
				
			||||||
		error = dbuf_hold_impl(dn, lvl, blkid, TRUE, FALSE, FTAG, &db);
 | 
							error = dbuf_hold_impl(dn, lvl, blkid, TRUE, FALSE, FTAG, &db);
 | 
				
			||||||
@ -2663,6 +2668,12 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset,
 | 
				
			|||||||
	if (db != NULL) {
 | 
						if (db != NULL) {
 | 
				
			||||||
		rw_exit(&db->db_rwlock);
 | 
							rw_exit(&db->db_rwlock);
 | 
				
			||||||
		dbuf_rele(db, FTAG);
 | 
							dbuf_rele(db, FTAG);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if (dn->dn_dbuf != NULL)
 | 
				
			||||||
 | 
								rw_exit(&dn->dn_dbuf->db_rwlock);
 | 
				
			||||||
 | 
							else if (dmu_objset_ds(dn->dn_objset) != NULL)
 | 
				
			||||||
 | 
								rrw_exit(&dmu_objset_ds(dn->dn_objset)->ds_bp_rwlock,
 | 
				
			||||||
 | 
								    FTAG);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (error);
 | 
						return (error);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user