| 1206 | } |
| 1207 | |
| 1208 | static void |
| 1209 | dnode_buf_evict_async(void *dbu) |
| 1210 | { |
| 1211 | dnode_children_t *dnc = dbu; |
| 1212 | |
| 1213 | DNODE_STAT_BUMP(dnode_buf_evict); |
| 1214 | |
| 1215 | for (int i = 0; i < dnc->dnc_count; i++) { |
| 1216 | dnode_handle_t *dnh = &dnc->dnc_children[i]; |
| 1217 | dnode_t *dn; |
| 1218 | |
| 1219 | /* |
| 1220 | * The dnode handle lock guards against the dnode moving to |
| 1221 | * another valid address, so there is no need here to guard |
| 1222 | * against changes to or from NULL. |
| 1223 | */ |
| 1224 | if (!DN_SLOT_IS_PTR(dnh->dnh_dnode)) { |
| 1225 | zrl_destroy(&dnh->dnh_zrlock); |
| 1226 | dnh->dnh_dnode = DN_SLOT_UNINIT; |
| 1227 | continue; |
| 1228 | } |
| 1229 | |
| 1230 | zrl_add(&dnh->dnh_zrlock); |
| 1231 | dn = dnh->dnh_dnode; |
| 1232 | /* |
| 1233 | * If there are holds on this dnode, then there should |
| 1234 | * be holds on the dnode's containing dbuf as well; thus |
| 1235 | * it wouldn't be eligible for eviction and this function |
| 1236 | * would not have been called. |
| 1237 | */ |
| 1238 | ASSERT(zfs_refcount_is_zero(&dn->dn_holds)); |
| 1239 | ASSERT(zfs_refcount_is_zero(&dn->dn_tx_holds)); |
| 1240 | |
| 1241 | dnode_destroy(dn); /* implicit zrl_remove() for first slot */ |
| 1242 | zrl_destroy(&dnh->dnh_zrlock); |
| 1243 | dnh->dnh_dnode = DN_SLOT_UNINIT; |
| 1244 | } |
| 1245 | kmem_free(dnc, sizeof (dnode_children_t) + |
| 1246 | dnc->dnc_count * sizeof (dnode_handle_t)); |
| 1247 | } |
| 1248 | |
| 1249 | /* |
| 1250 | * When the DNODE_MUST_BE_FREE flag is set, the "slots" parameter is used |
nothing calls this directly
no test coverage detected