dnode.c revision 08f3f137579a3563791f39cd2aff588a251a723c
0N/A * The contents of this file are subject to the terms of the 0N/A * Common Development and Distribution License (the "License"). 0N/A * You may not use this file except in compliance with the License. 0N/A * See the License for the specific language governing permissions 0N/A * and limitations under the License. 0N/A * When distributing Covered Code, include this CDDL HEADER in each 0N/A * If applicable, add the following below this CDDL HEADER, with the 0N/A * fields enclosed by brackets "[]" replaced with your own identifying 0N/A * information: Portions Copyright [yyyy] [name of copyright owner] 0N/A * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 0N/A * Use is subject to license terms. * dn_nblkptr is only one byte, so it's OK to read it in either * byte order. We can't read dn_bouslen. * OK to check dn_bonuslen for zero, because it won't matter if * we have the wrong byte order. This is necessary because the * dnode dnode is smaller than a regular dnode. * Note that the bonus length calculated here may be * longer than the actual bonus buffer. This is because * we always put the bonus buffer after the last block * pointer (instead of packing it against the end of the for (i = 0; i <
size; i++) {
/* clean up any unreferenced dbufs */ /* change bonus size and type */ /* fix up the bonus db_size */ * Wait for final references to the dnode to clear. This can * only happen if the arc is asyncronously evicting state that * has a hold on this dnode while we are trying to evict this for (i = 0; i <
epb; i++) {
* If there are holds on this dnode, then there should * be holds on the dnode's containing dbuf as well; thus * it wouldn't be eligable for eviction and this function * would not have been called. * EINVAL - invalid object number. * succeeds even for free dnodes. * If you are holding the spa config lock as writer, you shouldn't * be asking the DMU to do *anything*. * Return held dnode if the object is allocated, NULL if not. * Can only add a reference if there is already at least one * reference on the dnode. Returns FALSE if unable to add a /* NOTE: the DNODE_DNODE does not have a dn_dbuf */ /* ASSERT(dn->dn_free_txg == 0 || dn->dn_free_txg >= txg); */ * If we are already marked dirty, we're done. * The dnode maintains a hold on its containing dbuf as * long as there are holds on it. Each instantiated child * dbuf maintaines a hold on the dnode. When the last child * drops its hold, the dnode will drop its hold on the * containing dbuf. We add a "dirty hold" here so that the * dnode will hang around after we finish processing its /* we should be the only holder... hopefully */ /* ASSERT3U(refcount_count(&dn->dn_holds), ==, 1); */ * If the dnode is already dirty, it needs to be moved from * the dirty list to the free list. * Try to change the block size for the indicated dnode. This can only * succeed if there are no blocks allocated or dirty beyond first block /* Check for any allocated blocks beyond the first */ /* resize the old block */ /* rele after we have fixed the blocksize in the dnode */ /* read-holding callers must not rely on the lock being continuously held */ * if we have a read-lock, check to see if we need to do any work * before upgrading to a write-lock. * Compute the number of levels necessary to support the new maxblkid. /* dirty the left indirects */ /* transfer the dirty records to the new indirect */ /* clear this entire range */ /* clear the beginning of this range */ /* clear the end of this range */ /* clear a chunk out of this range */ /* there may be no overlap */ * First, block align the region to free: /* Freeing the whole block; fast-track this request */ /* Freeing past end-of-data */ /* Freeing part of the block. */ /* zero out any partial block data at the start of the range */ /* don't dirty if it isn't on disk and isn't dirty */ /* If the range was less than one block, we're done */ /* If the remaining range is past end of file, we're done */ /* zero out any partial block data at the end of the range */ /* don't dirty if not on disk and not dirty */ /* If the range did not include a full block, we are done */ * Read in and mark all the level-1 indirects dirty, * so that they will stay in memory until syncing phase. * Always dirty the first and last indirect to make sure * we dirty all the partial indirects. * Add this range to the dnode range list. * We will finish up this free operation in the syncing phase. /* Add new range to dn_ranges */ /* return TRUE if this blkid was freed in a recent txg, or FALSE if it wasn't */ * If we're in the process of opening the pool, dp will not be * set yet, but there shouldn't be anything dirty. /* call from syncing context when we actually write/free space for this dnode */ * Call when we think we're going to write/free space in open context. * Be conservative (ie. OK to write less than this or free more than * this, but don't write more or free less). dprintf(
"probing object %llu offset %llx level %d of %u\n",
* This can only happen when we are searching up * the block tree for data. We don't really need to * adjust the offset, as we will just end up looking * at the pointer to this block in its parent, and its * going to be unallocated, so we will skip over it. * This can only happen when we are searching up the tree * and these conditions mean that we need to keep climbing. i >= 0 && i <
epb; i +=
inc) {
* Find the next hole, data, or sparse region at or after *offset. * The value 'blkfill' tells us how many items we expect to find * in an L0 data block; this value is 1 for normal objects, * DNODES_PER_BLOCK for the meta dnode, and some fraction of * DNODES_PER_BLOCK when searching for sparse regions thereof. * dnode_next_offset(dn, flags, offset, 1, 1, 0); * Used in dmu_offset_next(). * dnode_next_offset(mdn, flags, offset, 0, DNODES_PER_BLOCK, txg); * Only finds objects that have new contents since txg (ie. * bonus buffer changes and content removal are ignored). * Used in dmu_object_next(). * dnode_next_offset(mdn, DNODE_FIND_HOLE, offset, 2, DNODES_PER_BLOCK >> 2, 0); * Finds the next L2 meta-dnode bp that's at most 1/4 full. * Used in dmu_object_alloc().