1*eda14cbcSMatt Macy /* 2*eda14cbcSMatt Macy * CDDL HEADER START 3*eda14cbcSMatt Macy * 4*eda14cbcSMatt Macy * The contents of this file are subject to the terms of the 5*eda14cbcSMatt Macy * Common Development and Distribution License (the "License"). 6*eda14cbcSMatt Macy * You may not use this file except in compliance with the License. 7*eda14cbcSMatt Macy * 8*eda14cbcSMatt Macy * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*eda14cbcSMatt Macy * or http://www.opensolaris.org/os/licensing. 10*eda14cbcSMatt Macy * See the License for the specific language governing permissions 11*eda14cbcSMatt Macy * and limitations under the License. 12*eda14cbcSMatt Macy * 13*eda14cbcSMatt Macy * When distributing Covered Code, include this CDDL HEADER in each 14*eda14cbcSMatt Macy * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*eda14cbcSMatt Macy * If applicable, add the following below this CDDL HEADER, with the 16*eda14cbcSMatt Macy * fields enclosed by brackets "[]" replaced with your own identifying 17*eda14cbcSMatt Macy * information: Portions Copyright [yyyy] [name of copyright owner] 18*eda14cbcSMatt Macy * 19*eda14cbcSMatt Macy * CDDL HEADER END 20*eda14cbcSMatt Macy */ 21*eda14cbcSMatt Macy /* 22*eda14cbcSMatt Macy * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 23*eda14cbcSMatt Macy * Copyright (c) 2015, 2018 by Delphix. All rights reserved. 24*eda14cbcSMatt Macy */ 25*eda14cbcSMatt Macy 26*eda14cbcSMatt Macy 27*eda14cbcSMatt Macy #include <sys/types.h> 28*eda14cbcSMatt Macy #include <sys/param.h> 29*eda14cbcSMatt Macy #include <sys/sysmacros.h> 30*eda14cbcSMatt Macy #include <sys/cmn_err.h> 31*eda14cbcSMatt Macy #include <sys/kmem.h> 32*eda14cbcSMatt Macy #include <sys/thread.h> 33*eda14cbcSMatt Macy #include <sys/file.h> 34*eda14cbcSMatt Macy #include <sys/vfs.h> 35*eda14cbcSMatt Macy #include <sys/zfs_znode.h> 36*eda14cbcSMatt Macy #include <sys/zfs_dir.h> 37*eda14cbcSMatt Macy #include <sys/zil.h> 38*eda14cbcSMatt Macy #include <sys/zil_impl.h> 39*eda14cbcSMatt Macy #include <sys/byteorder.h> 40*eda14cbcSMatt Macy #include <sys/policy.h> 41*eda14cbcSMatt Macy #include <sys/stat.h> 42*eda14cbcSMatt Macy #include <sys/acl.h> 43*eda14cbcSMatt Macy #include <sys/dmu.h> 44*eda14cbcSMatt Macy #include <sys/dbuf.h> 45*eda14cbcSMatt Macy #include <sys/spa.h> 46*eda14cbcSMatt Macy #include <sys/zfs_fuid.h> 47*eda14cbcSMatt Macy #include <sys/dsl_dataset.h> 48*eda14cbcSMatt Macy 49*eda14cbcSMatt Macy /* 50*eda14cbcSMatt Macy * These zfs_log_* functions must be called within a dmu tx, in one 51*eda14cbcSMatt Macy * of 2 contexts depending on zilog->z_replay: 52*eda14cbcSMatt Macy * 53*eda14cbcSMatt Macy * Non replay mode 54*eda14cbcSMatt Macy * --------------- 55*eda14cbcSMatt Macy * We need to record the transaction so that if it is committed to 56*eda14cbcSMatt Macy * the Intent Log then it can be replayed. An intent log transaction 57*eda14cbcSMatt Macy * structure (itx_t) is allocated and all the information necessary to 58*eda14cbcSMatt Macy * possibly replay the transaction is saved in it. The itx is then assigned 59*eda14cbcSMatt Macy * a sequence number and inserted in the in-memory list anchored in the zilog. 60*eda14cbcSMatt Macy * 61*eda14cbcSMatt Macy * Replay mode 62*eda14cbcSMatt Macy * ----------- 63*eda14cbcSMatt Macy * We need to mark the intent log record as replayed in the log header. 64*eda14cbcSMatt Macy * This is done in the same transaction as the replay so that they 65*eda14cbcSMatt Macy * commit atomically. 66*eda14cbcSMatt Macy */ 67*eda14cbcSMatt Macy 68*eda14cbcSMatt Macy int 69*eda14cbcSMatt Macy zfs_log_create_txtype(zil_create_t type, vsecattr_t *vsecp, vattr_t *vap) 70*eda14cbcSMatt Macy { 71*eda14cbcSMatt Macy int isxvattr = (vap->va_mask & ATTR_XVATTR); 72*eda14cbcSMatt Macy switch (type) { 73*eda14cbcSMatt Macy case Z_FILE: 74*eda14cbcSMatt Macy if (vsecp == NULL && !isxvattr) 75*eda14cbcSMatt Macy return (TX_CREATE); 76*eda14cbcSMatt Macy if (vsecp && isxvattr) 77*eda14cbcSMatt Macy return (TX_CREATE_ACL_ATTR); 78*eda14cbcSMatt Macy if (vsecp) 79*eda14cbcSMatt Macy return (TX_CREATE_ACL); 80*eda14cbcSMatt Macy else 81*eda14cbcSMatt Macy return (TX_CREATE_ATTR); 82*eda14cbcSMatt Macy /*NOTREACHED*/ 83*eda14cbcSMatt Macy case Z_DIR: 84*eda14cbcSMatt Macy if (vsecp == NULL && !isxvattr) 85*eda14cbcSMatt Macy return (TX_MKDIR); 86*eda14cbcSMatt Macy if (vsecp && isxvattr) 87*eda14cbcSMatt Macy return (TX_MKDIR_ACL_ATTR); 88*eda14cbcSMatt Macy if (vsecp) 89*eda14cbcSMatt Macy return (TX_MKDIR_ACL); 90*eda14cbcSMatt Macy else 91*eda14cbcSMatt Macy return (TX_MKDIR_ATTR); 92*eda14cbcSMatt Macy case Z_XATTRDIR: 93*eda14cbcSMatt Macy return (TX_MKXATTR); 94*eda14cbcSMatt Macy } 95*eda14cbcSMatt Macy ASSERT(0); 96*eda14cbcSMatt Macy return (TX_MAX_TYPE); 97*eda14cbcSMatt Macy } 98*eda14cbcSMatt Macy 99*eda14cbcSMatt Macy /* 100*eda14cbcSMatt Macy * build up the log data necessary for logging xvattr_t 101*eda14cbcSMatt Macy * First lr_attr_t is initialized. following the lr_attr_t 102*eda14cbcSMatt Macy * is the mapsize and attribute bitmap copied from the xvattr_t. 103*eda14cbcSMatt Macy * Following the bitmap and bitmapsize two 64 bit words are reserved 104*eda14cbcSMatt Macy * for the create time which may be set. Following the create time 105*eda14cbcSMatt Macy * records a single 64 bit integer which has the bits to set on 106*eda14cbcSMatt Macy * replay for the xvattr. 107*eda14cbcSMatt Macy */ 108*eda14cbcSMatt Macy static void 109*eda14cbcSMatt Macy zfs_log_xvattr(lr_attr_t *lrattr, xvattr_t *xvap) 110*eda14cbcSMatt Macy { 111*eda14cbcSMatt Macy uint32_t *bitmap; 112*eda14cbcSMatt Macy uint64_t *attrs; 113*eda14cbcSMatt Macy uint64_t *crtime; 114*eda14cbcSMatt Macy xoptattr_t *xoap; 115*eda14cbcSMatt Macy void *scanstamp; 116*eda14cbcSMatt Macy int i; 117*eda14cbcSMatt Macy 118*eda14cbcSMatt Macy xoap = xva_getxoptattr(xvap); 119*eda14cbcSMatt Macy ASSERT(xoap); 120*eda14cbcSMatt Macy 121*eda14cbcSMatt Macy lrattr->lr_attr_masksize = xvap->xva_mapsize; 122*eda14cbcSMatt Macy bitmap = &lrattr->lr_attr_bitmap; 123*eda14cbcSMatt Macy for (i = 0; i != xvap->xva_mapsize; i++, bitmap++) { 124*eda14cbcSMatt Macy *bitmap = xvap->xva_reqattrmap[i]; 125*eda14cbcSMatt Macy } 126*eda14cbcSMatt Macy 127*eda14cbcSMatt Macy /* Now pack the attributes up in a single uint64_t */ 128*eda14cbcSMatt Macy attrs = (uint64_t *)bitmap; 129*eda14cbcSMatt Macy crtime = attrs + 1; 130*eda14cbcSMatt Macy scanstamp = (caddr_t)(crtime + 2); 131*eda14cbcSMatt Macy *attrs = 0; 132*eda14cbcSMatt Macy if (XVA_ISSET_REQ(xvap, XAT_READONLY)) 133*eda14cbcSMatt Macy *attrs |= (xoap->xoa_readonly == 0) ? 0 : 134*eda14cbcSMatt Macy XAT0_READONLY; 135*eda14cbcSMatt Macy if (XVA_ISSET_REQ(xvap, XAT_HIDDEN)) 136*eda14cbcSMatt Macy *attrs |= (xoap->xoa_hidden == 0) ? 0 : 137*eda14cbcSMatt Macy XAT0_HIDDEN; 138*eda14cbcSMatt Macy if (XVA_ISSET_REQ(xvap, XAT_SYSTEM)) 139*eda14cbcSMatt Macy *attrs |= (xoap->xoa_system == 0) ? 0 : 140*eda14cbcSMatt Macy XAT0_SYSTEM; 141*eda14cbcSMatt Macy if (XVA_ISSET_REQ(xvap, XAT_ARCHIVE)) 142*eda14cbcSMatt Macy *attrs |= (xoap->xoa_archive == 0) ? 0 : 143*eda14cbcSMatt Macy XAT0_ARCHIVE; 144*eda14cbcSMatt Macy if (XVA_ISSET_REQ(xvap, XAT_IMMUTABLE)) 145*eda14cbcSMatt Macy *attrs |= (xoap->xoa_immutable == 0) ? 0 : 146*eda14cbcSMatt Macy XAT0_IMMUTABLE; 147*eda14cbcSMatt Macy if (XVA_ISSET_REQ(xvap, XAT_NOUNLINK)) 148*eda14cbcSMatt Macy *attrs |= (xoap->xoa_nounlink == 0) ? 0 : 149*eda14cbcSMatt Macy XAT0_NOUNLINK; 150*eda14cbcSMatt Macy if (XVA_ISSET_REQ(xvap, XAT_APPENDONLY)) 151*eda14cbcSMatt Macy *attrs |= (xoap->xoa_appendonly == 0) ? 0 : 152*eda14cbcSMatt Macy XAT0_APPENDONLY; 153*eda14cbcSMatt Macy if (XVA_ISSET_REQ(xvap, XAT_OPAQUE)) 154*eda14cbcSMatt Macy *attrs |= (xoap->xoa_opaque == 0) ? 0 : 155*eda14cbcSMatt Macy XAT0_APPENDONLY; 156*eda14cbcSMatt Macy if (XVA_ISSET_REQ(xvap, XAT_NODUMP)) 157*eda14cbcSMatt Macy *attrs |= (xoap->xoa_nodump == 0) ? 0 : 158*eda14cbcSMatt Macy XAT0_NODUMP; 159*eda14cbcSMatt Macy if (XVA_ISSET_REQ(xvap, XAT_AV_QUARANTINED)) 160*eda14cbcSMatt Macy *attrs |= (xoap->xoa_av_quarantined == 0) ? 0 : 161*eda14cbcSMatt Macy XAT0_AV_QUARANTINED; 162*eda14cbcSMatt Macy if (XVA_ISSET_REQ(xvap, XAT_AV_MODIFIED)) 163*eda14cbcSMatt Macy *attrs |= (xoap->xoa_av_modified == 0) ? 0 : 164*eda14cbcSMatt Macy XAT0_AV_MODIFIED; 165*eda14cbcSMatt Macy if (XVA_ISSET_REQ(xvap, XAT_CREATETIME)) 166*eda14cbcSMatt Macy ZFS_TIME_ENCODE(&xoap->xoa_createtime, crtime); 167*eda14cbcSMatt Macy if (XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP)) { 168*eda14cbcSMatt Macy ASSERT(!XVA_ISSET_REQ(xvap, XAT_PROJID)); 169*eda14cbcSMatt Macy 170*eda14cbcSMatt Macy bcopy(xoap->xoa_av_scanstamp, scanstamp, AV_SCANSTAMP_SZ); 171*eda14cbcSMatt Macy } else if (XVA_ISSET_REQ(xvap, XAT_PROJID)) { 172*eda14cbcSMatt Macy /* 173*eda14cbcSMatt Macy * XAT_PROJID and XAT_AV_SCANSTAMP will never be valid 174*eda14cbcSMatt Macy * at the same time, so we can share the same space. 175*eda14cbcSMatt Macy */ 176*eda14cbcSMatt Macy bcopy(&xoap->xoa_projid, scanstamp, sizeof (uint64_t)); 177*eda14cbcSMatt Macy } 178*eda14cbcSMatt Macy if (XVA_ISSET_REQ(xvap, XAT_REPARSE)) 179*eda14cbcSMatt Macy *attrs |= (xoap->xoa_reparse == 0) ? 0 : 180*eda14cbcSMatt Macy XAT0_REPARSE; 181*eda14cbcSMatt Macy if (XVA_ISSET_REQ(xvap, XAT_OFFLINE)) 182*eda14cbcSMatt Macy *attrs |= (xoap->xoa_offline == 0) ? 0 : 183*eda14cbcSMatt Macy XAT0_OFFLINE; 184*eda14cbcSMatt Macy if (XVA_ISSET_REQ(xvap, XAT_SPARSE)) 185*eda14cbcSMatt Macy *attrs |= (xoap->xoa_sparse == 0) ? 0 : 186*eda14cbcSMatt Macy XAT0_SPARSE; 187*eda14cbcSMatt Macy if (XVA_ISSET_REQ(xvap, XAT_PROJINHERIT)) 188*eda14cbcSMatt Macy *attrs |= (xoap->xoa_projinherit == 0) ? 0 : 189*eda14cbcSMatt Macy XAT0_PROJINHERIT; 190*eda14cbcSMatt Macy } 191*eda14cbcSMatt Macy 192*eda14cbcSMatt Macy static void * 193*eda14cbcSMatt Macy zfs_log_fuid_ids(zfs_fuid_info_t *fuidp, void *start) 194*eda14cbcSMatt Macy { 195*eda14cbcSMatt Macy zfs_fuid_t *zfuid; 196*eda14cbcSMatt Macy uint64_t *fuidloc = start; 197*eda14cbcSMatt Macy 198*eda14cbcSMatt Macy /* First copy in the ACE FUIDs */ 199*eda14cbcSMatt Macy for (zfuid = list_head(&fuidp->z_fuids); zfuid; 200*eda14cbcSMatt Macy zfuid = list_next(&fuidp->z_fuids, zfuid)) { 201*eda14cbcSMatt Macy *fuidloc++ = zfuid->z_logfuid; 202*eda14cbcSMatt Macy } 203*eda14cbcSMatt Macy return (fuidloc); 204*eda14cbcSMatt Macy } 205*eda14cbcSMatt Macy 206*eda14cbcSMatt Macy 207*eda14cbcSMatt Macy static void * 208*eda14cbcSMatt Macy zfs_log_fuid_domains(zfs_fuid_info_t *fuidp, void *start) 209*eda14cbcSMatt Macy { 210*eda14cbcSMatt Macy zfs_fuid_domain_t *zdomain; 211*eda14cbcSMatt Macy 212*eda14cbcSMatt Macy /* now copy in the domain info, if any */ 213*eda14cbcSMatt Macy if (fuidp->z_domain_str_sz != 0) { 214*eda14cbcSMatt Macy for (zdomain = list_head(&fuidp->z_domains); zdomain; 215*eda14cbcSMatt Macy zdomain = list_next(&fuidp->z_domains, zdomain)) { 216*eda14cbcSMatt Macy bcopy((void *)zdomain->z_domain, start, 217*eda14cbcSMatt Macy strlen(zdomain->z_domain) + 1); 218*eda14cbcSMatt Macy start = (caddr_t)start + 219*eda14cbcSMatt Macy strlen(zdomain->z_domain) + 1; 220*eda14cbcSMatt Macy } 221*eda14cbcSMatt Macy } 222*eda14cbcSMatt Macy return (start); 223*eda14cbcSMatt Macy } 224*eda14cbcSMatt Macy 225*eda14cbcSMatt Macy /* 226*eda14cbcSMatt Macy * If zp is an xattr node, check whether the xattr owner is unlinked. 227*eda14cbcSMatt Macy * We don't want to log anything if the owner is unlinked. 228*eda14cbcSMatt Macy */ 229*eda14cbcSMatt Macy static int 230*eda14cbcSMatt Macy zfs_xattr_owner_unlinked(znode_t *zp) 231*eda14cbcSMatt Macy { 232*eda14cbcSMatt Macy int unlinked = 0; 233*eda14cbcSMatt Macy znode_t *dzp; 234*eda14cbcSMatt Macy #ifdef __FreeBSD__ 235*eda14cbcSMatt Macy znode_t *tzp = zp; 236*eda14cbcSMatt Macy 237*eda14cbcSMatt Macy /* 238*eda14cbcSMatt Macy * zrele drops the vnode lock which violates the VOP locking contract 239*eda14cbcSMatt Macy * on FreeBSD. See comment at the top of zfs_replay.c for more detail. 240*eda14cbcSMatt Macy */ 241*eda14cbcSMatt Macy /* 242*eda14cbcSMatt Macy * if zp is XATTR node, keep walking up via z_xattr_parent until we 243*eda14cbcSMatt Macy * get the owner 244*eda14cbcSMatt Macy */ 245*eda14cbcSMatt Macy while (tzp->z_pflags & ZFS_XATTR) { 246*eda14cbcSMatt Macy ASSERT3U(zp->z_xattr_parent, !=, 0); 247*eda14cbcSMatt Macy if (zfs_zget(ZTOZSB(tzp), tzp->z_xattr_parent, &dzp) != 0) { 248*eda14cbcSMatt Macy unlinked = 1; 249*eda14cbcSMatt Macy break; 250*eda14cbcSMatt Macy } 251*eda14cbcSMatt Macy 252*eda14cbcSMatt Macy if (tzp != zp) 253*eda14cbcSMatt Macy zrele(tzp); 254*eda14cbcSMatt Macy tzp = dzp; 255*eda14cbcSMatt Macy unlinked = tzp->z_unlinked; 256*eda14cbcSMatt Macy } 257*eda14cbcSMatt Macy if (tzp != zp) 258*eda14cbcSMatt Macy zrele(tzp); 259*eda14cbcSMatt Macy #else 260*eda14cbcSMatt Macy zhold(zp); 261*eda14cbcSMatt Macy /* 262*eda14cbcSMatt Macy * if zp is XATTR node, keep walking up via z_xattr_parent until we 263*eda14cbcSMatt Macy * get the owner 264*eda14cbcSMatt Macy */ 265*eda14cbcSMatt Macy while (zp->z_pflags & ZFS_XATTR) { 266*eda14cbcSMatt Macy ASSERT3U(zp->z_xattr_parent, !=, 0); 267*eda14cbcSMatt Macy if (zfs_zget(ZTOZSB(zp), zp->z_xattr_parent, &dzp) != 0) { 268*eda14cbcSMatt Macy unlinked = 1; 269*eda14cbcSMatt Macy break; 270*eda14cbcSMatt Macy } 271*eda14cbcSMatt Macy 272*eda14cbcSMatt Macy zrele(zp); 273*eda14cbcSMatt Macy zp = dzp; 274*eda14cbcSMatt Macy unlinked = zp->z_unlinked; 275*eda14cbcSMatt Macy } 276*eda14cbcSMatt Macy zrele(zp); 277*eda14cbcSMatt Macy #endif 278*eda14cbcSMatt Macy return (unlinked); 279*eda14cbcSMatt Macy } 280*eda14cbcSMatt Macy 281*eda14cbcSMatt Macy /* 282*eda14cbcSMatt Macy * Handles TX_CREATE, TX_CREATE_ATTR, TX_MKDIR, TX_MKDIR_ATTR and 283*eda14cbcSMatt Macy * TK_MKXATTR transactions. 284*eda14cbcSMatt Macy * 285*eda14cbcSMatt Macy * TX_CREATE and TX_MKDIR are standard creates, but they may have FUID 286*eda14cbcSMatt Macy * domain information appended prior to the name. In this case the 287*eda14cbcSMatt Macy * uid/gid in the log record will be a log centric FUID. 288*eda14cbcSMatt Macy * 289*eda14cbcSMatt Macy * TX_CREATE_ACL_ATTR and TX_MKDIR_ACL_ATTR handle special creates that 290*eda14cbcSMatt Macy * may contain attributes, ACL and optional fuid information. 291*eda14cbcSMatt Macy * 292*eda14cbcSMatt Macy * TX_CREATE_ACL and TX_MKDIR_ACL handle special creates that specify 293*eda14cbcSMatt Macy * and ACL and normal users/groups in the ACEs. 294*eda14cbcSMatt Macy * 295*eda14cbcSMatt Macy * There may be an optional xvattr attribute information similar 296*eda14cbcSMatt Macy * to zfs_log_setattr. 297*eda14cbcSMatt Macy * 298*eda14cbcSMatt Macy * Also, after the file name "domain" strings may be appended. 299*eda14cbcSMatt Macy */ 300*eda14cbcSMatt Macy void 301*eda14cbcSMatt Macy zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, 302*eda14cbcSMatt Macy znode_t *dzp, znode_t *zp, char *name, vsecattr_t *vsecp, 303*eda14cbcSMatt Macy zfs_fuid_info_t *fuidp, vattr_t *vap) 304*eda14cbcSMatt Macy { 305*eda14cbcSMatt Macy itx_t *itx; 306*eda14cbcSMatt Macy lr_create_t *lr; 307*eda14cbcSMatt Macy lr_acl_create_t *lracl; 308*eda14cbcSMatt Macy size_t aclsize = 0; 309*eda14cbcSMatt Macy size_t xvatsize = 0; 310*eda14cbcSMatt Macy size_t txsize; 311*eda14cbcSMatt Macy xvattr_t *xvap = (xvattr_t *)vap; 312*eda14cbcSMatt Macy void *end; 313*eda14cbcSMatt Macy size_t lrsize; 314*eda14cbcSMatt Macy size_t namesize = strlen(name) + 1; 315*eda14cbcSMatt Macy size_t fuidsz = 0; 316*eda14cbcSMatt Macy 317*eda14cbcSMatt Macy if (zil_replaying(zilog, tx) || zfs_xattr_owner_unlinked(dzp)) 318*eda14cbcSMatt Macy return; 319*eda14cbcSMatt Macy 320*eda14cbcSMatt Macy /* 321*eda14cbcSMatt Macy * If we have FUIDs present then add in space for 322*eda14cbcSMatt Macy * domains and ACE fuid's if any. 323*eda14cbcSMatt Macy */ 324*eda14cbcSMatt Macy if (fuidp) { 325*eda14cbcSMatt Macy fuidsz += fuidp->z_domain_str_sz; 326*eda14cbcSMatt Macy fuidsz += fuidp->z_fuid_cnt * sizeof (uint64_t); 327*eda14cbcSMatt Macy } 328*eda14cbcSMatt Macy 329*eda14cbcSMatt Macy if (vap->va_mask & ATTR_XVATTR) 330*eda14cbcSMatt Macy xvatsize = ZIL_XVAT_SIZE(xvap->xva_mapsize); 331*eda14cbcSMatt Macy 332*eda14cbcSMatt Macy if ((int)txtype == TX_CREATE_ATTR || (int)txtype == TX_MKDIR_ATTR || 333*eda14cbcSMatt Macy (int)txtype == TX_CREATE || (int)txtype == TX_MKDIR || 334*eda14cbcSMatt Macy (int)txtype == TX_MKXATTR) { 335*eda14cbcSMatt Macy txsize = sizeof (*lr) + namesize + fuidsz + xvatsize; 336*eda14cbcSMatt Macy lrsize = sizeof (*lr); 337*eda14cbcSMatt Macy } else { 338*eda14cbcSMatt Macy txsize = 339*eda14cbcSMatt Macy sizeof (lr_acl_create_t) + namesize + fuidsz + 340*eda14cbcSMatt Macy ZIL_ACE_LENGTH(aclsize) + xvatsize; 341*eda14cbcSMatt Macy lrsize = sizeof (lr_acl_create_t); 342*eda14cbcSMatt Macy } 343*eda14cbcSMatt Macy 344*eda14cbcSMatt Macy itx = zil_itx_create(txtype, txsize); 345*eda14cbcSMatt Macy 346*eda14cbcSMatt Macy lr = (lr_create_t *)&itx->itx_lr; 347*eda14cbcSMatt Macy lr->lr_doid = dzp->z_id; 348*eda14cbcSMatt Macy lr->lr_foid = zp->z_id; 349*eda14cbcSMatt Macy /* Store dnode slot count in 8 bits above object id. */ 350*eda14cbcSMatt Macy LR_FOID_SET_SLOTS(lr->lr_foid, zp->z_dnodesize >> DNODE_SHIFT); 351*eda14cbcSMatt Macy lr->lr_mode = zp->z_mode; 352*eda14cbcSMatt Macy if (!IS_EPHEMERAL(KUID_TO_SUID(ZTOUID(zp)))) { 353*eda14cbcSMatt Macy lr->lr_uid = (uint64_t)KUID_TO_SUID(ZTOUID(zp)); 354*eda14cbcSMatt Macy } else { 355*eda14cbcSMatt Macy lr->lr_uid = fuidp->z_fuid_owner; 356*eda14cbcSMatt Macy } 357*eda14cbcSMatt Macy if (!IS_EPHEMERAL(KGID_TO_SGID(ZTOGID(zp)))) { 358*eda14cbcSMatt Macy lr->lr_gid = (uint64_t)KGID_TO_SGID(ZTOGID(zp)); 359*eda14cbcSMatt Macy } else { 360*eda14cbcSMatt Macy lr->lr_gid = fuidp->z_fuid_group; 361*eda14cbcSMatt Macy } 362*eda14cbcSMatt Macy (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(ZTOZSB(zp)), &lr->lr_gen, 363*eda14cbcSMatt Macy sizeof (uint64_t)); 364*eda14cbcSMatt Macy (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(ZTOZSB(zp)), 365*eda14cbcSMatt Macy lr->lr_crtime, sizeof (uint64_t) * 2); 366*eda14cbcSMatt Macy 367*eda14cbcSMatt Macy if (sa_lookup(zp->z_sa_hdl, SA_ZPL_RDEV(ZTOZSB(zp)), &lr->lr_rdev, 368*eda14cbcSMatt Macy sizeof (lr->lr_rdev)) != 0) 369*eda14cbcSMatt Macy lr->lr_rdev = 0; 370*eda14cbcSMatt Macy 371*eda14cbcSMatt Macy /* 372*eda14cbcSMatt Macy * Fill in xvattr info if any 373*eda14cbcSMatt Macy */ 374*eda14cbcSMatt Macy if (vap->va_mask & ATTR_XVATTR) { 375*eda14cbcSMatt Macy zfs_log_xvattr((lr_attr_t *)((caddr_t)lr + lrsize), xvap); 376*eda14cbcSMatt Macy end = (caddr_t)lr + lrsize + xvatsize; 377*eda14cbcSMatt Macy } else { 378*eda14cbcSMatt Macy end = (caddr_t)lr + lrsize; 379*eda14cbcSMatt Macy } 380*eda14cbcSMatt Macy 381*eda14cbcSMatt Macy /* Now fill in any ACL info */ 382*eda14cbcSMatt Macy 383*eda14cbcSMatt Macy if (vsecp) { 384*eda14cbcSMatt Macy lracl = (lr_acl_create_t *)&itx->itx_lr; 385*eda14cbcSMatt Macy lracl->lr_aclcnt = vsecp->vsa_aclcnt; 386*eda14cbcSMatt Macy lracl->lr_acl_bytes = aclsize; 387*eda14cbcSMatt Macy lracl->lr_domcnt = fuidp ? fuidp->z_domain_cnt : 0; 388*eda14cbcSMatt Macy lracl->lr_fuidcnt = fuidp ? fuidp->z_fuid_cnt : 0; 389*eda14cbcSMatt Macy if (vsecp->vsa_aclflags & VSA_ACE_ACLFLAGS) 390*eda14cbcSMatt Macy lracl->lr_acl_flags = (uint64_t)vsecp->vsa_aclflags; 391*eda14cbcSMatt Macy else 392*eda14cbcSMatt Macy lracl->lr_acl_flags = 0; 393*eda14cbcSMatt Macy 394*eda14cbcSMatt Macy bcopy(vsecp->vsa_aclentp, end, aclsize); 395*eda14cbcSMatt Macy end = (caddr_t)end + ZIL_ACE_LENGTH(aclsize); 396*eda14cbcSMatt Macy } 397*eda14cbcSMatt Macy 398*eda14cbcSMatt Macy /* drop in FUID info */ 399*eda14cbcSMatt Macy if (fuidp) { 400*eda14cbcSMatt Macy end = zfs_log_fuid_ids(fuidp, end); 401*eda14cbcSMatt Macy end = zfs_log_fuid_domains(fuidp, end); 402*eda14cbcSMatt Macy } 403*eda14cbcSMatt Macy /* 404*eda14cbcSMatt Macy * Now place file name in log record 405*eda14cbcSMatt Macy */ 406*eda14cbcSMatt Macy bcopy(name, end, namesize); 407*eda14cbcSMatt Macy 408*eda14cbcSMatt Macy zil_itx_assign(zilog, itx, tx); 409*eda14cbcSMatt Macy } 410*eda14cbcSMatt Macy 411*eda14cbcSMatt Macy /* 412*eda14cbcSMatt Macy * Handles both TX_REMOVE and TX_RMDIR transactions. 413*eda14cbcSMatt Macy */ 414*eda14cbcSMatt Macy void 415*eda14cbcSMatt Macy zfs_log_remove(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, 416*eda14cbcSMatt Macy znode_t *dzp, char *name, uint64_t foid, boolean_t unlinked) 417*eda14cbcSMatt Macy { 418*eda14cbcSMatt Macy itx_t *itx; 419*eda14cbcSMatt Macy lr_remove_t *lr; 420*eda14cbcSMatt Macy size_t namesize = strlen(name) + 1; 421*eda14cbcSMatt Macy 422*eda14cbcSMatt Macy if (zil_replaying(zilog, tx) || zfs_xattr_owner_unlinked(dzp)) 423*eda14cbcSMatt Macy return; 424*eda14cbcSMatt Macy 425*eda14cbcSMatt Macy itx = zil_itx_create(txtype, sizeof (*lr) + namesize); 426*eda14cbcSMatt Macy lr = (lr_remove_t *)&itx->itx_lr; 427*eda14cbcSMatt Macy lr->lr_doid = dzp->z_id; 428*eda14cbcSMatt Macy bcopy(name, (char *)(lr + 1), namesize); 429*eda14cbcSMatt Macy 430*eda14cbcSMatt Macy itx->itx_oid = foid; 431*eda14cbcSMatt Macy 432*eda14cbcSMatt Macy /* 433*eda14cbcSMatt Macy * Object ids can be re-instantiated in the next txg so 434*eda14cbcSMatt Macy * remove any async transactions to avoid future leaks. 435*eda14cbcSMatt Macy * This can happen if a fsync occurs on the re-instantiated 436*eda14cbcSMatt Macy * object for a WR_INDIRECT or WR_NEED_COPY write, which gets 437*eda14cbcSMatt Macy * the new file data and flushes a write record for the old object. 438*eda14cbcSMatt Macy */ 439*eda14cbcSMatt Macy if (unlinked) { 440*eda14cbcSMatt Macy ASSERT((txtype & ~TX_CI) == TX_REMOVE); 441*eda14cbcSMatt Macy zil_remove_async(zilog, foid); 442*eda14cbcSMatt Macy } 443*eda14cbcSMatt Macy zil_itx_assign(zilog, itx, tx); 444*eda14cbcSMatt Macy } 445*eda14cbcSMatt Macy 446*eda14cbcSMatt Macy /* 447*eda14cbcSMatt Macy * Handles TX_LINK transactions. 448*eda14cbcSMatt Macy */ 449*eda14cbcSMatt Macy void 450*eda14cbcSMatt Macy zfs_log_link(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, 451*eda14cbcSMatt Macy znode_t *dzp, znode_t *zp, char *name) 452*eda14cbcSMatt Macy { 453*eda14cbcSMatt Macy itx_t *itx; 454*eda14cbcSMatt Macy lr_link_t *lr; 455*eda14cbcSMatt Macy size_t namesize = strlen(name) + 1; 456*eda14cbcSMatt Macy 457*eda14cbcSMatt Macy if (zil_replaying(zilog, tx)) 458*eda14cbcSMatt Macy return; 459*eda14cbcSMatt Macy 460*eda14cbcSMatt Macy itx = zil_itx_create(txtype, sizeof (*lr) + namesize); 461*eda14cbcSMatt Macy lr = (lr_link_t *)&itx->itx_lr; 462*eda14cbcSMatt Macy lr->lr_doid = dzp->z_id; 463*eda14cbcSMatt Macy lr->lr_link_obj = zp->z_id; 464*eda14cbcSMatt Macy bcopy(name, (char *)(lr + 1), namesize); 465*eda14cbcSMatt Macy 466*eda14cbcSMatt Macy zil_itx_assign(zilog, itx, tx); 467*eda14cbcSMatt Macy } 468*eda14cbcSMatt Macy 469*eda14cbcSMatt Macy /* 470*eda14cbcSMatt Macy * Handles TX_SYMLINK transactions. 471*eda14cbcSMatt Macy */ 472*eda14cbcSMatt Macy void 473*eda14cbcSMatt Macy zfs_log_symlink(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, 474*eda14cbcSMatt Macy znode_t *dzp, znode_t *zp, char *name, char *link) 475*eda14cbcSMatt Macy { 476*eda14cbcSMatt Macy itx_t *itx; 477*eda14cbcSMatt Macy lr_create_t *lr; 478*eda14cbcSMatt Macy size_t namesize = strlen(name) + 1; 479*eda14cbcSMatt Macy size_t linksize = strlen(link) + 1; 480*eda14cbcSMatt Macy 481*eda14cbcSMatt Macy if (zil_replaying(zilog, tx)) 482*eda14cbcSMatt Macy return; 483*eda14cbcSMatt Macy 484*eda14cbcSMatt Macy itx = zil_itx_create(txtype, sizeof (*lr) + namesize + linksize); 485*eda14cbcSMatt Macy lr = (lr_create_t *)&itx->itx_lr; 486*eda14cbcSMatt Macy lr->lr_doid = dzp->z_id; 487*eda14cbcSMatt Macy lr->lr_foid = zp->z_id; 488*eda14cbcSMatt Macy lr->lr_uid = KUID_TO_SUID(ZTOUID(zp)); 489*eda14cbcSMatt Macy lr->lr_gid = KGID_TO_SGID(ZTOGID(zp)); 490*eda14cbcSMatt Macy lr->lr_mode = zp->z_mode; 491*eda14cbcSMatt Macy (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(ZTOZSB(zp)), &lr->lr_gen, 492*eda14cbcSMatt Macy sizeof (uint64_t)); 493*eda14cbcSMatt Macy (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(ZTOZSB(zp)), 494*eda14cbcSMatt Macy lr->lr_crtime, sizeof (uint64_t) * 2); 495*eda14cbcSMatt Macy bcopy(name, (char *)(lr + 1), namesize); 496*eda14cbcSMatt Macy bcopy(link, (char *)(lr + 1) + namesize, linksize); 497*eda14cbcSMatt Macy 498*eda14cbcSMatt Macy zil_itx_assign(zilog, itx, tx); 499*eda14cbcSMatt Macy } 500*eda14cbcSMatt Macy 501*eda14cbcSMatt Macy /* 502*eda14cbcSMatt Macy * Handles TX_RENAME transactions. 503*eda14cbcSMatt Macy */ 504*eda14cbcSMatt Macy void 505*eda14cbcSMatt Macy zfs_log_rename(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, 506*eda14cbcSMatt Macy znode_t *sdzp, char *sname, znode_t *tdzp, char *dname, znode_t *szp) 507*eda14cbcSMatt Macy { 508*eda14cbcSMatt Macy itx_t *itx; 509*eda14cbcSMatt Macy lr_rename_t *lr; 510*eda14cbcSMatt Macy size_t snamesize = strlen(sname) + 1; 511*eda14cbcSMatt Macy size_t dnamesize = strlen(dname) + 1; 512*eda14cbcSMatt Macy 513*eda14cbcSMatt Macy if (zil_replaying(zilog, tx)) 514*eda14cbcSMatt Macy return; 515*eda14cbcSMatt Macy 516*eda14cbcSMatt Macy itx = zil_itx_create(txtype, sizeof (*lr) + snamesize + dnamesize); 517*eda14cbcSMatt Macy lr = (lr_rename_t *)&itx->itx_lr; 518*eda14cbcSMatt Macy lr->lr_sdoid = sdzp->z_id; 519*eda14cbcSMatt Macy lr->lr_tdoid = tdzp->z_id; 520*eda14cbcSMatt Macy bcopy(sname, (char *)(lr + 1), snamesize); 521*eda14cbcSMatt Macy bcopy(dname, (char *)(lr + 1) + snamesize, dnamesize); 522*eda14cbcSMatt Macy itx->itx_oid = szp->z_id; 523*eda14cbcSMatt Macy 524*eda14cbcSMatt Macy zil_itx_assign(zilog, itx, tx); 525*eda14cbcSMatt Macy } 526*eda14cbcSMatt Macy 527*eda14cbcSMatt Macy /* 528*eda14cbcSMatt Macy * zfs_log_write() handles TX_WRITE transactions. The specified callback is 529*eda14cbcSMatt Macy * called as soon as the write is on stable storage (be it via a DMU sync or a 530*eda14cbcSMatt Macy * ZIL commit). 531*eda14cbcSMatt Macy */ 532*eda14cbcSMatt Macy long zfs_immediate_write_sz = 32768; 533*eda14cbcSMatt Macy 534*eda14cbcSMatt Macy void 535*eda14cbcSMatt Macy zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype, 536*eda14cbcSMatt Macy znode_t *zp, offset_t off, ssize_t resid, int ioflag, 537*eda14cbcSMatt Macy zil_callback_t callback, void *callback_data) 538*eda14cbcSMatt Macy { 539*eda14cbcSMatt Macy dmu_buf_impl_t *db = (dmu_buf_impl_t *)sa_get_db(zp->z_sa_hdl); 540*eda14cbcSMatt Macy uint32_t blocksize = zp->z_blksz; 541*eda14cbcSMatt Macy itx_wr_state_t write_state; 542*eda14cbcSMatt Macy uintptr_t fsync_cnt; 543*eda14cbcSMatt Macy 544*eda14cbcSMatt Macy if (zil_replaying(zilog, tx) || zp->z_unlinked || 545*eda14cbcSMatt Macy zfs_xattr_owner_unlinked(zp)) { 546*eda14cbcSMatt Macy if (callback != NULL) 547*eda14cbcSMatt Macy callback(callback_data); 548*eda14cbcSMatt Macy return; 549*eda14cbcSMatt Macy } 550*eda14cbcSMatt Macy 551*eda14cbcSMatt Macy if (zilog->zl_logbias == ZFS_LOGBIAS_THROUGHPUT) 552*eda14cbcSMatt Macy write_state = WR_INDIRECT; 553*eda14cbcSMatt Macy else if (!spa_has_slogs(zilog->zl_spa) && 554*eda14cbcSMatt Macy resid >= zfs_immediate_write_sz) 555*eda14cbcSMatt Macy write_state = WR_INDIRECT; 556*eda14cbcSMatt Macy else if (ioflag & (O_SYNC | O_DSYNC)) 557*eda14cbcSMatt Macy write_state = WR_COPIED; 558*eda14cbcSMatt Macy else 559*eda14cbcSMatt Macy write_state = WR_NEED_COPY; 560*eda14cbcSMatt Macy 561*eda14cbcSMatt Macy if ((fsync_cnt = (uintptr_t)tsd_get(zfs_fsyncer_key)) != 0) { 562*eda14cbcSMatt Macy (void) tsd_set(zfs_fsyncer_key, (void *)(fsync_cnt - 1)); 563*eda14cbcSMatt Macy } 564*eda14cbcSMatt Macy 565*eda14cbcSMatt Macy while (resid) { 566*eda14cbcSMatt Macy itx_t *itx; 567*eda14cbcSMatt Macy lr_write_t *lr; 568*eda14cbcSMatt Macy itx_wr_state_t wr_state = write_state; 569*eda14cbcSMatt Macy ssize_t len = resid; 570*eda14cbcSMatt Macy 571*eda14cbcSMatt Macy /* 572*eda14cbcSMatt Macy * A WR_COPIED record must fit entirely in one log block. 573*eda14cbcSMatt Macy * Large writes can use WR_NEED_COPY, which the ZIL will 574*eda14cbcSMatt Macy * split into multiple records across several log blocks 575*eda14cbcSMatt Macy * if necessary. 576*eda14cbcSMatt Macy */ 577*eda14cbcSMatt Macy if (wr_state == WR_COPIED && 578*eda14cbcSMatt Macy resid > zil_max_copied_data(zilog)) 579*eda14cbcSMatt Macy wr_state = WR_NEED_COPY; 580*eda14cbcSMatt Macy else if (wr_state == WR_INDIRECT) 581*eda14cbcSMatt Macy len = MIN(blocksize - P2PHASE(off, blocksize), resid); 582*eda14cbcSMatt Macy 583*eda14cbcSMatt Macy itx = zil_itx_create(txtype, sizeof (*lr) + 584*eda14cbcSMatt Macy (wr_state == WR_COPIED ? len : 0)); 585*eda14cbcSMatt Macy lr = (lr_write_t *)&itx->itx_lr; 586*eda14cbcSMatt Macy 587*eda14cbcSMatt Macy DB_DNODE_ENTER(db); 588*eda14cbcSMatt Macy if (wr_state == WR_COPIED && dmu_read_by_dnode(DB_DNODE(db), 589*eda14cbcSMatt Macy off, len, lr + 1, DMU_READ_NO_PREFETCH) != 0) { 590*eda14cbcSMatt Macy zil_itx_destroy(itx); 591*eda14cbcSMatt Macy itx = zil_itx_create(txtype, sizeof (*lr)); 592*eda14cbcSMatt Macy lr = (lr_write_t *)&itx->itx_lr; 593*eda14cbcSMatt Macy wr_state = WR_NEED_COPY; 594*eda14cbcSMatt Macy } 595*eda14cbcSMatt Macy DB_DNODE_EXIT(db); 596*eda14cbcSMatt Macy 597*eda14cbcSMatt Macy itx->itx_wr_state = wr_state; 598*eda14cbcSMatt Macy lr->lr_foid = zp->z_id; 599*eda14cbcSMatt Macy lr->lr_offset = off; 600*eda14cbcSMatt Macy lr->lr_length = len; 601*eda14cbcSMatt Macy lr->lr_blkoff = 0; 602*eda14cbcSMatt Macy BP_ZERO(&lr->lr_blkptr); 603*eda14cbcSMatt Macy 604*eda14cbcSMatt Macy itx->itx_private = ZTOZSB(zp); 605*eda14cbcSMatt Macy 606*eda14cbcSMatt Macy if (!(ioflag & (O_SYNC | O_DSYNC)) && (zp->z_sync_cnt == 0) && 607*eda14cbcSMatt Macy (fsync_cnt == 0)) 608*eda14cbcSMatt Macy itx->itx_sync = B_FALSE; 609*eda14cbcSMatt Macy 610*eda14cbcSMatt Macy itx->itx_callback = callback; 611*eda14cbcSMatt Macy itx->itx_callback_data = callback_data; 612*eda14cbcSMatt Macy zil_itx_assign(zilog, itx, tx); 613*eda14cbcSMatt Macy 614*eda14cbcSMatt Macy off += len; 615*eda14cbcSMatt Macy resid -= len; 616*eda14cbcSMatt Macy } 617*eda14cbcSMatt Macy } 618*eda14cbcSMatt Macy 619*eda14cbcSMatt Macy /* 620*eda14cbcSMatt Macy * Handles TX_TRUNCATE transactions. 621*eda14cbcSMatt Macy */ 622*eda14cbcSMatt Macy void 623*eda14cbcSMatt Macy zfs_log_truncate(zilog_t *zilog, dmu_tx_t *tx, int txtype, 624*eda14cbcSMatt Macy znode_t *zp, uint64_t off, uint64_t len) 625*eda14cbcSMatt Macy { 626*eda14cbcSMatt Macy itx_t *itx; 627*eda14cbcSMatt Macy lr_truncate_t *lr; 628*eda14cbcSMatt Macy 629*eda14cbcSMatt Macy if (zil_replaying(zilog, tx) || zp->z_unlinked || 630*eda14cbcSMatt Macy zfs_xattr_owner_unlinked(zp)) 631*eda14cbcSMatt Macy return; 632*eda14cbcSMatt Macy 633*eda14cbcSMatt Macy itx = zil_itx_create(txtype, sizeof (*lr)); 634*eda14cbcSMatt Macy lr = (lr_truncate_t *)&itx->itx_lr; 635*eda14cbcSMatt Macy lr->lr_foid = zp->z_id; 636*eda14cbcSMatt Macy lr->lr_offset = off; 637*eda14cbcSMatt Macy lr->lr_length = len; 638*eda14cbcSMatt Macy 639*eda14cbcSMatt Macy itx->itx_sync = (zp->z_sync_cnt != 0); 640*eda14cbcSMatt Macy zil_itx_assign(zilog, itx, tx); 641*eda14cbcSMatt Macy } 642*eda14cbcSMatt Macy 643*eda14cbcSMatt Macy /* 644*eda14cbcSMatt Macy * Handles TX_SETATTR transactions. 645*eda14cbcSMatt Macy */ 646*eda14cbcSMatt Macy void 647*eda14cbcSMatt Macy zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype, 648*eda14cbcSMatt Macy znode_t *zp, vattr_t *vap, uint_t mask_applied, zfs_fuid_info_t *fuidp) 649*eda14cbcSMatt Macy { 650*eda14cbcSMatt Macy itx_t *itx; 651*eda14cbcSMatt Macy lr_setattr_t *lr; 652*eda14cbcSMatt Macy xvattr_t *xvap = (xvattr_t *)vap; 653*eda14cbcSMatt Macy size_t recsize = sizeof (lr_setattr_t); 654*eda14cbcSMatt Macy void *start; 655*eda14cbcSMatt Macy 656*eda14cbcSMatt Macy if (zil_replaying(zilog, tx) || zp->z_unlinked) 657*eda14cbcSMatt Macy return; 658*eda14cbcSMatt Macy 659*eda14cbcSMatt Macy /* 660*eda14cbcSMatt Macy * If XVATTR set, then log record size needs to allow 661*eda14cbcSMatt Macy * for lr_attr_t + xvattr mask, mapsize and create time 662*eda14cbcSMatt Macy * plus actual attribute values 663*eda14cbcSMatt Macy */ 664*eda14cbcSMatt Macy if (vap->va_mask & ATTR_XVATTR) 665*eda14cbcSMatt Macy recsize = sizeof (*lr) + ZIL_XVAT_SIZE(xvap->xva_mapsize); 666*eda14cbcSMatt Macy 667*eda14cbcSMatt Macy if (fuidp) 668*eda14cbcSMatt Macy recsize += fuidp->z_domain_str_sz; 669*eda14cbcSMatt Macy 670*eda14cbcSMatt Macy itx = zil_itx_create(txtype, recsize); 671*eda14cbcSMatt Macy lr = (lr_setattr_t *)&itx->itx_lr; 672*eda14cbcSMatt Macy lr->lr_foid = zp->z_id; 673*eda14cbcSMatt Macy lr->lr_mask = (uint64_t)mask_applied; 674*eda14cbcSMatt Macy lr->lr_mode = (uint64_t)vap->va_mode; 675*eda14cbcSMatt Macy if ((mask_applied & ATTR_UID) && IS_EPHEMERAL(vap->va_uid)) 676*eda14cbcSMatt Macy lr->lr_uid = fuidp->z_fuid_owner; 677*eda14cbcSMatt Macy else 678*eda14cbcSMatt Macy lr->lr_uid = (uint64_t)vap->va_uid; 679*eda14cbcSMatt Macy 680*eda14cbcSMatt Macy if ((mask_applied & ATTR_GID) && IS_EPHEMERAL(vap->va_gid)) 681*eda14cbcSMatt Macy lr->lr_gid = fuidp->z_fuid_group; 682*eda14cbcSMatt Macy else 683*eda14cbcSMatt Macy lr->lr_gid = (uint64_t)vap->va_gid; 684*eda14cbcSMatt Macy 685*eda14cbcSMatt Macy lr->lr_size = (uint64_t)vap->va_size; 686*eda14cbcSMatt Macy ZFS_TIME_ENCODE(&vap->va_atime, lr->lr_atime); 687*eda14cbcSMatt Macy ZFS_TIME_ENCODE(&vap->va_mtime, lr->lr_mtime); 688*eda14cbcSMatt Macy start = (lr_setattr_t *)(lr + 1); 689*eda14cbcSMatt Macy if (vap->va_mask & ATTR_XVATTR) { 690*eda14cbcSMatt Macy zfs_log_xvattr((lr_attr_t *)start, xvap); 691*eda14cbcSMatt Macy start = (caddr_t)start + ZIL_XVAT_SIZE(xvap->xva_mapsize); 692*eda14cbcSMatt Macy } 693*eda14cbcSMatt Macy 694*eda14cbcSMatt Macy /* 695*eda14cbcSMatt Macy * Now stick on domain information if any on end 696*eda14cbcSMatt Macy */ 697*eda14cbcSMatt Macy 698*eda14cbcSMatt Macy if (fuidp) 699*eda14cbcSMatt Macy (void) zfs_log_fuid_domains(fuidp, start); 700*eda14cbcSMatt Macy 701*eda14cbcSMatt Macy itx->itx_sync = (zp->z_sync_cnt != 0); 702*eda14cbcSMatt Macy zil_itx_assign(zilog, itx, tx); 703*eda14cbcSMatt Macy } 704*eda14cbcSMatt Macy 705*eda14cbcSMatt Macy /* 706*eda14cbcSMatt Macy * Handles TX_ACL transactions. 707*eda14cbcSMatt Macy */ 708*eda14cbcSMatt Macy void 709*eda14cbcSMatt Macy zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp, 710*eda14cbcSMatt Macy vsecattr_t *vsecp, zfs_fuid_info_t *fuidp) 711*eda14cbcSMatt Macy { 712*eda14cbcSMatt Macy itx_t *itx; 713*eda14cbcSMatt Macy lr_acl_v0_t *lrv0; 714*eda14cbcSMatt Macy lr_acl_t *lr; 715*eda14cbcSMatt Macy int txtype; 716*eda14cbcSMatt Macy int lrsize; 717*eda14cbcSMatt Macy size_t txsize; 718*eda14cbcSMatt Macy size_t aclbytes = vsecp->vsa_aclentsz; 719*eda14cbcSMatt Macy 720*eda14cbcSMatt Macy if (zil_replaying(zilog, tx) || zp->z_unlinked) 721*eda14cbcSMatt Macy return; 722*eda14cbcSMatt Macy 723*eda14cbcSMatt Macy txtype = (ZTOZSB(zp)->z_version < ZPL_VERSION_FUID) ? 724*eda14cbcSMatt Macy TX_ACL_V0 : TX_ACL; 725*eda14cbcSMatt Macy 726*eda14cbcSMatt Macy if (txtype == TX_ACL) 727*eda14cbcSMatt Macy lrsize = sizeof (*lr); 728*eda14cbcSMatt Macy else 729*eda14cbcSMatt Macy lrsize = sizeof (*lrv0); 730*eda14cbcSMatt Macy 731*eda14cbcSMatt Macy txsize = lrsize + 732*eda14cbcSMatt Macy ((txtype == TX_ACL) ? ZIL_ACE_LENGTH(aclbytes) : aclbytes) + 733*eda14cbcSMatt Macy (fuidp ? fuidp->z_domain_str_sz : 0) + 734*eda14cbcSMatt Macy sizeof (uint64_t) * (fuidp ? fuidp->z_fuid_cnt : 0); 735*eda14cbcSMatt Macy 736*eda14cbcSMatt Macy itx = zil_itx_create(txtype, txsize); 737*eda14cbcSMatt Macy 738*eda14cbcSMatt Macy lr = (lr_acl_t *)&itx->itx_lr; 739*eda14cbcSMatt Macy lr->lr_foid = zp->z_id; 740*eda14cbcSMatt Macy if (txtype == TX_ACL) { 741*eda14cbcSMatt Macy lr->lr_acl_bytes = aclbytes; 742*eda14cbcSMatt Macy lr->lr_domcnt = fuidp ? fuidp->z_domain_cnt : 0; 743*eda14cbcSMatt Macy lr->lr_fuidcnt = fuidp ? fuidp->z_fuid_cnt : 0; 744*eda14cbcSMatt Macy if (vsecp->vsa_mask & VSA_ACE_ACLFLAGS) 745*eda14cbcSMatt Macy lr->lr_acl_flags = (uint64_t)vsecp->vsa_aclflags; 746*eda14cbcSMatt Macy else 747*eda14cbcSMatt Macy lr->lr_acl_flags = 0; 748*eda14cbcSMatt Macy } 749*eda14cbcSMatt Macy lr->lr_aclcnt = (uint64_t)vsecp->vsa_aclcnt; 750*eda14cbcSMatt Macy 751*eda14cbcSMatt Macy if (txtype == TX_ACL_V0) { 752*eda14cbcSMatt Macy lrv0 = (lr_acl_v0_t *)lr; 753*eda14cbcSMatt Macy bcopy(vsecp->vsa_aclentp, (ace_t *)(lrv0 + 1), aclbytes); 754*eda14cbcSMatt Macy } else { 755*eda14cbcSMatt Macy void *start = (ace_t *)(lr + 1); 756*eda14cbcSMatt Macy 757*eda14cbcSMatt Macy bcopy(vsecp->vsa_aclentp, start, aclbytes); 758*eda14cbcSMatt Macy 759*eda14cbcSMatt Macy start = (caddr_t)start + ZIL_ACE_LENGTH(aclbytes); 760*eda14cbcSMatt Macy 761*eda14cbcSMatt Macy if (fuidp) { 762*eda14cbcSMatt Macy start = zfs_log_fuid_ids(fuidp, start); 763*eda14cbcSMatt Macy (void) zfs_log_fuid_domains(fuidp, start); 764*eda14cbcSMatt Macy } 765*eda14cbcSMatt Macy } 766*eda14cbcSMatt Macy 767*eda14cbcSMatt Macy itx->itx_sync = (zp->z_sync_cnt != 0); 768*eda14cbcSMatt Macy zil_itx_assign(zilog, itx, tx); 769*eda14cbcSMatt Macy } 770*eda14cbcSMatt Macy 771*eda14cbcSMatt Macy /* BEGIN CSTYLED */ 772*eda14cbcSMatt Macy ZFS_MODULE_PARAM(zfs, zfs_, immediate_write_sz, LONG, ZMOD_RW, 773*eda14cbcSMatt Macy "Largest data block to write to zil"); 774*eda14cbcSMatt Macy /* END CSTYLED */ 775