traverse_visitbp: visit DMU_GROUPUSED_OBJECT before DMU_USERUSED_OBJECT

This is done to ensure that visited object IDs are always increasing.
Also, pass correct object ID to prefetch_dnode_metadata for
os_groupused_dnode.

Without this change we would hit an assert if traversal was paused on
a GROUPUSED object, which is unlikely but possible.

Apparently the same change was independently developed by Deplhix.

Reviewed by:	Matthew Ahrens <mahrens@delphix.com>
MFC after:	10 days
Sponsored by:	HybridCluster
This commit is contained in:
Andriy Gapon 2014-01-17 10:23:46 +00:00
parent df217ba9ba
commit 6d03ca5789

View File

@ -351,9 +351,9 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp,
prefetch_dnode_metadata(td, dnp, zb->zb_objset,
DMU_META_DNODE_OBJECT);
if (arc_buf_size(buf) >= sizeof (objset_phys_t)) {
prefetch_dnode_metadata(td, &osp->os_userused_dnode,
zb->zb_objset, DMU_USERUSED_OBJECT);
prefetch_dnode_metadata(td, &osp->os_groupused_dnode,
zb->zb_objset, DMU_GROUPUSED_OBJECT);
prefetch_dnode_metadata(td, &osp->os_userused_dnode,
zb->zb_objset, DMU_USERUSED_OBJECT);
}
@ -364,18 +364,18 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp,
err = 0;
}
if (err == 0 && arc_buf_size(buf) >= sizeof (objset_phys_t)) {
dnp = &osp->os_userused_dnode;
dnp = &osp->os_groupused_dnode;
err = traverse_dnode(td, dnp, zb->zb_objset,
DMU_USERUSED_OBJECT);
DMU_GROUPUSED_OBJECT);
}
if (err && hard) {
lasterr = err;
err = 0;
}
if (err == 0 && arc_buf_size(buf) >= sizeof (objset_phys_t)) {
dnp = &osp->os_groupused_dnode;
dnp = &osp->os_userused_dnode;
err = traverse_dnode(td, dnp, zb->zb_objset,
DMU_GROUPUSED_OBJECT);
DMU_USERUSED_OBJECT);
}
}