Esempio n. 1
0
/*
 * zfs_log_create() is used to handle TX_CREATE, TX_CREATE_ATTR, TX_MKDIR,
 * TX_MKDIR_ATTR and TX_MKXATTR
 * transactions.
 *
 * TX_CREATE and TX_MKDIR are standard creates, but they may have FUID
 * domain information appended prior to the name.  In this case the
 * uid/gid in the log record will be a log centric FUID.
 *
 * TX_CREATE_ACL_ATTR and TX_MKDIR_ACL_ATTR handle special creates that
 * may contain attributes, ACL and optional fuid information.
 *
 * TX_CREATE_ACL and TX_MKDIR_ACL handle special creates that specify
 * and ACL and normal users/groups in the ACEs.
 *
 * There may be an optional xvattr attribute information similar
 * to zfs_log_setattr.
 *
 * Also, after the file name "domain" strings may be appended.
 */
void
zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
    znode_t *dzp, znode_t *zp, char *name, vsecattr_t *vsecp,
    zfs_fuid_info_t *fuidp, vattr_t *vap)
{
	itx_t *itx;
	lr_create_t *lr;
	lr_acl_create_t *lracl;
	size_t aclsize;
	size_t xvatsize = 0;
	size_t txsize;
	xvattr_t *xvap = (xvattr_t *)vap;
	void *end;
	size_t lrsize;
	size_t namesize = strlen(name) + 1;
	size_t fuidsz = 0;

	if (zil_replaying(zilog, tx))
		return;

	/*
	 * If we have FUIDs present then add in space for
	 * domains and ACE fuid's if any.
	 */
	if (fuidp) {
		fuidsz += fuidp->z_domain_str_sz;
		fuidsz += fuidp->z_fuid_cnt * sizeof (uint64_t);
	}

	if (vap->va_mask & AT_XVATTR)
		xvatsize = ZIL_XVAT_SIZE(xvap->xva_mapsize);

	if ((int)txtype == TX_CREATE_ATTR || (int)txtype == TX_MKDIR_ATTR ||
	    (int)txtype == TX_CREATE || (int)txtype == TX_MKDIR ||
	    (int)txtype == TX_MKXATTR) {
		txsize = sizeof (*lr) + namesize + fuidsz + xvatsize;
		lrsize = sizeof (*lr);
	} else {
		aclsize = (vsecp) ? vsecp->vsa_aclentsz : 0;
		txsize =
		    sizeof (lr_acl_create_t) + namesize + fuidsz +
		    ZIL_ACE_LENGTH(aclsize) + xvatsize;
		lrsize = sizeof (lr_acl_create_t);
	}

	itx = zil_itx_create(txtype, txsize);

	lr = (lr_create_t *)&itx->itx_lr;
	lr->lr_doid = dzp->z_id;
	lr->lr_foid = zp->z_id;
	lr->lr_mode = zp->z_mode;
	if (!IS_EPHEMERAL(zp->z_uid)) {
		lr->lr_uid = (uint64_t)zp->z_uid;
	} else {
		lr->lr_uid = fuidp->z_fuid_owner;
	}
	if (!IS_EPHEMERAL(zp->z_gid)) {
		lr->lr_gid = (uint64_t)zp->z_gid;
	} else {
		lr->lr_gid = fuidp->z_fuid_group;
	}
	(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zp->z_zfsvfs), &lr->lr_gen,
	    sizeof (uint64_t));
	(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(zp->z_zfsvfs),
	    lr->lr_crtime, sizeof (uint64_t) * 2);

	if (sa_lookup(zp->z_sa_hdl, SA_ZPL_RDEV(zp->z_zfsvfs), &lr->lr_rdev,
	    sizeof (lr->lr_rdev)) != 0)
		lr->lr_rdev = 0;

	/*
	 * Fill in xvattr info if any
	 */
	if (vap->va_mask & AT_XVATTR) {
		zfs_log_xvattr((lr_attr_t *)((caddr_t)lr + lrsize), xvap);
		end = (caddr_t)lr + lrsize + xvatsize;
	} else {
		end = (caddr_t)lr + lrsize;
	}

	/* Now fill in any ACL info */

	if (vsecp) {
		lracl = (lr_acl_create_t *)&itx->itx_lr;
		lracl->lr_aclcnt = vsecp->vsa_aclcnt;
		lracl->lr_acl_bytes = aclsize;
		lracl->lr_domcnt = fuidp ? fuidp->z_domain_cnt : 0;
		lracl->lr_fuidcnt  = fuidp ? fuidp->z_fuid_cnt : 0;
		if (vsecp->vsa_aclflags & VSA_ACE_ACLFLAGS)
			lracl->lr_acl_flags = (uint64_t)vsecp->vsa_aclflags;
		else
			lracl->lr_acl_flags = 0;

		bcopy(vsecp->vsa_aclentp, end, aclsize);
		end = (caddr_t)end + ZIL_ACE_LENGTH(aclsize);
	}

	/* drop in FUID info */
	if (fuidp) {
		end = zfs_log_fuid_ids(fuidp, end);
		end = zfs_log_fuid_domains(fuidp, end);
	}
	/*
	 * Now place file name in log record
	 */
	bcopy(name, end, namesize);

	zil_itx_assign(zilog, itx, tx);
}
Esempio n. 2
0
File: zfs_log.c Progetto: AB17/zfs
void
zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
	znode_t *zp, offset_t off, ssize_t resid, int ioflag)
{
	itx_wr_state_t write_state;
	boolean_t slogging;
	uintptr_t fsync_cnt;
	ssize_t immediate_write_sz;

	if (zil_replaying(zilog, tx) || zp->z_unlinked)
		return;

	immediate_write_sz = (zilog->zl_logbias == ZFS_LOGBIAS_THROUGHPUT)
	    ? 0 : (ssize_t)zfs_immediate_write_sz;

	slogging = spa_has_slogs(zilog->zl_spa) &&
	    (zilog->zl_logbias == ZFS_LOGBIAS_LATENCY);
	if (resid > immediate_write_sz && !slogging && resid <= zp->z_blksz)
		write_state = WR_INDIRECT;
	else if (ioflag & (FSYNC | FDSYNC))
		write_state = WR_COPIED;
	else
		write_state = WR_NEED_COPY;

	if ((fsync_cnt = (uintptr_t)tsd_get(zfs_fsyncer_key)) != 0) {
		(void) tsd_set(zfs_fsyncer_key, (void *)(fsync_cnt - 1));
	}

	while (resid) {
		itx_t *itx;
		lr_write_t *lr;
		ssize_t len;

		/*
		 * If the write would overflow the largest block then split it.
		 */
		if (write_state != WR_INDIRECT && resid > ZIL_MAX_LOG_DATA)
			len = SPA_MAXBLOCKSIZE >> 1;
		else
			len = resid;

		itx = zil_itx_create(txtype, sizeof (*lr) +
		    (write_state == WR_COPIED ? len : 0));
		lr = (lr_write_t *)&itx->itx_lr;
		if (write_state == WR_COPIED && dmu_read(ZTOZSB(zp)->z_os,
		    zp->z_id, off, len, lr + 1, DMU_READ_NO_PREFETCH) != 0) {
			zil_itx_destroy(itx);
			itx = zil_itx_create(txtype, sizeof (*lr));
			lr = (lr_write_t *)&itx->itx_lr;
			write_state = WR_NEED_COPY;
		}

		itx->itx_wr_state = write_state;
		if (write_state == WR_NEED_COPY)
			itx->itx_sod += len;
		lr->lr_foid = zp->z_id;
		lr->lr_offset = off;
		lr->lr_length = len;
		lr->lr_blkoff = 0;
		BP_ZERO(&lr->lr_blkptr);

		itx->itx_private = ZTOZSB(zp);

		if (!(ioflag & (FSYNC | FDSYNC)) && (zp->z_sync_cnt == 0) &&
		    (fsync_cnt == 0))
			itx->itx_sync = B_FALSE;

		zil_itx_assign(zilog, itx, tx);

		off += len;
		resid -= len;
	}
Esempio n. 3
0
File: zvol.c Progetto: torn5/zfs
static void
zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx,
	       uint64_t offset, uint64_t size, int sync)
{
	uint32_t blocksize = zv->zv_volblocksize;
	zilog_t *zilog = zv->zv_zilog;
	boolean_t slogging;
	ssize_t immediate_write_sz;

	if (zil_replaying(zilog, tx))
		return;

	immediate_write_sz = (zilog->zl_logbias == ZFS_LOGBIAS_THROUGHPUT)
		? 0 : zvol_immediate_write_sz;
	slogging = spa_has_slogs(zilog->zl_spa) &&
		(zilog->zl_logbias == ZFS_LOGBIAS_LATENCY);

	while (size) {
		itx_t *itx;
		lr_write_t *lr;
		ssize_t len;
		itx_wr_state_t write_state;

		/*
		 * Unlike zfs_log_write() we can be called with
		 * up to DMU_MAX_ACCESS/2 (5MB) writes.
		 */
		if (blocksize > immediate_write_sz && !slogging &&
		    size >= blocksize && offset % blocksize == 0) {
			write_state = WR_INDIRECT; /* uses dmu_sync */
			len = blocksize;
		} else if (sync) {
			write_state = WR_COPIED;
			len = MIN(ZIL_MAX_LOG_DATA, size);
		} else {
			write_state = WR_NEED_COPY;
			len = MIN(ZIL_MAX_LOG_DATA, size);
		}

		itx = zil_itx_create(TX_WRITE, sizeof (*lr) +
		    (write_state == WR_COPIED ? len : 0));
		lr = (lr_write_t *)&itx->itx_lr;
		if (write_state == WR_COPIED && dmu_read(zv->zv_objset,
		    ZVOL_OBJ, offset, len, lr+1, DMU_READ_NO_PREFETCH) != 0) {
			zil_itx_destroy(itx);
			itx = zil_itx_create(TX_WRITE, sizeof (*lr));
			lr = (lr_write_t *)&itx->itx_lr;
			write_state = WR_NEED_COPY;
		}

		itx->itx_wr_state = write_state;
		if (write_state == WR_NEED_COPY)
			itx->itx_sod += len;
		lr->lr_foid = ZVOL_OBJ;
		lr->lr_offset = offset;
		lr->lr_length = len;
		lr->lr_blkoff = 0;
		BP_ZERO(&lr->lr_blkptr);

		itx->itx_private = zv;
		itx->itx_sync = sync;

		(void) zil_itx_assign(zilog, itx, tx);

		offset += len;
		size -= len;
	}
}
Esempio n. 4
0
File: zfs_log.c Progetto: LLNL/zfs
/*
 * Handles TX_ACL transactions.
 */
void
zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp,
    vsecattr_t *vsecp, zfs_fuid_info_t *fuidp)
{
	itx_t *itx;
	lr_acl_v0_t *lrv0;
	lr_acl_t *lr;
	int txtype;
	int lrsize;
	size_t txsize;
	size_t aclbytes = vsecp->vsa_aclentsz;

	if (zil_replaying(zilog, tx) || zp->z_unlinked)
		return;

	txtype = (ZTOZSB(zp)->z_version < ZPL_VERSION_FUID) ?
	    TX_ACL_V0 : TX_ACL;

	if (txtype == TX_ACL)
		lrsize = sizeof (*lr);
	else
		lrsize = sizeof (*lrv0);

	txsize = lrsize +
	    ((txtype == TX_ACL) ? ZIL_ACE_LENGTH(aclbytes) : aclbytes) +
	    (fuidp ? fuidp->z_domain_str_sz : 0) +
	    sizeof (uint64_t) * (fuidp ? fuidp->z_fuid_cnt : 0);

	itx = zil_itx_create(txtype, txsize);

	lr = (lr_acl_t *)&itx->itx_lr;
	lr->lr_foid = zp->z_id;
	if (txtype == TX_ACL) {
		lr->lr_acl_bytes = aclbytes;
		lr->lr_domcnt = fuidp ? fuidp->z_domain_cnt : 0;
		lr->lr_fuidcnt = fuidp ? fuidp->z_fuid_cnt : 0;
		if (vsecp->vsa_mask & VSA_ACE_ACLFLAGS)
			lr->lr_acl_flags = (uint64_t)vsecp->vsa_aclflags;
		else
			lr->lr_acl_flags = 0;
	}
	lr->lr_aclcnt = (uint64_t)vsecp->vsa_aclcnt;

	if (txtype == TX_ACL_V0) {
		lrv0 = (lr_acl_v0_t *)lr;
		bcopy(vsecp->vsa_aclentp, (ace_t *)(lrv0 + 1), aclbytes);
	} else {
		void *start = (ace_t *)(lr + 1);

		bcopy(vsecp->vsa_aclentp, start, aclbytes);

		start = (caddr_t)start + ZIL_ACE_LENGTH(aclbytes);

		if (fuidp) {
			start = zfs_log_fuid_ids(fuidp, start);
			(void) zfs_log_fuid_domains(fuidp, start);
		}
	}

	itx->itx_sync = (zp->z_sync_cnt != 0);
	zil_itx_assign(zilog, itx, tx);
}
Esempio n. 5
0
File: zfs_log.c Progetto: LLNL/zfs
void
zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
    znode_t *zp, offset_t off, ssize_t resid, int ioflag,
    zil_callback_t callback, void *callback_data)
{
	uint32_t blocksize = zp->z_blksz;
	itx_wr_state_t write_state;
	uintptr_t fsync_cnt;

	if (zil_replaying(zilog, tx) || zp->z_unlinked ||
	    zfs_xattr_owner_unlinked(zp)) {
		if (callback != NULL)
			callback(callback_data);
		return;
	}

	if (zilog->zl_logbias == ZFS_LOGBIAS_THROUGHPUT)
		write_state = WR_INDIRECT;
	else if (!spa_has_slogs(zilog->zl_spa) &&
	    resid >= zfs_immediate_write_sz)
		write_state = WR_INDIRECT;
	else if (ioflag & (FSYNC | FDSYNC))
		write_state = WR_COPIED;
	else
		write_state = WR_NEED_COPY;

	if ((fsync_cnt = (uintptr_t)tsd_get(zfs_fsyncer_key)) != 0) {
		(void) tsd_set(zfs_fsyncer_key, (void *)(fsync_cnt - 1));
	}

	while (resid) {
		itx_t *itx;
		lr_write_t *lr;
		itx_wr_state_t wr_state = write_state;
		ssize_t len = resid;

		if (wr_state == WR_COPIED && resid > ZIL_MAX_COPIED_DATA)
			wr_state = WR_NEED_COPY;
		else if (wr_state == WR_INDIRECT)
			len = MIN(blocksize - P2PHASE(off, blocksize), resid);

		itx = zil_itx_create(txtype, sizeof (*lr) +
		    (wr_state == WR_COPIED ? len : 0));
		lr = (lr_write_t *)&itx->itx_lr;
		if (wr_state == WR_COPIED && dmu_read(ZTOZSB(zp)->z_os,
		    zp->z_id, off, len, lr + 1, DMU_READ_NO_PREFETCH) != 0) {
			zil_itx_destroy(itx);
			itx = zil_itx_create(txtype, sizeof (*lr));
			lr = (lr_write_t *)&itx->itx_lr;
			wr_state = WR_NEED_COPY;
		}

		itx->itx_wr_state = wr_state;
		lr->lr_foid = zp->z_id;
		lr->lr_offset = off;
		lr->lr_length = len;
		lr->lr_blkoff = 0;
		BP_ZERO(&lr->lr_blkptr);

		itx->itx_private = ZTOZSB(zp);

		if (!(ioflag & (FSYNC | FDSYNC)) && (zp->z_sync_cnt == 0) &&
		    (fsync_cnt == 0))
			itx->itx_sync = B_FALSE;

		itx->itx_callback = callback;
		itx->itx_callback_data = callback_data;
		zil_itx_assign(zilog, itx, tx);

		off += len;
		resid -= len;
	}
}
Esempio n. 6
0
void
zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
	znode_t *zp, offset_t off, ssize_t resid, int ioflag)
{
	itx_wr_state_t write_state;
	boolean_t slogging;
	uintptr_t fsync_cnt;

	if (zilog == NULL || zp->z_unlinked)
		return;

	/*
	 * Writes are handled in three different ways:
	 *
	 * WR_INDIRECT:
	 *    If the write is greater than zfs_immediate_write_sz and there are
	 *    no separate logs in this pool then later *if* we need to log the
	 *    write then dmu_sync() is used to immediately write the block and
	 *    its block pointer is put in the log record.
	 * WR_COPIED:
	 *    If we know we'll immediately be committing the
	 *    transaction (FDSYNC (O_DSYNC)), the we allocate a larger
	 *    log record here for the data and copy the data in.
	 * WR_NEED_COPY:
	 *    Otherwise we don't allocate a buffer, and *if* we need to
	 *    flush the write later then a buffer is allocated and
	 *    we retrieve the data using the dmu.
	 */
	slogging = spa_has_slogs(zilog->zl_spa);
	if (resid > zfs_immediate_write_sz && !slogging)
		write_state = WR_INDIRECT;
	else if (ioflag & FDSYNC)
		write_state = WR_COPIED;
	else
		write_state = WR_NEED_COPY;
#ifndef __APPLE__
	if ((fsync_cnt = (uintptr_t)tsd_get(zfs_fsyncer_key)) != 0) {
		(void) tsd_set(zfs_fsyncer_key, (void *)(fsync_cnt - 1));
	}
#endif
	while (resid) {
		itx_t *itx;
		lr_write_t *lr;
		ssize_t len;

		/*
		 * If there are slogs and the write would overflow the largest
		 * block, then because we don't want to use the main pool
		 * to dmu_sync, we have to split the write.
		 */
		if (slogging && resid > ZIL_MAX_LOG_DATA)
			len = SPA_MAXBLOCKSIZE >> 1;
		else
			len = resid;

		itx = zil_itx_create(txtype, sizeof (*lr) +
		    (write_state == WR_COPIED ? len : 0));
		lr = (lr_write_t *)&itx->itx_lr;
		if (write_state == WR_COPIED && dmu_read(zp->z_zfsvfs->z_os,
		    zp->z_id, off, len, lr + 1) != 0) {
			kmem_free(itx, offsetof(itx_t, itx_lr) +
			    itx->itx_lr.lrc_reclen);
			itx = zil_itx_create(txtype, sizeof (*lr));
			lr = (lr_write_t *)&itx->itx_lr;
			write_state = WR_NEED_COPY;
		}

		itx->itx_wr_state = write_state;
		lr->lr_foid = zp->z_id;
		lr->lr_offset = off;
		lr->lr_length = len;
		lr->lr_blkoff = 0;
		BP_ZERO(&lr->lr_blkptr);

		itx->itx_private = zp->z_zfsvfs;

		if ((zp->z_sync_cnt != 0) || (fsync_cnt != 0))
			itx->itx_sync = B_TRUE;
		else
			itx->itx_sync = B_FALSE;

		zp->z_last_itx = zil_itx_assign(zilog, itx, tx);

		off += len;
		resid -= len;
	}
Esempio n. 7
0
void
zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
              znode_t *zp, offset_t off, ssize_t resid, int ioflag)
{
    itx_wr_state_t write_state;
    boolean_t slogging;
    uintptr_t fsync_cnt;

    if (zilog == NULL || zp->z_unlinked)
        return;

    ZFS_HANDLE_REPLAY(zilog, tx); /* exits if replay */

    slogging = spa_has_slogs(zilog->zl_spa);
    if (resid > zfs_immediate_write_sz && !slogging && resid <= zp->z_blksz)
        write_state = WR_INDIRECT;
    else if (ioflag & (FSYNC | FDSYNC))
        write_state = WR_COPIED;
    else
        write_state = WR_NEED_COPY;

    if ((fsync_cnt = (uintptr_t)tsd_get(zfs_fsyncer_key)) != 0) {
        (void) tsd_set(zfs_fsyncer_key, (void *)(fsync_cnt - 1));
    }

    while (resid) {
        itx_t *itx;
        lr_write_t *lr;
        ssize_t len;

        /*
         * If the write would overflow the largest block then split it.
         */
        if (write_state != WR_INDIRECT && resid > ZIL_MAX_LOG_DATA)
            len = SPA_MAXBLOCKSIZE >> 1;
        else
            len = resid;

        itx = zil_itx_create(txtype, sizeof (*lr) +
                             (write_state == WR_COPIED ? len : 0));
        lr = (lr_write_t *)&itx->itx_lr;
        if (write_state == WR_COPIED && dmu_read(zp->z_zfsvfs->z_os,
                zp->z_id, off, len, lr + 1, DMU_READ_NO_PREFETCH) != 0) {
            kmem_free(itx, offsetof(itx_t, itx_lr) +
                      itx->itx_lr.lrc_reclen);
            itx = zil_itx_create(txtype, sizeof (*lr));
            lr = (lr_write_t *)&itx->itx_lr;
            write_state = WR_NEED_COPY;
        }

        itx->itx_wr_state = write_state;
        if (write_state == WR_NEED_COPY)
            itx->itx_sod += len;
        lr->lr_foid = zp->z_id;
        lr->lr_offset = off;
        lr->lr_length = len;
        lr->lr_blkoff = 0;
        BP_ZERO(&lr->lr_blkptr);

        itx->itx_private = zp->z_zfsvfs;

        if ((zp->z_sync_cnt != 0) || (fsync_cnt != 0) ||
                (ioflag & (FSYNC | FDSYNC)))
            itx->itx_sync = B_TRUE;
        else
            itx->itx_sync = B_FALSE;

        zp->z_last_itx = zil_itx_assign(zilog, itx, tx);

        off += len;
        resid -= len;
    }
Esempio n. 8
0
/*
 * zfs_log_create() is used to handle TX_CREATE, TX_CREATE_ATTR, TX_MKDIR,
 * TX_MKDIR_ATTR and TX_MKXATTR
 * transactions.
 *
 * TX_CREATE and TX_MKDIR are standard creates, but they may have FUID
 * domain information appended prior to the name.  In this case the
 * uid/gid in the log record will be a log centric FUID.
 *
 * TX_CREATE_ACL_ATTR and TX_MKDIR_ACL_ATTR handle special creates that
 * may contain attributes, ACL and optional fuid information.
 *
 * TX_CREATE_ACL and TX_MKDIR_ACL handle special creates that specify
 * and ACL and normal users/groups in the ACEs.
 *
 * There may be an optional xvattr attribute information similar
 * to zfs_log_setattr.
 *
 * Also, after the file name "domain" strings may be appended.
 */
void
zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
               znode_t *dzp, znode_t *zp, char *name, vsecattr_t *vsecp,
               zfs_fuid_info_t *fuidp, vattr_t *vap)
{
    itx_t *itx;
    uint64_t seq;
    lr_create_t *lr;
#ifdef HAVE_ZPL
    lr_acl_create_t *lracl;
#endif
    size_t aclsize;
    size_t xvatsize = 0;
    size_t txsize;
    xvattr_t *xvap = (xvattr_t *)vap;
    void *end;
    size_t lrsize;
    size_t namesize = strlen(name) + 1;
    size_t fuidsz = 0;

    if (zilog == NULL)
        return;

    ZFS_HANDLE_REPLAY(zilog, tx); /* exits if replay */

    /*
     * If we have FUIDs present then add in space for
     * domains and ACE fuid's if any.
     */
    if (fuidp) {
        fuidsz += fuidp->z_domain_str_sz;
        fuidsz += fuidp->z_fuid_cnt * sizeof (uint64_t);
    }

    if (vap->va_mask & AT_XVATTR)
        xvatsize = ZIL_XVAT_SIZE(xvap->xva_mapsize);

    if ((int)txtype == TX_CREATE_ATTR || (int)txtype == TX_MKDIR_ATTR ||
            (int)txtype == TX_CREATE || (int)txtype == TX_MKDIR ||
            (int)txtype == TX_MKXATTR) {
        txsize = sizeof (*lr) + namesize + fuidsz + xvatsize;
        lrsize = sizeof (*lr);
    } else {
        aclsize = (vsecp) ? vsecp->vsa_aclentsz : 0;
        txsize =
            sizeof (lr_acl_create_t) + namesize + fuidsz +
            ZIL_ACE_LENGTH(aclsize) + xvatsize;
        lrsize = sizeof (lr_acl_create_t);
    }

    itx = zil_itx_create(txtype, txsize);

    lr = (lr_create_t *)&itx->itx_lr;
    lr->lr_doid = dzp->z_id;
    lr->lr_foid = zp->z_id;
    lr->lr_mode = zp->z_phys->zp_mode;
    if (!IS_EPHEMERAL(zp->z_phys->zp_uid)) {
        lr->lr_uid = (uint64_t)zp->z_phys->zp_uid;
    } else {
        lr->lr_uid = fuidp->z_fuid_owner;
    }
    if (!IS_EPHEMERAL(zp->z_phys->zp_gid)) {
        lr->lr_gid = (uint64_t)zp->z_phys->zp_gid;
    } else {
        lr->lr_gid = fuidp->z_fuid_group;
    }
    lr->lr_gen = zp->z_phys->zp_gen;
    lr->lr_crtime[0] = zp->z_phys->zp_crtime[0];
    lr->lr_crtime[1] = zp->z_phys->zp_crtime[1];
    lr->lr_rdev = zp->z_phys->zp_rdev;

    /*
     * Fill in xvattr info if any
     */
#ifdef HAVE_ZPL
    if (vap->va_mask & AT_XVATTR) {
        zfs_log_xvattr((lr_attr_t *)((caddr_t)lr + lrsize), xvap);
        end = (caddr_t)lr + lrsize + xvatsize;
    } else {
        end = (caddr_t)lr + lrsize;
    }
#else
    end = (caddr_t)lr + lrsize;
#endif /* HAVE_ZPL */


    /* Now fill in any ACL info */

#ifdef HAVE_ZPL
    if (vsecp) {
        lracl = (lr_acl_create_t *)&itx->itx_lr;
        lracl->lr_aclcnt = vsecp->vsa_aclcnt;
        lracl->lr_acl_bytes = aclsize;
        lracl->lr_domcnt = fuidp ? fuidp->z_domain_cnt : 0;
        lracl->lr_fuidcnt  = fuidp ? fuidp->z_fuid_cnt : 0;
        if (vsecp->vsa_aclflags & VSA_ACE_ACLFLAGS)
            lracl->lr_acl_flags = (uint64_t)vsecp->vsa_aclflags;
        else
            lracl->lr_acl_flags = 0;

        bcopy(vsecp->vsa_aclentp, end, aclsize);
        end = (caddr_t)end + ZIL_ACE_LENGTH(aclsize);
    }

    /* drop in FUID info */
    if (fuidp) {
        end = zfs_log_fuid_ids(fuidp, end);
        end = zfs_log_fuid_domains(fuidp, end);
    }
#endif
    /*
     * Now place file name in log record
     */
    bcopy(name, end, namesize);

    seq = zil_itx_assign(zilog, itx, tx);
    dzp->z_last_itx = seq;
    zp->z_last_itx = seq;
}