194
195 static void *
196 zfs_log_fuid_domains(zfs_fuid_info_t *fuidp, void *start)
197 {
198 zfs_fuid_domain_t *zdomain;
199
200 /* now copy in the domain info, if any */
201 if (fuidp->z_domain_str_sz != 0) {
202 for (zdomain = list_head(&fuidp->z_domains); zdomain;
203 zdomain = list_next(&fuidp->z_domains, zdomain)) {
204 bcopy((void *)zdomain->z_domain, start,
205 strlen(zdomain->z_domain) + 1);
206 start = (caddr_t)start +
207 strlen(zdomain->z_domain) + 1;
208 }
209 }
210 return (start);
211 }
212
213 /*
214 * zfs_log_create() is used to handle TX_CREATE, TX_CREATE_ATTR, TX_MKDIR,
215 * TX_MKDIR_ATTR and TX_MKXATTR
216 * transactions.
217 *
218 * TX_CREATE and TX_MKDIR are standard creates, but they may have FUID
219 * domain information appended prior to the name. In this case the
220 * uid/gid in the log record will be a log centric FUID.
221 *
222 * TX_CREATE_ACL_ATTR and TX_MKDIR_ACL_ATTR handle special creates that
223 * may contain attributes, ACL and optional fuid information.
224 *
225 * TX_CREATE_ACL and TX_MKDIR_ACL handle special creates that specify
226 * and ACL and normal users/groups in the ACEs.
227 *
228 * There may be an optional xvattr attribute information similar
229 * to zfs_log_setattr.
230 *
231 * Also, after the file name "domain" strings may be appended.
232 */
233 void
234 zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
235 znode_t *dzp, znode_t *zp, char *name, vsecattr_t *vsecp,
236 zfs_fuid_info_t *fuidp, vattr_t *vap)
323 lracl->lr_acl_flags = 0;
324
325 bcopy(vsecp->vsa_aclentp, end, aclsize);
326 end = (caddr_t)end + ZIL_ACE_LENGTH(aclsize);
327 }
328
329 /* drop in FUID info */
330 if (fuidp) {
331 end = zfs_log_fuid_ids(fuidp, end);
332 end = zfs_log_fuid_domains(fuidp, end);
333 }
334 /*
335 * Now place file name in log record
336 */
337 bcopy(name, end, namesize);
338
339 zil_itx_assign(zilog, itx, tx);
340 }
341
342 /*
343 * zfs_log_remove() handles both TX_REMOVE and TX_RMDIR transactions.
344 */
345 void
346 zfs_log_remove(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
347 znode_t *dzp, char *name, uint64_t foid)
348 {
349 itx_t *itx;
350 lr_remove_t *lr;
351 size_t namesize = strlen(name) + 1;
352
353 if (zil_replaying(zilog, tx))
354 return;
355
356 itx = zil_itx_create(txtype, sizeof (*lr) + namesize);
357 lr = (lr_remove_t *)&itx->itx_lr;
358 lr->lr_doid = dzp->z_id;
359 bcopy(name, (char *)(lr + 1), namesize);
360
361 itx->itx_oid = foid;
362
363 zil_itx_assign(zilog, itx, tx);
364 }
365
366 /*
367 * zfs_log_link() handles TX_LINK transactions.
368 */
369 void
370 zfs_log_link(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
371 znode_t *dzp, znode_t *zp, char *name)
372 {
373 itx_t *itx;
374 lr_link_t *lr;
375 size_t namesize = strlen(name) + 1;
376
377 if (zil_replaying(zilog, tx))
378 return;
379
380 itx = zil_itx_create(txtype, sizeof (*lr) + namesize);
381 lr = (lr_link_t *)&itx->itx_lr;
382 lr->lr_doid = dzp->z_id;
383 lr->lr_link_obj = zp->z_id;
384 bcopy(name, (char *)(lr + 1), namesize);
385
386 zil_itx_assign(zilog, itx, tx);
387 }
388
389 /*
390 * zfs_log_symlink() handles TX_SYMLINK transactions.
391 */
392 void
393 zfs_log_symlink(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
394 znode_t *dzp, znode_t *zp, char *name, char *link)
395 {
396 itx_t *itx;
397 lr_create_t *lr;
398 size_t namesize = strlen(name) + 1;
399 size_t linksize = strlen(link) + 1;
400
401 if (zil_replaying(zilog, tx))
402 return;
403
404 itx = zil_itx_create(txtype, sizeof (*lr) + namesize + linksize);
405 lr = (lr_create_t *)&itx->itx_lr;
406 lr->lr_doid = dzp->z_id;
407 lr->lr_foid = zp->z_id;
408 lr->lr_uid = zp->z_uid;
409 lr->lr_gid = zp->z_gid;
410 lr->lr_mode = zp->z_mode;
411 (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zp->z_zfsvfs), &lr->lr_gen,
412 sizeof (uint64_t));
413 (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(zp->z_zfsvfs),
414 lr->lr_crtime, sizeof (uint64_t) * 2);
415 bcopy(name, (char *)(lr + 1), namesize);
416 bcopy(link, (char *)(lr + 1) + namesize, linksize);
417
418 zil_itx_assign(zilog, itx, tx);
419 }
420
421 /*
422 * zfs_log_rename() handles TX_RENAME transactions.
423 */
424 void
425 zfs_log_rename(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
426 znode_t *sdzp, char *sname, znode_t *tdzp, char *dname, znode_t *szp)
427 {
428 itx_t *itx;
429 lr_rename_t *lr;
430 size_t snamesize = strlen(sname) + 1;
431 size_t dnamesize = strlen(dname) + 1;
432
433 if (zil_replaying(zilog, tx))
434 return;
435
436 itx = zil_itx_create(txtype, sizeof (*lr) + snamesize + dnamesize);
437 lr = (lr_rename_t *)&itx->itx_lr;
438 lr->lr_sdoid = sdzp->z_id;
439 lr->lr_tdoid = tdzp->z_id;
440 bcopy(sname, (char *)(lr + 1), snamesize);
441 bcopy(dname, (char *)(lr + 1) + snamesize, dnamesize);
442 itx->itx_oid = szp->z_id;
443
444 zil_itx_assign(zilog, itx, tx);
445 }
446
447 /*
448 * zfs_log_write() handles TX_WRITE transactions.
449 */
450 ssize_t zfs_immediate_write_sz = 32768;
451
452 void
453 zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
454 znode_t *zp, offset_t off, ssize_t resid, int ioflag)
455 {
456 itx_wr_state_t write_state;
457 boolean_t slogging;
458 uintptr_t fsync_cnt;
459 ssize_t immediate_write_sz;
460
461 if (zil_replaying(zilog, tx) || zp->z_unlinked)
462 return;
463
464 immediate_write_sz = (zilog->zl_logbias == ZFS_LOGBIAS_THROUGHPUT)
465 ? 0 : zfs_immediate_write_sz;
466
467 slogging = spa_has_slogs(zilog->zl_spa) &&
468 (zilog->zl_logbias == ZFS_LOGBIAS_LATENCY);
507 lr->lr_foid = zp->z_id;
508 lr->lr_offset = off;
509 lr->lr_length = len;
510 lr->lr_blkoff = 0;
511 BP_ZERO(&lr->lr_blkptr);
512
513 itx->itx_private = zp->z_zfsvfs;
514
515 if (!(ioflag & (FSYNC | FDSYNC)) && (zp->z_sync_cnt == 0) &&
516 (fsync_cnt == 0))
517 itx->itx_sync = B_FALSE;
518
519 zil_itx_assign(zilog, itx, tx);
520
521 off += len;
522 resid -= len;
523 }
524 }
525
526 /*
527 * zfs_log_truncate() handles TX_TRUNCATE transactions.
528 */
529 void
530 zfs_log_truncate(zilog_t *zilog, dmu_tx_t *tx, int txtype,
531 znode_t *zp, uint64_t off, uint64_t len)
532 {
533 itx_t *itx;
534 lr_truncate_t *lr;
535
536 if (zil_replaying(zilog, tx) || zp->z_unlinked)
537 return;
538
539 itx = zil_itx_create(txtype, sizeof (*lr));
540 lr = (lr_truncate_t *)&itx->itx_lr;
541 lr->lr_foid = zp->z_id;
542 lr->lr_offset = off;
543 lr->lr_length = len;
544
545 itx->itx_sync = (zp->z_sync_cnt != 0);
546 zil_itx_assign(zilog, itx, tx);
547 }
548
549 /*
550 * zfs_log_setattr() handles TX_SETATTR transactions.
551 */
552 void
553 zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype,
554 znode_t *zp, vattr_t *vap, uint_t mask_applied, zfs_fuid_info_t *fuidp)
555 {
556 itx_t *itx;
557 lr_setattr_t *lr;
558 xvattr_t *xvap = (xvattr_t *)vap;
559 size_t recsize = sizeof (lr_setattr_t);
560 void *start;
561
562 if (zil_replaying(zilog, tx) || zp->z_unlinked)
563 return;
564
565 /*
566 * If XVATTR set, then log record size needs to allow
567 * for lr_attr_t + xvattr mask, mapsize and create time
568 * plus actual attribute values
569 */
570 if (vap->va_mask & AT_XVATTR)
592 ZFS_TIME_ENCODE(&vap->va_atime, lr->lr_atime);
593 ZFS_TIME_ENCODE(&vap->va_mtime, lr->lr_mtime);
594 start = (lr_setattr_t *)(lr + 1);
595 if (vap->va_mask & AT_XVATTR) {
596 zfs_log_xvattr((lr_attr_t *)start, xvap);
597 start = (caddr_t)start + ZIL_XVAT_SIZE(xvap->xva_mapsize);
598 }
599
600 /*
601 * Now stick on domain information if any on end
602 */
603
604 if (fuidp)
605 (void) zfs_log_fuid_domains(fuidp, start);
606
607 itx->itx_sync = (zp->z_sync_cnt != 0);
608 zil_itx_assign(zilog, itx, tx);
609 }
610
611 /*
612 * zfs_log_acl() handles TX_ACL transactions.
613 */
614 void
615 zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp,
616 vsecattr_t *vsecp, zfs_fuid_info_t *fuidp)
617 {
618 itx_t *itx;
619 lr_acl_v0_t *lrv0;
620 lr_acl_t *lr;
621 int txtype;
622 int lrsize;
623 size_t txsize;
624 size_t aclbytes = vsecp->vsa_aclentsz;
625
626 if (zil_replaying(zilog, tx) || zp->z_unlinked)
627 return;
628
629 txtype = (zp->z_zfsvfs->z_version < ZPL_VERSION_FUID) ?
630 TX_ACL_V0 : TX_ACL;
631
632 if (txtype == TX_ACL)
|
194
195 static void *
196 zfs_log_fuid_domains(zfs_fuid_info_t *fuidp, void *start)
197 {
198 zfs_fuid_domain_t *zdomain;
199
200 /* now copy in the domain info, if any */
201 if (fuidp->z_domain_str_sz != 0) {
202 for (zdomain = list_head(&fuidp->z_domains); zdomain;
203 zdomain = list_next(&fuidp->z_domains, zdomain)) {
204 bcopy((void *)zdomain->z_domain, start,
205 strlen(zdomain->z_domain) + 1);
206 start = (caddr_t)start +
207 strlen(zdomain->z_domain) + 1;
208 }
209 }
210 return (start);
211 }
212
213 /*
214 * Handles TX_CREATE, TX_CREATE_ATTR, TX_MKDIR, TX_MKDIR_ATTR and
215 * TK_MKXATTR transactions.
216 *
217 * TX_CREATE and TX_MKDIR are standard creates, but they may have FUID
218 * domain information appended prior to the name. In this case the
219 * uid/gid in the log record will be a log centric FUID.
220 *
221 * TX_CREATE_ACL_ATTR and TX_MKDIR_ACL_ATTR handle special creates that
222 * may contain attributes, ACL and optional fuid information.
223 *
224 * TX_CREATE_ACL and TX_MKDIR_ACL handle special creates that specify
225 * and ACL and normal users/groups in the ACEs.
226 *
227 * There may be an optional xvattr attribute information similar
228 * to zfs_log_setattr.
229 *
230 * Also, after the file name "domain" strings may be appended.
231 */
232 void
233 zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
234 znode_t *dzp, znode_t *zp, char *name, vsecattr_t *vsecp,
235 zfs_fuid_info_t *fuidp, vattr_t *vap)
322 lracl->lr_acl_flags = 0;
323
324 bcopy(vsecp->vsa_aclentp, end, aclsize);
325 end = (caddr_t)end + ZIL_ACE_LENGTH(aclsize);
326 }
327
328 /* drop in FUID info */
329 if (fuidp) {
330 end = zfs_log_fuid_ids(fuidp, end);
331 end = zfs_log_fuid_domains(fuidp, end);
332 }
333 /*
334 * Now place file name in log record
335 */
336 bcopy(name, end, namesize);
337
338 zil_itx_assign(zilog, itx, tx);
339 }
340
341 /*
342 * Handles both TX_REMOVE and TX_RMDIR transactions.
343 */
344 void
345 zfs_log_remove(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
346 znode_t *dzp, char *name, uint64_t foid)
347 {
348 itx_t *itx;
349 lr_remove_t *lr;
350 size_t namesize = strlen(name) + 1;
351
352 if (zil_replaying(zilog, tx))
353 return;
354
355 itx = zil_itx_create(txtype, sizeof (*lr) + namesize);
356 lr = (lr_remove_t *)&itx->itx_lr;
357 lr->lr_doid = dzp->z_id;
358 bcopy(name, (char *)(lr + 1), namesize);
359
360 itx->itx_oid = foid;
361
362 zil_itx_assign(zilog, itx, tx);
363 }
364
365 /*
366 * Handles TX_LINK transactions.
367 */
368 void
369 zfs_log_link(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
370 znode_t *dzp, znode_t *zp, char *name)
371 {
372 itx_t *itx;
373 lr_link_t *lr;
374 size_t namesize = strlen(name) + 1;
375
376 if (zil_replaying(zilog, tx))
377 return;
378
379 itx = zil_itx_create(txtype, sizeof (*lr) + namesize);
380 lr = (lr_link_t *)&itx->itx_lr;
381 lr->lr_doid = dzp->z_id;
382 lr->lr_link_obj = zp->z_id;
383 bcopy(name, (char *)(lr + 1), namesize);
384
385 zil_itx_assign(zilog, itx, tx);
386 }
387
388 /*
389 * Handles TX_SYMLINK transactions.
390 */
391 void
392 zfs_log_symlink(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
393 znode_t *dzp, znode_t *zp, char *name, char *link)
394 {
395 itx_t *itx;
396 lr_create_t *lr;
397 size_t namesize = strlen(name) + 1;
398 size_t linksize = strlen(link) + 1;
399
400 if (zil_replaying(zilog, tx))
401 return;
402
403 itx = zil_itx_create(txtype, sizeof (*lr) + namesize + linksize);
404 lr = (lr_create_t *)&itx->itx_lr;
405 lr->lr_doid = dzp->z_id;
406 lr->lr_foid = zp->z_id;
407 lr->lr_uid = zp->z_uid;
408 lr->lr_gid = zp->z_gid;
409 lr->lr_mode = zp->z_mode;
410 (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zp->z_zfsvfs), &lr->lr_gen,
411 sizeof (uint64_t));
412 (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(zp->z_zfsvfs),
413 lr->lr_crtime, sizeof (uint64_t) * 2);
414 bcopy(name, (char *)(lr + 1), namesize);
415 bcopy(link, (char *)(lr + 1) + namesize, linksize);
416
417 zil_itx_assign(zilog, itx, tx);
418 }
419
420 /*
421 * Handles TX_RENAME transactions.
422 */
423 void
424 zfs_log_rename(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
425 znode_t *sdzp, char *sname, znode_t *tdzp, char *dname, znode_t *szp)
426 {
427 itx_t *itx;
428 lr_rename_t *lr;
429 size_t snamesize = strlen(sname) + 1;
430 size_t dnamesize = strlen(dname) + 1;
431
432 if (zil_replaying(zilog, tx))
433 return;
434
435 itx = zil_itx_create(txtype, sizeof (*lr) + snamesize + dnamesize);
436 lr = (lr_rename_t *)&itx->itx_lr;
437 lr->lr_sdoid = sdzp->z_id;
438 lr->lr_tdoid = tdzp->z_id;
439 bcopy(sname, (char *)(lr + 1), snamesize);
440 bcopy(dname, (char *)(lr + 1) + snamesize, dnamesize);
441 itx->itx_oid = szp->z_id;
442
443 zil_itx_assign(zilog, itx, tx);
444 }
445
446 /*
447 * Handles TX_WRITE transactions.
448 */
449 ssize_t zfs_immediate_write_sz = 32768;
450
451 void
452 zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
453 znode_t *zp, offset_t off, ssize_t resid, int ioflag)
454 {
455 itx_wr_state_t write_state;
456 boolean_t slogging;
457 uintptr_t fsync_cnt;
458 ssize_t immediate_write_sz;
459
460 if (zil_replaying(zilog, tx) || zp->z_unlinked)
461 return;
462
463 immediate_write_sz = (zilog->zl_logbias == ZFS_LOGBIAS_THROUGHPUT)
464 ? 0 : zfs_immediate_write_sz;
465
466 slogging = spa_has_slogs(zilog->zl_spa) &&
467 (zilog->zl_logbias == ZFS_LOGBIAS_LATENCY);
506 lr->lr_foid = zp->z_id;
507 lr->lr_offset = off;
508 lr->lr_length = len;
509 lr->lr_blkoff = 0;
510 BP_ZERO(&lr->lr_blkptr);
511
512 itx->itx_private = zp->z_zfsvfs;
513
514 if (!(ioflag & (FSYNC | FDSYNC)) && (zp->z_sync_cnt == 0) &&
515 (fsync_cnt == 0))
516 itx->itx_sync = B_FALSE;
517
518 zil_itx_assign(zilog, itx, tx);
519
520 off += len;
521 resid -= len;
522 }
523 }
524
525 /*
526 * Handles TX_TRUNCATE transactions.
527 */
528 void
529 zfs_log_truncate(zilog_t *zilog, dmu_tx_t *tx, int txtype,
530 znode_t *zp, uint64_t off, uint64_t len)
531 {
532 itx_t *itx;
533 lr_truncate_t *lr;
534
535 if (zil_replaying(zilog, tx) || zp->z_unlinked)
536 return;
537
538 itx = zil_itx_create(txtype, sizeof (*lr));
539 lr = (lr_truncate_t *)&itx->itx_lr;
540 lr->lr_foid = zp->z_id;
541 lr->lr_offset = off;
542 lr->lr_length = len;
543
544 itx->itx_sync = (zp->z_sync_cnt != 0);
545 zil_itx_assign(zilog, itx, tx);
546 }
547
548 /*
549 * Handles TX_SETATTR transactions.
550 */
551 void
552 zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype,
553 znode_t *zp, vattr_t *vap, uint_t mask_applied, zfs_fuid_info_t *fuidp)
554 {
555 itx_t *itx;
556 lr_setattr_t *lr;
557 xvattr_t *xvap = (xvattr_t *)vap;
558 size_t recsize = sizeof (lr_setattr_t);
559 void *start;
560
561 if (zil_replaying(zilog, tx) || zp->z_unlinked)
562 return;
563
564 /*
565 * If XVATTR set, then log record size needs to allow
566 * for lr_attr_t + xvattr mask, mapsize and create time
567 * plus actual attribute values
568 */
569 if (vap->va_mask & AT_XVATTR)
591 ZFS_TIME_ENCODE(&vap->va_atime, lr->lr_atime);
592 ZFS_TIME_ENCODE(&vap->va_mtime, lr->lr_mtime);
593 start = (lr_setattr_t *)(lr + 1);
594 if (vap->va_mask & AT_XVATTR) {
595 zfs_log_xvattr((lr_attr_t *)start, xvap);
596 start = (caddr_t)start + ZIL_XVAT_SIZE(xvap->xva_mapsize);
597 }
598
599 /*
600 * Now stick on domain information if any on end
601 */
602
603 if (fuidp)
604 (void) zfs_log_fuid_domains(fuidp, start);
605
606 itx->itx_sync = (zp->z_sync_cnt != 0);
607 zil_itx_assign(zilog, itx, tx);
608 }
609
610 /*
611 * Handles TX_ACL transactions.
612 */
613 void
614 zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp,
615 vsecattr_t *vsecp, zfs_fuid_info_t *fuidp)
616 {
617 itx_t *itx;
618 lr_acl_v0_t *lrv0;
619 lr_acl_t *lr;
620 int txtype;
621 int lrsize;
622 size_t txsize;
623 size_t aclbytes = vsecp->vsa_aclentsz;
624
625 if (zil_replaying(zilog, tx) || zp->z_unlinked)
626 return;
627
628 txtype = (zp->z_zfsvfs->z_version < ZPL_VERSION_FUID) ?
629 TX_ACL_V0 : TX_ACL;
630
631 if (txtype == TX_ACL)
|