FreeBSD/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_replay.c
/*
 * Replaying ACLs is complicated by FUID support.
 * The log record may contain some optional data
 * to be used for replaying FUID's.  These pieces
 * are the actual FUIDs that were created initially.
 * The FUID table index may no longer be valid and
 * during zfs_create() a new index may be assigned.
 * Because of this the log will contain the original
 * doman+rid in order to create a new FUID.
 *
 * The individual ACEs may contain an ephemeral uid/gid which is no
 * longer valid and will need to be replaced with an actual FUID.
 *
 */
Replaying ACLs is complicated by FUID support.
The log record may contain some optional data
to be used for replaying FUID's.  These pieces
are the actual FUIDs that were created initially.
The FUID table index may no longer be valid and
during zfs_create() a new index may be assigned.
Because of this the log will contain the original
doman+rid in order to create a new FUID.

The individual ACEs may contain an ephemeral uid/gid which is no
longer valid and will need to be replaced with an actual FUID.
Replaying ACLs is complicated by FUID support . The log record may contain some optional data to be used for replaying FUID ' s . These pieces are the actual FUIDs that were created initially . The FUID table index may no longer be valid and during zfs_create () a new index may be assigned . Because of this the log will contain the original doman + rid in order to create a new FUID . The individual ACEs may contain an ephemeral uid / gid which is no longer valid and will need to be replaced with an actual FUID .
static int
zfs_replay_acl(zfsvfs_t *zfsvfs, lr_acl_t *lr, boolean_t byteswap)
{
	ace_t *ace = (ace_t *)(lr + 1);
	vsecattr_t vsa;
	znode_t *zp;
	vnode_t *vp;
	int error;
	if (byteswap) {
		byteswap_uint64_array(lr, sizeof (*lr));
		zfs_ace_byteswap(ace, lr->lr_acl_bytes, B_FALSE);
		if (lr->lr_fuidcnt) {
			byteswap_uint64_array((caddr_t)ace +
			    ZIL_ACE_LENGTH(lr->lr_acl_bytes),
			    lr->lr_fuidcnt * sizeof (uint64_t));
		}
	}
	if ((error = zfs_zget(zfsvfs, lr->lr_foid, &zp)) != 0)
		return (error);
	bzero(&vsa, sizeof (vsa));
	vsa.vsa_mask = VSA_ACE | VSA_ACECNT | VSA_ACE_ACLFLAGS;
	vsa.vsa_aclcnt = lr->lr_aclcnt;
	vsa.vsa_aclentp = ace;
	vsa.vsa_aclentsz = lr->lr_acl_bytes;
	vsa.vsa_aclflags = lr->lr_acl_flags;
	if (lr->lr_fuidcnt) {
		void *fuidstart = (caddr_t)ace +
		    ZIL_ACE_LENGTH(lr->lr_acl_bytes);
		zfsvfs->z_fuid_replay =
		    zfs_replay_fuids(fuidstart, &fuidstart,
		    lr->lr_fuidcnt, lr->lr_domcnt, 0, 0);
	}
	vp = ZTOV(zp);
	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
	error = zfs_setsecattr(vp, &vsa, 0, kcred, NULL);
	VOP_UNLOCK(vp, 0);
	if (zfsvfs->z_fuid_replay)
		zfs_fuid_info_free(zfsvfs->z_fuid_replay);
	zfsvfs->z_fuid_replay = NULL;
	VN_RELE(vp);
	return (error);
}
static int zfs_replay_acl ( zfsvfs_t * zfsvfs , lr_acl_t * lr , boolean_t byteswap ) { ace_t * ace = ( ace_t * ) ( lr + 1 ) ; vsecattr_t vsa ; znode_t * zp ; vnode_t * vp ; int error ; if ( byteswap ) { byteswap_uint64_array ( lr , sizeof ( * lr ) ) ; zfs_ace_byteswap ( ace , lr -> lr_acl_bytes , B_FALSE ) ; if ( lr -> lr_fuidcnt ) { byteswap_uint64_array ( ( caddr_t ) ace + ZIL_ACE_LENGTH ( lr -> lr_acl_bytes ) , lr -> lr_fuidcnt * sizeof ( uint64_t ) ) ; } } if ( ( error = zfs_zget ( zfsvfs , lr -> lr_foid , & zp ) ) != 0 ) return ( error ) ; bzero ( & vsa , sizeof ( vsa ) ) ; vsa . vsa_mask = VSA_ACE | VSA_ACECNT | VSA_ACE_ACLFLAGS ; vsa . vsa_aclcnt = lr -> lr_aclcnt ; vsa . vsa_aclentp = ace ; vsa . vsa_aclentsz = lr -> lr_acl_bytes ; vsa . vsa_aclflags = lr -> lr_acl_flags ; if ( lr -> lr_fuidcnt ) { void * fuidstart = ( caddr_t ) ace + ZIL_ACE_LENGTH ( lr -> lr_acl_bytes ) ; zfsvfs -> z_fuid_replay = zfs_replay_fuids ( fuidstart , & fuidstart , lr -> lr_fuidcnt , lr -> lr_domcnt , 0 , 0 ) ; } vp = ZTOV ( zp ) ; vn_lock ( vp , LK_EXCLUSIVE | LK_RETRY ) ; error = zfs_setsecattr ( vp , & vsa , 0 , kcred , NULL ) ; VOP_UNLOCK ( vp , 0 ) ; if ( zfsvfs -> z_fuid_replay ) zfs_fuid_info_free ( zfsvfs -> z_fuid_replay ) ; zfsvfs -> z_fuid_replay = NULL ; VN_RELE ( vp ) ; return ( error ) ; }
Replaying ACLs is complicated by FUID support.
Replaying ACLs is complicated by FUID support .