zfs_replay.c revision 569e6c63191416b7413c148fd5a6194a0b820b2c
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * CDDL HEADER START
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The contents of this file are subject to the terms of the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Common Development and Distribution License (the "License").
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * You may not use this file except in compliance with the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * See the License for the specific language governing permissions
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * and limitations under the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * When distributing Covered Code, include this CDDL HEADER in each
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * If applicable, add the following below this CDDL HEADER, with the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * fields enclosed by brackets "[]" replaced with your own identifying
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * information: Portions Copyright [yyyy] [name of copyright owner]
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * CDDL HEADER END
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Use is subject to license terms.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster#pragma ident "%Z%%M% %I% %E% SMI"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Functions to replay ZFS intent log (ZIL) records
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The functions are called through a function vector (zfs_replay_vector)
a90aba9cbcbb8e7fe95e45590d853959efe0d354Tom Rumsey * which is indexed by the transaction type.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterzfs_init_vattr(vattr_t *vap, uint64_t mask, uint64_t mode,
1d407e39b7d8f68d9a2b1e178f35fab037d9835aRobert Wapshott uint64_t uid, uint64_t gid, uint64_t rdev, uint64_t nodeid)
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott vap->va_uid = (uid_t)(IS_EPHEMERAL(uid)) ? -1 : uid;
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott vap->va_gid = (gid_t)(IS_EPHEMERAL(gid)) ? -1 : gid;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/* ARGSUSED */
1d407e39b7d8f68d9a2b1e178f35fab037d9835aRobert Wapshottzfs_replay_error(zfsvfs_t *zfsvfs, lr_t *lr, boolean_t byteswap)
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumseyzfs_replay_xvattr(lr_attr_t *lrattr, xvattr_t *xvap)
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey xvap->xva_vattr.va_mask &= ~AT_XVATTR; /* shouldn't happen */
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey ASSERT(lrattr->lr_attr_masksize == xvap->xva_mapsize);
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey for (i = 0; i != lrattr->lr_attr_masksize; i++, bitmap++)
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott attrs = (uint64_t *)(lrattr + lrattr->lr_attr_masksize - 1);
a90aba9cbcbb8e7fe95e45590d853959efe0d354Tom Rumsey xoap->xoa_hidden = ((*attrs & XAT0_HIDDEN) != 0);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster xoap->xoa_system = ((*attrs & XAT0_SYSTEM) != 0);
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott xoap->xoa_archive = ((*attrs & XAT0_ARCHIVE) != 0);
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott xoap->xoa_readonly = ((*attrs & XAT0_READONLY) != 0);
786bac66d599daf6355e45e64da84c846a857552Craig McDonnell xoap->xoa_immutable = ((*attrs & XAT0_IMMUTABLE) != 0);
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott xoap->xoa_nounlink = ((*attrs & XAT0_NOUNLINK) != 0);
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott xoap->xoa_appendonly = ((*attrs & XAT0_APPENDONLY) != 0);
a90aba9cbcbb8e7fe95e45590d853959efe0d354Tom Rumsey xoap->xoa_nodump = ((*attrs & XAT0_NODUMP) != 0);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster xoap->xoa_opaque = ((*attrs & XAT0_OPAQUE) != 0);
c6c8bcf74a1e796c167156af1cc1a5d95c67aceaRobert Wapshott xoap->xoa_av_modified = ((*attrs & XAT0_AV_MODIFIED) != 0);
c6c8bcf74a1e796c167156af1cc1a5d95c67aceaRobert Wapshott if (XVA_ISSET_REQ(xvap, XAT_AV_QUARANTINED))
c6c8bcf74a1e796c167156af1cc1a5d95c67aceaRobert Wapshott ZFS_TIME_DECODE(&xoap->xoa_createtime, crtime);
c6c8bcf74a1e796c167156af1cc1a5d95c67aceaRobert Wapshott bcopy(scanstamp, xoap->xoa_av_scanstamp, AV_SCANSTAMP_SZ);
c6c8bcf74a1e796c167156af1cc1a5d95c67aceaRobert Wapshottzfs_replay_domain_cnt(uint64_t uid, uint64_t gid)
be367fb48c4c5a05214aab48aea9f09703b63a97Craig McDonnellzfs_replay_fuid_domain_common(zfs_fuid_info_t *fuid_infop, void *start,
786bac66d599daf6355e45e64da84c846a857552Craig McDonnell for (i = 0; i != domcnt; i++) {
786bac66d599daf6355e45e64da84c846a857552Craig McDonnell * Set the uid/gid in the fuid_info structure.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterzfs_replay_fuid_ugid(zfs_fuid_info_t *fuid_infop, uint64_t uid, uint64_t gid)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * If owner or group are log specific FUIDs then slurp up
786bac66d599daf6355e45e64da84c846a857552Craig McDonnell * domain information and build zfs_fuid_info_t
786bac66d599daf6355e45e64da84c846a857552Craig McDonnell * Load fuid domains into fuid_info_t
786bac66d599daf6355e45e64da84c846a857552Craig McDonnellzfs_replay_fuid_domain(void *buf, void **end, uint64_t uid, uint64_t gid)
786bac66d599daf6355e45e64da84c846a857552Craig McDonnell kmem_zalloc(domcnt * sizeof (char **), KM_SLEEP);
786bac66d599daf6355e45e64da84c846a857552Craig McDonnell *end = zfs_replay_fuid_domain_common(fuid_infop, buf, domcnt);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * load zfs_fuid_t's and fuid_domains into fuid_info_t
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumseyzfs_replay_fuids(void *start, void **end, int idcnt, int domcnt, uint64_t uid,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster kmem_zalloc(domcnt * sizeof (char **), KM_SLEEP);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for (i = 0; i != idcnt; i++) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster zfuid = kmem_alloc(sizeof (zfs_fuid_t), KM_SLEEP);
786bac66d599daf6355e45e64da84c846a857552Craig McDonnell list_insert_tail(&fuid_infop->z_fuids, zfuid);
786bac66d599daf6355e45e64da84c846a857552Craig McDonnell *end = zfs_replay_fuid_domain_common(fuid_infop, log_fuid, domcnt);
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey /* swap the lr_attr structure */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /* swap the bitmap */
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey byteswap_uint32_array(lrattr + 1, (lrattr->lr_attr_masksize - 1) *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /* swap the attributes, create time + 64 bit word for attributes */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster byteswap_uint64_array((caddr_t)(lrattr + 1) + (sizeof (uint32_t) *
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey (lrattr->lr_attr_masksize - 1)), 3 * sizeof (uint64_t));
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey * Replay file create with optional ACL, xvattr information as well
c5b669842423d36fc543ddd3ea318bbae4231ecfTom Rumsey * as option FUID information.
d552ef9965b495ec6fa5f89b12ad638ad4cc87f4Tony Bamford char *name = NULL; /* location determined later */
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize);
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey zfs_ace_byteswap(aclstart, lracl->lr_acl_bytes, B_FALSE);
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey /* swap fuids */
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey if ((error = zfs_zget(zfsvfs, lr->lr_doid, &dzp)) != 0)
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey zfs_init_vattr(&xva.xva_vattr, AT_TYPE | AT_MODE | AT_UID | AT_GID,
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey lr->lr_mode, lr->lr_uid, lr->lr_gid, lr->lr_rdev, lr->lr_foid);
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey * All forms of zfs create (create, mkdir, mkxattrdir, symlink)
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey * eventually end up in zfs_mknode(), which assigns the object's
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey * creation time and generation number. The generic VOP_CREATE()
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey * doesn't have either concept, so we smuggle the values inside
d552ef9965b495ec6fa5f89b12ad638ad4cc87f4Tony Bamford * the vattr's otherwise unused va_ctime and va_nblocks fields.
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey ZFS_TIME_DECODE(&xva.xva_vattr.va_ctime, lr->lr_crtime);
8a888dac872ea5d7dd9ce4a0739c4065d544f275Tom Rumsey error = dmu_object_info(zfsvfs->z_os, lr->lr_foid, NULL);
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey zfsvfs->z_fuid_replay = zfs_replay_fuids(fuidstart,
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt,
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey /*FALLTHROUGH*/
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize);
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey vsec.vsa_aclentp = (caddr_t)(lracl + 1) + xvatlen;
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt,
a90aba9cbcbb8e7fe95e45590d853959efe0d354Tom Rumsey error = VOP_CREATE(ZTOV(dzp), name, &xva.xva_vattr,
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey zfsvfs->z_fuid_replay = zfs_replay_fuids(fuidstart,
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt,
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey /*FALLTHROUGH*/
6309b849c2de831a0eaed9c27b5794bed9bd8fd1Neil Madden xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize);
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey vsec.vsa_aclentp = (caddr_t)(lracl + 1) + xvatlen;
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt,
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey error = VOP_MKDIR(ZTOV(dzp), name, &xva.xva_vattr,
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumseyzfs_replay_create(zfsvfs_t *zfsvfs, lr_create_t *lr, boolean_t byteswap)
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey char *name = NULL; /* location determined later */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (txtype == TX_CREATE_ATTR || txtype == TX_MKDIR_ATTR)
d552ef9965b495ec6fa5f89b12ad638ad4cc87f4Tony Bamford if ((error = zfs_zget(zfsvfs, lr->lr_doid, &dzp)) != 0)
d552ef9965b495ec6fa5f89b12ad638ad4cc87f4Tony Bamford zfs_init_vattr(&xva.xva_vattr, AT_TYPE | AT_MODE | AT_UID | AT_GID,
d552ef9965b495ec6fa5f89b12ad638ad4cc87f4Tony Bamford lr->lr_mode, lr->lr_uid, lr->lr_gid, lr->lr_rdev, lr->lr_foid);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * All forms of zfs create (create, mkdir, mkxattrdir, symlink)
4e28a378d7cafffd7988c4c3783c820db42ffb9dAndrew Forrest * eventually end up in zfs_mknode(), which assigns the object's
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * creation time and generation number. The generic VOP_CREATE()
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * doesn't have either concept, so we smuggle the values inside
786bac66d599daf6355e45e64da84c846a857552Craig McDonnell * the vattr's otherwise unused va_ctime and va_nblocks fields.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ZFS_TIME_DECODE(&xva.xva_vattr.va_ctime, lr->lr_crtime);
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott error = dmu_object_info(zfsvfs->z_os, lr->lr_foid, NULL);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Symlinks don't have fuid info, and CIFS never creates
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The _ATTR versions will grab the fuid info in their subcases.
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey if ((int)lr->lr_common.lrc_txtype != TX_SYMLINK &&
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey (int)lr->lr_common.lrc_txtype != TX_MKDIR_ATTR &&
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey (int)lr->lr_common.lrc_txtype != TX_CREATE_ATTR) {
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize);
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey zfs_replay_xvattr((lr_attr_t *)((caddr_t)lr + lrsize), &xva);
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey /*FALLTHROUGH*/
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey error = VOP_CREATE(ZTOV(dzp), name, &xva.xva_vattr,
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize);
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey zfs_replay_xvattr((lr_attr_t *)((caddr_t)lr + lrsize), &xva);
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey /*FALLTHROUGH*/
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey error = VOP_MKDIR(ZTOV(dzp), name, &xva.xva_vattr,
a19a421277791c670d5a4ebcd6d7af7de159d271Tom Rumsey error = zfs_make_xattrdir(dzp, &xva.xva_vattr, &vp, kcred);
out:
return (error);
int error;
int vflg = 0;
if (byteswap)
return (error);
case TX_REMOVE:
case TX_RMDIR:
return (error);
int error;
int vflg = 0;
if (byteswap)
return (error);
return (error);
return (error);
int error;
int vflg = 0;
if (byteswap)
return (error);
return (error);
return (error);
int error;
if (byteswap)
error = 0;
return (error);
return (error);
int error;
if (byteswap)
error = 0;
return (error);
return (error);
int error;
void *start;
if (byteswap) {
error = 0;
return (error);
return (error);
int error;
if (byteswap) {
error = 0;
return (error);
return (error);
int error;
if (byteswap) {
error = 0;
return (error);
return (error);