/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2013, 2015 by Delphix. All rights reserved.
*/
#include <sys/sysmacros.h>
#include <sys/zfs_znode.h>
#include <sys/zfs_fuid.h>
#include <sys/byteorder.h>
/*
* Functions to replay ZFS intent log (ZIL) records
* The functions are called through a function vector (zfs_replay_vector)
* which is indexed by the transaction type.
*/
static void
{
}
/* ARGSUSED */
static int
{
}
static void
{
void *scanstamp;
int i;
return;
}
((*attrs & XAT0_AV_QUARANTINED) != 0);
}
static int
{
int domcnt = 0;
if (uid_idx)
domcnt++;
domcnt++;
return (domcnt);
}
static void *
int domcnt)
{
int i;
for (i = 0; i != domcnt; i++) {
}
return (start);
}
/*
*/
static void
{
/*
* If owner or group are log specific FUIDs then slurp up
* domain information and build zfs_fuid_info_t
*/
if (IS_EPHEMERAL(uid))
if (IS_EPHEMERAL(gid))
}
/*
* Load fuid domains into fuid_info_t
*/
static zfs_fuid_info_t *
{
int domcnt;
if (domcnt == 0)
return (fuid_infop);
return (fuid_infop);
}
/*
* load zfs_fuid_t's and fuid_domains into fuid_info_t
*/
static zfs_fuid_info_t *
{
int i;
for (i = 0; i != idcnt; i++) {
log_fuid++;
}
return (fuid_infop);
}
static void
{
/* swap the lr_attr structure */
/* swap the bitmap */
sizeof (uint32_t));
/* swap the attributes, create time + 64 bit word for attributes */
}
/*
* Replay file create with optional ACL, xvattr information as well
* as option FUID information.
*/
static int
{
int vflg = 0;
void *aclstart;
void *fuidstart;
int error;
if (byteswap) {
if (txtype == TX_CREATE_ACL_ATTR ||
txtype == TX_MKDIR_ACL_ATTR) {
}
/* swap fuids */
if (lracl->lr_fuidcnt) {
}
}
return (error);
/*
* All forms of zfs create (create, mkdir, mkxattrdir, symlink)
* eventually end up in zfs_mknode(), which assigns the object's
* creation time and generation number. The generic VOP_CREATE()
* doesn't have either concept, so we smuggle the values inside
* the vattr's otherwise unused va_ctime and va_nblocks fields.
*/
goto bail;
vflg |= FIGNORECASE;
switch (txtype) {
case TX_CREATE_ACL:
/*FALLTHROUGH*/
case TX_CREATE_ACL_ATTR:
}
}
break;
case TX_MKDIR_ACL:
/*FALLTHROUGH*/
case TX_MKDIR_ACL_ATTR:
}
}
break;
default:
}
bail:
if (zfsvfs->z_fuid_replay)
return (error);
}
static int
{
int vflg = 0;
void *start;
int error;
if (byteswap) {
}
return (error);
/*
* All forms of zfs create (create, mkdir, mkxattrdir, symlink)
* eventually end up in zfs_mknode(), which assigns the object's
* creation time and generation number. The generic VOP_CREATE()
* doesn't have either concept, so we smuggle the values inside
* the vattr's otherwise unused va_ctime and va_nblocks fields.
*/
goto out;
vflg |= FIGNORECASE;
/*
* Symlinks don't have fuid info, and CIFS never creates
* symlinks.
*
* The _ATTR versions will grab the fuid info in their subcases.
*/
}
switch (txtype) {
case TX_CREATE_ATTR:
/*FALLTHROUGH*/
case TX_CREATE:
break;
case TX_MKDIR_ATTR:
/*FALLTHROUGH*/
case TX_MKDIR:
break;
case TX_MKXATTR:
break;
case TX_SYMLINK:
break;
default:
}
out:
if (zfsvfs->z_fuid_replay)
return (error);
}
static int
{
int error;
int vflg = 0;
if (byteswap)
return (error);
vflg |= FIGNORECASE;
case TX_REMOVE:
break;
case TX_RMDIR:
break;
default:
}
return (error);
}
static int
{
int error;
int vflg = 0;
if (byteswap)
return (error);
return (error);
}
vflg |= FIGNORECASE;
return (error);
}
static int
{
int error;
int vflg = 0;
if (byteswap)
return (error);
return (error);
}
vflg |= FIGNORECASE;
return (error);
}
static int
{
int error;
if (byteswap)
/*
* As we can log writes out of order, it's possible the
* file has been removed. In this case just drop the write
* and return success.
*/
error = 0;
return (error);
}
/*
* This may be a write from a dmu_sync() for a whole block,
* and may extend beyond the current end of the file.
* We can't just replay what was written for this TX_WRITE as
* a future TX_WRITE2 may extend the eof and the data for that
* write needs to be there. So we write the whole block and
* reduce the eof. This needs to be done within the single dmu
* transaction created within vn_rdwr -> zfs_write. So a possible
* new end of file is passed through in zfsvfs->z_replay_eof
*/
/* If it's a dmu_sync() block, write the whole block */
}
}
return (error);
}
/*
* TX_WRITE2 are only generated when dmu_sync() returns EALREADY
* meaning the pool block is already being synced. So now that we always write
* out full blocks, all we have to do is expand the eof if
* the file is grown.
*/
static int
{
int error;
if (byteswap)
return (error);
top:
if (error) {
goto top;
}
return (error);
}
/* Ensure the replayed seq is updated */
}
return (error);
}
static int
{
int error;
if (byteswap)
return (error);
return (error);
}
static int
{
int error;
void *start;
if (byteswap) {
}
return (error);
/*
* Fill in xvattr_t portions if necessary.
*/
} else
return (error);
}
static int
{
int error;
if (byteswap) {
}
return (error);
vsa.vsa_aclflags = 0;
return (error);
}
/*
* 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.
*
* longer valid and will need to be replaced with an actual FUID.
*
*/
static int
{
int error;
if (byteswap) {
if (lr->lr_fuidcnt) {
}
}
return (error);
if (lr->lr_fuidcnt) {
}
if (zfsvfs->z_fuid_replay)
return (error);
}
/*
* Callback vectors for replaying records
*/
zfs_replay_error, /* 0 no such transaction type */
zfs_replay_create, /* TX_CREATE */
zfs_replay_create, /* TX_MKDIR */
zfs_replay_create, /* TX_MKXATTR */
zfs_replay_create, /* TX_SYMLINK */
zfs_replay_remove, /* TX_REMOVE */
zfs_replay_remove, /* TX_RMDIR */
zfs_replay_link, /* TX_LINK */
zfs_replay_rename, /* TX_RENAME */
zfs_replay_write, /* TX_WRITE */
zfs_replay_truncate, /* TX_TRUNCATE */
zfs_replay_setattr, /* TX_SETATTR */
zfs_replay_acl_v0, /* TX_ACL_V0 */
zfs_replay_acl, /* TX_ACL */
zfs_replay_create_acl, /* TX_CREATE_ACL */
zfs_replay_create, /* TX_CREATE_ATTR */
zfs_replay_create_acl, /* TX_CREATE_ACL_ATTR */
zfs_replay_create_acl, /* TX_MKDIR_ACL */
zfs_replay_create, /* TX_MKDIR_ATTR */
zfs_replay_create_acl, /* TX_MKDIR_ACL_ATTR */
zfs_replay_write2, /* TX_WRITE2 */
};