FreeBSD ZFS
The Zettabyte File System
|
00001 /* 00002 * CDDL HEADER START 00003 * 00004 * The contents of this file are subject to the terms of the 00005 * Common Development and Distribution License (the "License"). 00006 * You may not use this file except in compliance with the License. 00007 * 00008 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 00009 * or http://www.opensolaris.org/os/licensing. 00010 * See the License for the specific language governing permissions 00011 * and limitations under the License. 00012 * 00013 * When distributing Covered Code, include this CDDL HEADER in each 00014 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 00015 * If applicable, add the following below this CDDL HEADER, with the 00016 * fields enclosed by brackets "[]" replaced with your own identifying 00017 * information: Portions Copyright [yyyy] [name of copyright owner] 00018 * 00019 * CDDL HEADER END 00020 */ 00021 /* 00022 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 00023 */ 00024 00025 #include <sys/types.h> 00026 #include <sys/param.h> 00027 #include <sys/systm.h> 00028 #include <sys/sysmacros.h> 00029 #include <sys/cmn_err.h> 00030 #include <sys/kmem.h> 00031 #include <sys/file.h> 00032 #include <sys/vfs.h> 00033 #include <sys/zfs_znode.h> 00034 #include <sys/zfs_dir.h> 00035 #include <sys/zil.h> 00036 #include <sys/zil_impl.h> 00037 #include <sys/byteorder.h> 00038 #include <sys/policy.h> 00039 #include <sys/stat.h> 00040 #include <sys/acl.h> 00041 #include <sys/dmu.h> 00042 #include <sys/spa.h> 00043 #include <sys/zfs_fuid.h> 00044 #include <sys/dsl_dataset.h> 00045 00068 int 00069 zfs_log_create_txtype(zil_create_t type, vsecattr_t *vsecp, vattr_t *vap) 00070 { 00071 int isxvattr = (vap->va_mask & AT_XVATTR); 00072 switch (type) { 00073 case Z_FILE: 00074 if (vsecp == NULL && !isxvattr) 00075 return (TX_CREATE); 00076 if (vsecp && isxvattr) 00077 #ifdef TODO 00078 return (TX_CREATE_ACL_ATTR); 00079 #else 00080 panic("%s:%u: unsupported condition", __func__, __LINE__); 00081 #endif 00082 if (vsecp) 00083 return (TX_CREATE_ACL); 00084 else 00085 return (TX_CREATE_ATTR); 00086 /*NOTREACHED*/ 00087 case Z_DIR: 00088 if (vsecp == NULL && !isxvattr) 00089 return (TX_MKDIR); 00090 if (vsecp && isxvattr) 00091 #ifdef TODO 00092 return (TX_MKDIR_ACL_ATTR); 00093 #else 00094 panic("%s:%u: unsupported condition", __func__, __LINE__); 00095 #endif 00096 if (vsecp) 00097 return (TX_MKDIR_ACL); 00098 else 00099 return (TX_MKDIR_ATTR); 00100 case Z_XATTRDIR: 00101 return (TX_MKXATTR); 00102 } 00103 ASSERT(0); 00104 return (TX_MAX_TYPE); 00105 } 00106 00116 static void 00117 zfs_log_xvattr(lr_attr_t *lrattr, xvattr_t *xvap) 00118 { 00119 uint32_t *bitmap; 00120 uint64_t *attrs; 00121 uint64_t *crtime; 00122 xoptattr_t *xoap; 00123 void *scanstamp; 00124 int i; 00125 00126 xoap = xva_getxoptattr(xvap); 00127 ASSERT(xoap); 00128 00129 lrattr->lr_attr_masksize = xvap->xva_mapsize; 00130 bitmap = &lrattr->lr_attr_bitmap; 00131 for (i = 0; i != xvap->xva_mapsize; i++, bitmap++) { 00132 *bitmap = xvap->xva_reqattrmap[i]; 00133 } 00134 00135 /* Now pack the attributes up in a single uint64_t */ 00136 attrs = (uint64_t *)bitmap; 00137 crtime = attrs + 1; 00138 scanstamp = (caddr_t)(crtime + 2); 00139 *attrs = 0; 00140 if (XVA_ISSET_REQ(xvap, XAT_READONLY)) 00141 *attrs |= (xoap->xoa_readonly == 0) ? 0 : 00142 XAT0_READONLY; 00143 if (XVA_ISSET_REQ(xvap, XAT_HIDDEN)) 00144 *attrs |= (xoap->xoa_hidden == 0) ? 0 : 00145 XAT0_HIDDEN; 00146 if (XVA_ISSET_REQ(xvap, XAT_SYSTEM)) 00147 *attrs |= (xoap->xoa_system == 0) ? 0 : 00148 XAT0_SYSTEM; 00149 if (XVA_ISSET_REQ(xvap, XAT_ARCHIVE)) 00150 *attrs |= (xoap->xoa_archive == 0) ? 0 : 00151 XAT0_ARCHIVE; 00152 if (XVA_ISSET_REQ(xvap, XAT_IMMUTABLE)) 00153 *attrs |= (xoap->xoa_immutable == 0) ? 0 : 00154 XAT0_IMMUTABLE; 00155 if (XVA_ISSET_REQ(xvap, XAT_NOUNLINK)) 00156 *attrs |= (xoap->xoa_nounlink == 0) ? 0 : 00157 XAT0_NOUNLINK; 00158 if (XVA_ISSET_REQ(xvap, XAT_APPENDONLY)) 00159 *attrs |= (xoap->xoa_appendonly == 0) ? 0 : 00160 XAT0_APPENDONLY; 00161 if (XVA_ISSET_REQ(xvap, XAT_OPAQUE)) 00162 *attrs |= (xoap->xoa_opaque == 0) ? 0 : 00163 XAT0_APPENDONLY; 00164 if (XVA_ISSET_REQ(xvap, XAT_NODUMP)) 00165 *attrs |= (xoap->xoa_nodump == 0) ? 0 : 00166 XAT0_NODUMP; 00167 if (XVA_ISSET_REQ(xvap, XAT_AV_QUARANTINED)) 00168 *attrs |= (xoap->xoa_av_quarantined == 0) ? 0 : 00169 XAT0_AV_QUARANTINED; 00170 if (XVA_ISSET_REQ(xvap, XAT_AV_MODIFIED)) 00171 *attrs |= (xoap->xoa_av_modified == 0) ? 0 : 00172 XAT0_AV_MODIFIED; 00173 if (XVA_ISSET_REQ(xvap, XAT_CREATETIME)) 00174 ZFS_TIME_ENCODE(&xoap->xoa_createtime, crtime); 00175 if (XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP)) 00176 bcopy(xoap->xoa_av_scanstamp, scanstamp, AV_SCANSTAMP_SZ); 00177 if (XVA_ISSET_REQ(xvap, XAT_REPARSE)) 00178 *attrs |= (xoap->xoa_reparse == 0) ? 0 : 00179 XAT0_REPARSE; 00180 if (XVA_ISSET_REQ(xvap, XAT_OFFLINE)) 00181 *attrs |= (xoap->xoa_offline == 0) ? 0 : 00182 XAT0_OFFLINE; 00183 if (XVA_ISSET_REQ(xvap, XAT_SPARSE)) 00184 *attrs |= (xoap->xoa_sparse == 0) ? 0 : 00185 XAT0_SPARSE; 00186 } 00187 00188 static void * 00189 zfs_log_fuid_ids(zfs_fuid_info_t *fuidp, void *start) 00190 { 00191 zfs_fuid_t *zfuid; 00192 uint64_t *fuidloc = start; 00193 00194 /* First copy in the ACE FUIDs */ 00195 for (zfuid = list_head(&fuidp->z_fuids); zfuid; 00196 zfuid = list_next(&fuidp->z_fuids, zfuid)) { 00197 *fuidloc++ = zfuid->z_logfuid; 00198 } 00199 return (fuidloc); 00200 } 00201 00202 00203 static void * 00204 zfs_log_fuid_domains(zfs_fuid_info_t *fuidp, void *start) 00205 { 00206 zfs_fuid_domain_t *zdomain; 00207 00208 /* now copy in the domain info, if any */ 00209 if (fuidp->z_domain_str_sz != 0) { 00210 for (zdomain = list_head(&fuidp->z_domains); zdomain; 00211 zdomain = list_next(&fuidp->z_domains, zdomain)) { 00212 bcopy((void *)zdomain->z_domain, start, 00213 strlen(zdomain->z_domain) + 1); 00214 start = (caddr_t)start + 00215 strlen(zdomain->z_domain) + 1; 00216 } 00217 } 00218 return (start); 00219 } 00220 00240 void 00241 zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, 00242 znode_t *dzp, znode_t *zp, char *name, vsecattr_t *vsecp, 00243 zfs_fuid_info_t *fuidp, vattr_t *vap) 00244 { 00245 itx_t *itx; 00246 lr_create_t *lr; 00247 lr_acl_create_t *lracl; 00248 size_t aclsize; 00249 size_t xvatsize = 0; 00250 size_t txsize; 00251 xvattr_t *xvap = (xvattr_t *)vap; 00252 void *end; 00253 size_t lrsize; 00254 size_t namesize = strlen(name) + 1; 00255 size_t fuidsz = 0; 00256 00257 if (zil_replaying(zilog, tx)) 00258 return; 00259 00260 /* 00261 * If we have FUIDs present then add in space for 00262 * domains and ACE fuid's if any. 00263 */ 00264 if (fuidp) { 00265 fuidsz += fuidp->z_domain_str_sz; 00266 fuidsz += fuidp->z_fuid_cnt * sizeof (uint64_t); 00267 } 00268 00269 if (vap->va_mask & AT_XVATTR) 00270 xvatsize = ZIL_XVAT_SIZE(xvap->xva_mapsize); 00271 00272 if ((int)txtype == TX_CREATE_ATTR || (int)txtype == TX_MKDIR_ATTR || 00273 (int)txtype == TX_CREATE || (int)txtype == TX_MKDIR || 00274 (int)txtype == TX_MKXATTR) { 00275 txsize = sizeof (*lr) + namesize + fuidsz + xvatsize; 00276 lrsize = sizeof (*lr); 00277 } else { 00278 aclsize = (vsecp) ? vsecp->vsa_aclentsz : 0; 00279 txsize = 00280 sizeof (lr_acl_create_t) + namesize + fuidsz + 00281 ZIL_ACE_LENGTH(aclsize) + xvatsize; 00282 lrsize = sizeof (lr_acl_create_t); 00283 } 00284 00285 itx = zil_itx_create(txtype, txsize); 00286 00287 lr = (lr_create_t *)&itx->itx_lr; 00288 lr->lr_doid = dzp->z_id; 00289 lr->lr_foid = zp->z_id; 00290 lr->lr_mode = zp->z_mode; 00291 if (!IS_EPHEMERAL(zp->z_uid)) { 00292 lr->lr_uid = (uint64_t)zp->z_uid; 00293 } else { 00294 lr->lr_uid = fuidp->z_fuid_owner; 00295 } 00296 if (!IS_EPHEMERAL(zp->z_gid)) { 00297 lr->lr_gid = (uint64_t)zp->z_gid; 00298 } else { 00299 lr->lr_gid = fuidp->z_fuid_group; 00300 } 00301 (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zp->z_zfsvfs), &lr->lr_gen, 00302 sizeof (uint64_t)); 00303 (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(zp->z_zfsvfs), 00304 lr->lr_crtime, sizeof (uint64_t) * 2); 00305 00306 if (sa_lookup(zp->z_sa_hdl, SA_ZPL_RDEV(zp->z_zfsvfs), &lr->lr_rdev, 00307 sizeof (lr->lr_rdev)) != 0) 00308 lr->lr_rdev = 0; 00309 00310 /* 00311 * Fill in xvattr info if any 00312 */ 00313 if (vap->va_mask & AT_XVATTR) { 00314 zfs_log_xvattr((lr_attr_t *)((caddr_t)lr + lrsize), xvap); 00315 end = (caddr_t)lr + lrsize + xvatsize; 00316 } else { 00317 end = (caddr_t)lr + lrsize; 00318 } 00319 00320 /* Now fill in any ACL info */ 00321 00322 if (vsecp) { 00323 lracl = (lr_acl_create_t *)&itx->itx_lr; 00324 lracl->lr_aclcnt = vsecp->vsa_aclcnt; 00325 lracl->lr_acl_bytes = aclsize; 00326 lracl->lr_domcnt = fuidp ? fuidp->z_domain_cnt : 0; 00327 lracl->lr_fuidcnt = fuidp ? fuidp->z_fuid_cnt : 0; 00328 if (vsecp->vsa_aclflags & VSA_ACE_ACLFLAGS) 00329 lracl->lr_acl_flags = (uint64_t)vsecp->vsa_aclflags; 00330 else 00331 lracl->lr_acl_flags = 0; 00332 00333 bcopy(vsecp->vsa_aclentp, end, aclsize); 00334 end = (caddr_t)end + ZIL_ACE_LENGTH(aclsize); 00335 } 00336 00337 /* drop in FUID info */ 00338 if (fuidp) { 00339 end = zfs_log_fuid_ids(fuidp, end); 00340 end = zfs_log_fuid_domains(fuidp, end); 00341 } 00342 /* 00343 * Now place file name in log record 00344 */ 00345 bcopy(name, end, namesize); 00346 00347 zil_itx_assign(zilog, itx, tx); 00348 } 00349 00353 void 00354 zfs_log_remove(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, 00355 znode_t *dzp, char *name, uint64_t foid) 00356 { 00357 itx_t *itx; 00358 lr_remove_t *lr; 00359 size_t namesize = strlen(name) + 1; 00360 00361 if (zil_replaying(zilog, tx)) 00362 return; 00363 00364 itx = zil_itx_create(txtype, sizeof (*lr) + namesize); 00365 lr = (lr_remove_t *)&itx->itx_lr; 00366 lr->lr_doid = dzp->z_id; 00367 bcopy(name, (char *)(lr + 1), namesize); 00368 00369 itx->itx_oid = foid; 00370 00371 zil_itx_assign(zilog, itx, tx); 00372 } 00373 00377 void 00378 zfs_log_link(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, 00379 znode_t *dzp, znode_t *zp, char *name) 00380 { 00381 itx_t *itx; 00382 lr_link_t *lr; 00383 size_t namesize = strlen(name) + 1; 00384 00385 if (zil_replaying(zilog, tx)) 00386 return; 00387 00388 itx = zil_itx_create(txtype, sizeof (*lr) + namesize); 00389 lr = (lr_link_t *)&itx->itx_lr; 00390 lr->lr_doid = dzp->z_id; 00391 lr->lr_link_obj = zp->z_id; 00392 bcopy(name, (char *)(lr + 1), namesize); 00393 00394 zil_itx_assign(zilog, itx, tx); 00395 } 00396 00400 void 00401 zfs_log_symlink(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, 00402 znode_t *dzp, znode_t *zp, char *name, char *link) 00403 { 00404 itx_t *itx; 00405 lr_create_t *lr; 00406 size_t namesize = strlen(name) + 1; 00407 size_t linksize = strlen(link) + 1; 00408 00409 if (zil_replaying(zilog, tx)) 00410 return; 00411 00412 itx = zil_itx_create(txtype, sizeof (*lr) + namesize + linksize); 00413 lr = (lr_create_t *)&itx->itx_lr; 00414 lr->lr_doid = dzp->z_id; 00415 lr->lr_foid = zp->z_id; 00416 lr->lr_uid = zp->z_uid; 00417 lr->lr_gid = zp->z_gid; 00418 lr->lr_mode = zp->z_mode; 00419 (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zp->z_zfsvfs), &lr->lr_gen, 00420 sizeof (uint64_t)); 00421 (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(zp->z_zfsvfs), 00422 lr->lr_crtime, sizeof (uint64_t) * 2); 00423 bcopy(name, (char *)(lr + 1), namesize); 00424 bcopy(link, (char *)(lr + 1) + namesize, linksize); 00425 00426 zil_itx_assign(zilog, itx, tx); 00427 } 00428 00432 void 00433 zfs_log_rename(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, 00434 znode_t *sdzp, char *sname, znode_t *tdzp, char *dname, znode_t *szp) 00435 { 00436 itx_t *itx; 00437 lr_rename_t *lr; 00438 size_t snamesize = strlen(sname) + 1; 00439 size_t dnamesize = strlen(dname) + 1; 00440 00441 if (zil_replaying(zilog, tx)) 00442 return; 00443 00444 itx = zil_itx_create(txtype, sizeof (*lr) + snamesize + dnamesize); 00445 lr = (lr_rename_t *)&itx->itx_lr; 00446 lr->lr_sdoid = sdzp->z_id; 00447 lr->lr_tdoid = tdzp->z_id; 00448 bcopy(sname, (char *)(lr + 1), snamesize); 00449 bcopy(dname, (char *)(lr + 1) + snamesize, dnamesize); 00450 itx->itx_oid = szp->z_id; 00451 00452 zil_itx_assign(zilog, itx, tx); 00453 } 00454 00458 ssize_t zfs_immediate_write_sz = 32768; 00459 00460 void 00461 zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype, 00462 znode_t *zp, offset_t off, ssize_t resid, int ioflag) 00463 { 00464 itx_wr_state_t write_state; 00465 boolean_t slogging; 00466 uintptr_t fsync_cnt; 00467 ssize_t immediate_write_sz; 00468 00469 if (zil_replaying(zilog, tx) || zp->z_unlinked) 00470 return; 00471 00472 immediate_write_sz = (zilog->zl_logbias == ZFS_LOGBIAS_THROUGHPUT) 00473 ? 0 : zfs_immediate_write_sz; 00474 00475 slogging = spa_has_slogs(zilog->zl_spa) && 00476 (zilog->zl_logbias == ZFS_LOGBIAS_LATENCY); 00477 if (resid > immediate_write_sz && !slogging && resid <= zp->z_blksz) 00478 write_state = WR_INDIRECT; 00479 else if (ioflag & (FSYNC | FDSYNC)) 00480 write_state = WR_COPIED; 00481 else 00482 write_state = WR_NEED_COPY; 00483 00484 if ((fsync_cnt = (uintptr_t)tsd_get(zfs_fsyncer_key)) != 0) { 00485 (void) tsd_set(zfs_fsyncer_key, (void *)(fsync_cnt - 1)); 00486 } 00487 00488 while (resid) { 00489 itx_t *itx; 00490 lr_write_t *lr; 00491 ssize_t len; 00492 00493 /* 00494 * If the write would overflow the largest block then split it. 00495 */ 00496 if (write_state != WR_INDIRECT && resid > ZIL_MAX_LOG_DATA) 00497 len = SPA_MAXBLOCKSIZE >> 1; 00498 else 00499 len = resid; 00500 00501 itx = zil_itx_create(txtype, sizeof (*lr) + 00502 (write_state == WR_COPIED ? len : 0)); 00503 lr = (lr_write_t *)&itx->itx_lr; 00504 if (write_state == WR_COPIED && dmu_read(zp->z_zfsvfs->z_os, 00505 zp->z_id, off, len, lr + 1, DMU_READ_NO_PREFETCH) != 0) { 00506 zil_itx_destroy(itx); 00507 itx = zil_itx_create(txtype, sizeof (*lr)); 00508 lr = (lr_write_t *)&itx->itx_lr; 00509 write_state = WR_NEED_COPY; 00510 } 00511 00512 itx->itx_wr_state = write_state; 00513 if (write_state == WR_NEED_COPY) 00514 itx->itx_sod += len; 00515 lr->lr_foid = zp->z_id; 00516 lr->lr_offset = off; 00517 lr->lr_length = len; 00518 lr->lr_blkoff = 0; 00519 BP_ZERO(&lr->lr_blkptr); 00520 00521 itx->itx_private = zp->z_zfsvfs; 00522 00523 if (!(ioflag & (FSYNC | FDSYNC)) && (zp->z_sync_cnt == 0) && 00524 (fsync_cnt == 0)) 00525 itx->itx_sync = B_FALSE; 00526 00527 zil_itx_assign(zilog, itx, tx); 00528 00529 off += len; 00530 resid -= len; 00531 } 00532 } 00533 00537 void 00538 zfs_log_truncate(zilog_t *zilog, dmu_tx_t *tx, int txtype, 00539 znode_t *zp, uint64_t off, uint64_t len) 00540 { 00541 itx_t *itx; 00542 lr_truncate_t *lr; 00543 00544 if (zil_replaying(zilog, tx) || zp->z_unlinked) 00545 return; 00546 00547 itx = zil_itx_create(txtype, sizeof (*lr)); 00548 lr = (lr_truncate_t *)&itx->itx_lr; 00549 lr->lr_foid = zp->z_id; 00550 lr->lr_offset = off; 00551 lr->lr_length = len; 00552 00553 itx->itx_sync = (zp->z_sync_cnt != 0); 00554 zil_itx_assign(zilog, itx, tx); 00555 } 00556 00560 void 00561 zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype, 00562 znode_t *zp, vattr_t *vap, uint_t mask_applied, zfs_fuid_info_t *fuidp) 00563 { 00564 itx_t *itx; 00565 lr_setattr_t *lr; 00566 xvattr_t *xvap = (xvattr_t *)vap; 00567 size_t recsize = sizeof (lr_setattr_t); 00568 void *start; 00569 00570 if (zil_replaying(zilog, tx) || zp->z_unlinked) 00571 return; 00572 00573 /* 00574 * If XVATTR set, then log record size needs to allow 00575 * for lr_attr_t + xvattr mask, mapsize and create time 00576 * plus actual attribute values 00577 */ 00578 if (vap->va_mask & AT_XVATTR) 00579 recsize = sizeof (*lr) + ZIL_XVAT_SIZE(xvap->xva_mapsize); 00580 00581 if (fuidp) 00582 recsize += fuidp->z_domain_str_sz; 00583 00584 itx = zil_itx_create(txtype, recsize); 00585 lr = (lr_setattr_t *)&itx->itx_lr; 00586 lr->lr_foid = zp->z_id; 00587 lr->lr_mask = (uint64_t)mask_applied; 00588 lr->lr_mode = (uint64_t)vap->va_mode; 00589 if ((mask_applied & AT_UID) && IS_EPHEMERAL(vap->va_uid)) 00590 lr->lr_uid = fuidp->z_fuid_owner; 00591 else 00592 lr->lr_uid = (uint64_t)vap->va_uid; 00593 00594 if ((mask_applied & AT_GID) && IS_EPHEMERAL(vap->va_gid)) 00595 lr->lr_gid = fuidp->z_fuid_group; 00596 else 00597 lr->lr_gid = (uint64_t)vap->va_gid; 00598 00599 lr->lr_size = (uint64_t)vap->va_size; 00600 ZFS_TIME_ENCODE(&vap->va_atime, lr->lr_atime); 00601 ZFS_TIME_ENCODE(&vap->va_mtime, lr->lr_mtime); 00602 start = (lr_setattr_t *)(lr + 1); 00603 if (vap->va_mask & AT_XVATTR) { 00604 zfs_log_xvattr((lr_attr_t *)start, xvap); 00605 start = (caddr_t)start + ZIL_XVAT_SIZE(xvap->xva_mapsize); 00606 } 00607 00608 /* 00609 * Now stick on domain information if any on end 00610 */ 00611 00612 if (fuidp) 00613 (void) zfs_log_fuid_domains(fuidp, start); 00614 00615 itx->itx_sync = (zp->z_sync_cnt != 0); 00616 zil_itx_assign(zilog, itx, tx); 00617 } 00618 00622 void 00623 zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp, 00624 vsecattr_t *vsecp, zfs_fuid_info_t *fuidp) 00625 { 00626 itx_t *itx; 00627 lr_acl_v0_t *lrv0; 00628 lr_acl_t *lr; 00629 int txtype; 00630 int lrsize; 00631 size_t txsize; 00632 size_t aclbytes = vsecp->vsa_aclentsz; 00633 00634 if (zil_replaying(zilog, tx) || zp->z_unlinked) 00635 return; 00636 00637 txtype = (zp->z_zfsvfs->z_version < ZPL_VERSION_FUID) ? 00638 TX_ACL_V0 : TX_ACL; 00639 00640 if (txtype == TX_ACL) 00641 lrsize = sizeof (*lr); 00642 else 00643 lrsize = sizeof (*lrv0); 00644 00645 txsize = lrsize + 00646 ((txtype == TX_ACL) ? ZIL_ACE_LENGTH(aclbytes) : aclbytes) + 00647 (fuidp ? fuidp->z_domain_str_sz : 0) + 00648 sizeof (uint64_t) * (fuidp ? fuidp->z_fuid_cnt : 0); 00649 00650 itx = zil_itx_create(txtype, txsize); 00651 00652 lr = (lr_acl_t *)&itx->itx_lr; 00653 lr->lr_foid = zp->z_id; 00654 if (txtype == TX_ACL) { 00655 lr->lr_acl_bytes = aclbytes; 00656 lr->lr_domcnt = fuidp ? fuidp->z_domain_cnt : 0; 00657 lr->lr_fuidcnt = fuidp ? fuidp->z_fuid_cnt : 0; 00658 if (vsecp->vsa_mask & VSA_ACE_ACLFLAGS) 00659 lr->lr_acl_flags = (uint64_t)vsecp->vsa_aclflags; 00660 else 00661 lr->lr_acl_flags = 0; 00662 } 00663 lr->lr_aclcnt = (uint64_t)vsecp->vsa_aclcnt; 00664 00665 if (txtype == TX_ACL_V0) { 00666 lrv0 = (lr_acl_v0_t *)lr; 00667 bcopy(vsecp->vsa_aclentp, (ace_t *)(lrv0 + 1), aclbytes); 00668 } else { 00669 void *start = (ace_t *)(lr + 1); 00670 00671 bcopy(vsecp->vsa_aclentp, start, aclbytes); 00672 00673 start = (caddr_t)start + ZIL_ACE_LENGTH(aclbytes); 00674 00675 if (fuidp) { 00676 start = zfs_log_fuid_ids(fuidp, start); 00677 (void) zfs_log_fuid_domains(fuidp, start); 00678 } 00679 } 00680 00681 itx->itx_sync = (zp->z_sync_cnt != 0); 00682 zil_itx_assign(zilog, itx, tx); 00683 }