mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 18:40:43 +03:00
Rebase master to b117
This commit is contained in:
+37
-49
@@ -156,7 +156,7 @@ dnode_verify(dnode_t *dn)
|
||||
}
|
||||
if (dn->dn_phys->dn_type != DMU_OT_NONE)
|
||||
ASSERT3U(dn->dn_phys->dn_nlevels, <=, dn->dn_nlevels);
|
||||
ASSERT(dn->dn_object == DMU_META_DNODE_OBJECT || dn->dn_dbuf != NULL);
|
||||
ASSERT(DMU_OBJECT_IS_SPECIAL(dn->dn_object) || dn->dn_dbuf != NULL);
|
||||
if (dn->dn_dbuf != NULL) {
|
||||
ASSERT3P(dn->dn_phys, ==,
|
||||
(dnode_phys_t *)dn->dn_dbuf->db.db_data +
|
||||
@@ -321,6 +321,7 @@ dnode_destroy(dnode_t *dn)
|
||||
}
|
||||
ASSERT(NULL == list_head(&dn->dn_dbufs));
|
||||
#endif
|
||||
ASSERT(dn->dn_oldphys == NULL);
|
||||
|
||||
mutex_enter(&os->os_lock);
|
||||
list_remove(&os->os_dnodes, dn);
|
||||
@@ -417,8 +418,7 @@ void
|
||||
dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
|
||||
dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
|
||||
{
|
||||
int i, nblkptr;
|
||||
dmu_buf_impl_t *db = NULL;
|
||||
int nblkptr;
|
||||
|
||||
ASSERT3U(blocksize, >=, SPA_MINBLOCKSIZE);
|
||||
ASSERT3U(blocksize, <=, SPA_MAXBLOCKSIZE);
|
||||
@@ -430,42 +430,25 @@ dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize,
|
||||
ASSERT3U(bonustype, <, DMU_OT_NUMTYPES);
|
||||
ASSERT3U(bonuslen, <=, DN_MAX_BONUSLEN);
|
||||
|
||||
for (i = 0; i < TXG_SIZE; i++)
|
||||
ASSERT(!list_link_active(&dn->dn_dirty_link[i]));
|
||||
|
||||
/* clean up any unreferenced dbufs */
|
||||
dnode_evict_dbufs(dn);
|
||||
ASSERT3P(list_head(&dn->dn_dbufs), ==, NULL);
|
||||
|
||||
/*
|
||||
* XXX I should really have a generation number to tell if we
|
||||
* need to do this...
|
||||
*/
|
||||
if (blocksize != dn->dn_datablksz ||
|
||||
dn->dn_bonustype != bonustype || dn->dn_bonuslen != bonuslen) {
|
||||
/* free all old data */
|
||||
dnode_free_range(dn, 0, -1ULL, tx);
|
||||
}
|
||||
|
||||
nblkptr = 1 + ((DN_MAX_BONUSLEN - bonuslen) >> SPA_BLKPTRSHIFT);
|
||||
|
||||
/* change blocksize */
|
||||
rw_enter(&dn->dn_struct_rwlock, RW_WRITER);
|
||||
if (blocksize != dn->dn_datablksz &&
|
||||
(!BP_IS_HOLE(&dn->dn_phys->dn_blkptr[0]) ||
|
||||
list_head(&dn->dn_dbufs) != NULL)) {
|
||||
db = dbuf_hold(dn, 0, FTAG);
|
||||
dbuf_new_size(db, blocksize, tx);
|
||||
}
|
||||
dnode_setdblksz(dn, blocksize);
|
||||
dnode_setdirty(dn, tx);
|
||||
dn->dn_next_bonuslen[tx->tx_txg&TXG_MASK] = bonuslen;
|
||||
dn->dn_next_blksz[tx->tx_txg&TXG_MASK] = blocksize;
|
||||
if (dn->dn_datablksz != blocksize) {
|
||||
/* change blocksize */
|
||||
ASSERT(dn->dn_maxblkid == 0 &&
|
||||
(BP_IS_HOLE(&dn->dn_phys->dn_blkptr[0]) ||
|
||||
dnode_block_freed(dn, 0)));
|
||||
dnode_setdblksz(dn, blocksize);
|
||||
dn->dn_next_blksz[tx->tx_txg&TXG_MASK] = blocksize;
|
||||
}
|
||||
if (dn->dn_bonuslen != bonuslen)
|
||||
dn->dn_next_bonuslen[tx->tx_txg&TXG_MASK] = bonuslen;
|
||||
nblkptr = 1 + ((DN_MAX_BONUSLEN - bonuslen) >> SPA_BLKPTRSHIFT);
|
||||
if (dn->dn_nblkptr != nblkptr)
|
||||
dn->dn_next_nblkptr[tx->tx_txg&TXG_MASK] = nblkptr;
|
||||
rw_exit(&dn->dn_struct_rwlock);
|
||||
if (db)
|
||||
dbuf_rele(db, FTAG);
|
||||
|
||||
/* change type */
|
||||
dn->dn_type = ot;
|
||||
@@ -569,6 +552,22 @@ dnode_hold_impl(objset_impl_t *os, uint64_t object, int flag,
|
||||
*/
|
||||
ASSERT(spa_config_held(os->os_spa, SCL_ALL, RW_WRITER) == 0);
|
||||
|
||||
if (object == DMU_USERUSED_OBJECT || object == DMU_GROUPUSED_OBJECT) {
|
||||
dn = (object == DMU_USERUSED_OBJECT) ?
|
||||
os->os_userused_dnode : os->os_groupused_dnode;
|
||||
if (dn == NULL)
|
||||
return (ENOENT);
|
||||
type = dn->dn_type;
|
||||
if ((flag & DNODE_MUST_BE_ALLOCATED) && type == DMU_OT_NONE)
|
||||
return (ENOENT);
|
||||
if ((flag & DNODE_MUST_BE_FREE) && type != DMU_OT_NONE)
|
||||
return (EEXIST);
|
||||
DNODE_VERIFY(dn);
|
||||
(void) refcount_add(&dn->dn_holds, tag);
|
||||
*dnp = dn;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (object == 0 || object >= DN_MAX_OBJECT)
|
||||
return (EINVAL);
|
||||
|
||||
@@ -627,7 +626,8 @@ dnode_hold_impl(objset_impl_t *os, uint64_t object, int flag,
|
||||
type = dn->dn_type;
|
||||
if (dn->dn_free_txg ||
|
||||
((flag & DNODE_MUST_BE_ALLOCATED) && type == DMU_OT_NONE) ||
|
||||
((flag & DNODE_MUST_BE_FREE) && type != DMU_OT_NONE)) {
|
||||
((flag & DNODE_MUST_BE_FREE) &&
|
||||
(type != DMU_OT_NONE || dn->dn_oldphys))) {
|
||||
mutex_exit(&dn->dn_mtx);
|
||||
dbuf_rele(db, FTAG);
|
||||
return (type == DMU_OT_NONE ? ENOENT : EEXIST);
|
||||
@@ -692,8 +692,10 @@ dnode_setdirty(dnode_t *dn, dmu_tx_t *tx)
|
||||
objset_impl_t *os = dn->dn_objset;
|
||||
uint64_t txg = tx->tx_txg;
|
||||
|
||||
if (dn->dn_object == DMU_META_DNODE_OBJECT)
|
||||
if (DMU_OBJECT_IS_SPECIAL(dn->dn_object)) {
|
||||
dsl_dataset_dirty(os->os_dsl_dataset, tx);
|
||||
return;
|
||||
}
|
||||
|
||||
DNODE_VERIFY(dn);
|
||||
|
||||
@@ -1189,11 +1191,6 @@ dnode_block_freed(dnode_t *dn, uint64_t blkid)
|
||||
if (dn->dn_free_txg)
|
||||
return (TRUE);
|
||||
|
||||
/*
|
||||
* If dn_datablkshift is not set, then there's only a single
|
||||
* block, in which case there will never be a free range so it
|
||||
* won't matter.
|
||||
*/
|
||||
range_tofind.fr_blkid = blkid;
|
||||
mutex_enter(&dn->dn_mtx);
|
||||
for (i = 0; i < TXG_SIZE; i++) {
|
||||
@@ -1278,7 +1275,7 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset,
|
||||
dprintf("probing object %llu offset %llx level %d of %u\n",
|
||||
dn->dn_object, *offset, lvl, dn->dn_phys->dn_nlevels);
|
||||
|
||||
hole = flags & DNODE_FIND_HOLE;
|
||||
hole = ((flags & DNODE_FIND_HOLE) != 0);
|
||||
inc = (flags & DNODE_FIND_BACKWARDS) ? -1 : 1;
|
||||
ASSERT(txg == 0 || !hole);
|
||||
|
||||
@@ -1325,16 +1322,7 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset,
|
||||
|
||||
for (i = (*offset >> span) & (blkfill - 1);
|
||||
i >= 0 && i < blkfill; i += inc) {
|
||||
boolean_t newcontents = B_TRUE;
|
||||
if (txg) {
|
||||
int j;
|
||||
newcontents = B_FALSE;
|
||||
for (j = 0; j < dnp[i].dn_nblkptr; j++) {
|
||||
if (dnp[i].dn_blkptr[j].blk_birth > txg)
|
||||
newcontents = B_TRUE;
|
||||
}
|
||||
}
|
||||
if (!dnp[i].dn_type == hole && newcontents)
|
||||
if ((dnp[i].dn_type == DMU_OT_NONE) == hole)
|
||||
break;
|
||||
*offset += (1ULL << span) * inc;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user