* Dirty all the in-core level-1 dbufs in the range specified by start_blkid * and end_blkid. */
| 1950 | * and end_blkid. |
| 1951 | */ |
| 1952 | static void |
| 1953 | dnode_dirty_l1range(dnode_t *dn, uint64_t start_blkid, uint64_t end_blkid, |
| 1954 | dmu_tx_t *tx) |
| 1955 | { |
| 1956 | dmu_buf_impl_t *db_search; |
| 1957 | dmu_buf_impl_t *db; |
| 1958 | avl_index_t where; |
| 1959 | |
| 1960 | db_search = kmem_zalloc(sizeof (dmu_buf_impl_t), KM_SLEEP); |
| 1961 | |
| 1962 | mutex_enter(&dn->dn_dbufs_mtx); |
| 1963 | |
| 1964 | db_search->db_level = 1; |
| 1965 | db_search->db_blkid = start_blkid + 1; |
| 1966 | db_search->db_state = DB_SEARCH; |
| 1967 | for (;;) { |
| 1968 | |
| 1969 | db = avl_find(&dn->dn_dbufs, db_search, &where); |
| 1970 | if (db == NULL) |
| 1971 | db = avl_nearest(&dn->dn_dbufs, where, AVL_AFTER); |
| 1972 | |
| 1973 | if (db == NULL || db->db_level != 1 || |
| 1974 | db->db_blkid >= end_blkid) { |
| 1975 | break; |
| 1976 | } |
| 1977 | |
| 1978 | /* |
| 1979 | * Setup the next blkid we want to search for. |
| 1980 | */ |
| 1981 | db_search->db_blkid = db->db_blkid + 1; |
| 1982 | ASSERT3U(db->db_blkid, >=, start_blkid); |
| 1983 | |
| 1984 | /* |
| 1985 | * If the dbuf transitions to DB_EVICTING while we're trying |
| 1986 | * to dirty it, then we will be unable to discover it in |
| 1987 | * the dbuf hash table. This will result in a call to |
| 1988 | * dbuf_create() which needs to acquire the dn_dbufs_mtx |
| 1989 | * lock. To avoid a deadlock, we drop the lock before |
| 1990 | * dirtying the level-1 dbuf. |
| 1991 | */ |
| 1992 | mutex_exit(&dn->dn_dbufs_mtx); |
| 1993 | dnode_dirty_l1(dn, db->db_blkid, tx); |
| 1994 | mutex_enter(&dn->dn_dbufs_mtx); |
| 1995 | } |
| 1996 | |
| 1997 | #ifdef ZFS_DEBUG |
| 1998 | /* |
| 1999 | * Walk all the in-core level-1 dbufs and verify they have been dirtied. |
| 2000 | */ |
| 2001 | db_search->db_level = 1; |
| 2002 | db_search->db_blkid = start_blkid + 1; |
| 2003 | db_search->db_state = DB_SEARCH; |
| 2004 | db = avl_find(&dn->dn_dbufs, db_search, &where); |
| 2005 | if (db == NULL) |
| 2006 | db = avl_nearest(&dn->dn_dbufs, where, AVL_AFTER); |
| 2007 | for (; db != NULL; db = AVL_NEXT(&dn->dn_dbufs, db)) { |
| 2008 | if (db->db_level != 1 || db->db_blkid >= end_blkid) |
| 2009 | break; |
no test coverage detected