MCPcopy Create free account
hub / github.com/F-Stack/f-stack / free_children

Function free_children

freebsd/contrib/openzfs/module/zfs/dnode_sync.c:264–356  ·  view source on GitHub ↗

* We don't usually free the indirect blocks here. If in one txg we have a * free_range and a write to the same indirect block, it's important that we * preserve the hole's birth times. Therefore, we don't free any any indirect * blocks in free_children(). If an indirect block happens to turn into all * holes, it will be freed by dbuf_write_children_ready, which happens at a * point in the s

Source from the content-addressed store, hash-verified

262 * case.
263 */
264static void
265free_children(dmu_buf_impl_t *db, uint64_t blkid, uint64_t nblks,
266 boolean_t free_indirects, dmu_tx_t *tx)
267{
268 dnode_t *dn;
269 blkptr_t *bp;
270 dmu_buf_impl_t *subdb;
271 uint64_t start, end, dbstart, dbend;
272 unsigned int epbs, shift, i;
273
274 /*
275 * There is a small possibility that this block will not be cached:
276 * 1 - if level > 1 and there are no children with level <= 1
277 * 2 - if this block was evicted since we read it from
278 * dmu_tx_hold_free().
279 */
280 if (db->db_state != DB_CACHED)
281 (void) dbuf_read(db, NULL, DB_RF_MUST_SUCCEED);
282
283 /*
284 * If we modify this indirect block, and we are not freeing the
285 * dnode (!free_indirects), then this indirect block needs to get
286 * written to disk by dbuf_write(). If it is dirty, we know it will
287 * be written (otherwise, we would have incorrect on-disk state
288 * because the space would be freed but still referenced by the BP
289 * in this indirect block). Therefore we VERIFY that it is
290 * dirty.
291 *
292 * Our VERIFY covers some cases that do not actually have to be
293 * dirty, but the open-context code happens to dirty. E.g. if the
294 * blocks we are freeing are all holes, because in that case, we
295 * are only freeing part of this indirect block, so it is an
296 * ancestor of the first or last block to be freed. The first and
297 * last L1 indirect blocks are always dirtied by dnode_free_range().
298 */
299 db_lock_type_t dblt = dmu_buf_lock_parent(db, RW_READER, FTAG);
300 VERIFY(BP_GET_FILL(db->db_blkptr) == 0 || db->db_dirtycnt > 0);
301 dmu_buf_unlock_parent(db, dblt, FTAG);
302
303 dbuf_release_bp(db);
304 bp = db->db.db_data;
305
306 DB_DNODE_ENTER(db);
307 dn = DB_DNODE(db);
308 epbs = dn->dn_phys->dn_indblkshift - SPA_BLKPTRSHIFT;
309 ASSERT3U(epbs, <, 31);
310 shift = (db->db_level - 1) * epbs;
311 dbstart = db->db_blkid << epbs;
312 start = blkid >> shift;
313 if (dbstart < start) {
314 bp += start - dbstart;
315 } else {
316 start = dbstart;
317 }
318 dbend = ((db->db_blkid + 1) << epbs) - 1;
319 end = (blkid + nblks - 1) >> shift;
320 if (dbend <= end)
321 end = dbend;

Callers 1

Calls 11

dbuf_readFunction · 0.85
dmu_buf_lock_parentFunction · 0.85
dmu_buf_unlock_parentFunction · 0.85
dbuf_release_bpFunction · 0.85
rw_enterFunction · 0.85
free_blocksFunction · 0.85
rw_exitFunction · 0.85
dbuf_hold_implFunction · 0.85
dbuf_releFunction · 0.85
bzeroFunction · 0.85
arc_buf_freezeFunction · 0.85

Tested by

no test coverage detected