zfs_log: add flex array fields to log record structs

ZIL log record structs (lr_XX_t) are frequently allocated with extra
space after the struct to carry variable-sized "payload" items.

Linux 6.10+ compiled with CONFIG_FORTIFY_SOURCE has been doing runtime
bounds checking on memcpy() calls. Because these types had no indicator
that they might use more space than their simple definition,
__fortify_memcpy_chk will frequently complain about overruns eg:

    memcpy: detected field-spanning write (size 7) of single field
        "lr + 1" at zfs_log.c:425 (size 0)
    memcpy: detected field-spanning write (size 9) of single field
        "(char *)(lr + 1)" at zfs_log.c:593 (size 0)
    memcpy: detected field-spanning write (size 4) of single field
        "(char *)(lr + 1) + snamesize" at zfs_log.c:594 (size 0)
    memcpy: detected field-spanning write (size 7) of single field
        "lr + 1" at zfs_log.c:425 (size 0)
    memcpy: detected field-spanning write (size 9) of single field
        "(char *)(lr + 1)" at zfs_log.c:593 (size 0)
    memcpy: detected field-spanning write (size 4) of single field
        "(char *)(lr + 1) + snamesize" at zfs_log.c:594 (size 0)
    memcpy: detected field-spanning write (size 7) of single field
        "lr + 1" at zfs_log.c:425 (size 0)
    memcpy: detected field-spanning write (size 9) of single field
        "(char *)(lr + 1)" at zfs_log.c:593 (size 0)
    memcpy: detected field-spanning write (size 4) of single field
        "(char *)(lr + 1) + snamesize" at zfs_log.c:594 (size 0)

To fix this, this commit adds flex array fields to all lr_XX_t structs
that require them, and then uses those fields to access that
end-of-struct area rather than more complicated casts and pointer
addition.

Sponsored-by: https://despairlabs.com/sponsor/
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Norris <robn@despairlabs.com>
Closes #16501
Closes #16539
This commit is contained in:
Rob Norris 2024-09-28 02:18:11 +10:00 committed by Tony Hutter
parent 56608daa8d
commit 30ea442961
5 changed files with 162 additions and 131 deletions

View File

@ -64,7 +64,8 @@ static void
zil_prt_rec_create(zilog_t *zilog, int txtype, const void *arg) zil_prt_rec_create(zilog_t *zilog, int txtype, const void *arg)
{ {
(void) zilog; (void) zilog;
const lr_create_t *lr = arg; const lr_create_t *lrc = arg;
const _lr_create_t *lr = &lrc->lr_create;
time_t crtime = lr->lr_crtime[0]; time_t crtime = lr->lr_crtime[0];
char *name, *link; char *name, *link;
lr_attr_t *lrattr; lr_attr_t *lrattr;
@ -121,7 +122,8 @@ static void
zil_prt_rec_rename(zilog_t *zilog, int txtype, const void *arg) zil_prt_rec_rename(zilog_t *zilog, int txtype, const void *arg)
{ {
(void) zilog, (void) txtype; (void) zilog, (void) txtype;
const lr_rename_t *lr = arg; const lr_rename_t *lrr = arg;
const _lr_rename_t *lr = &lrr->lr_rename;
char *snm = (char *)(lr + 1); char *snm = (char *)(lr + 1);
char *tnm = snm + strlen(snm) + 1; char *tnm = snm + strlen(snm) + 1;

View File

@ -1861,7 +1861,7 @@ ztest_verify_unused_bonus(dmu_buf_t *db, void *end, uint64_t obj,
static void static void
ztest_log_create(ztest_ds_t *zd, dmu_tx_t *tx, lr_create_t *lr) ztest_log_create(ztest_ds_t *zd, dmu_tx_t *tx, lr_create_t *lr)
{ {
char *name = (void *)(lr + 1); /* name follows lr */ char *name = (char *)&lr->lr_data[0]; /* name follows lr */
size_t namesize = strlen(name) + 1; size_t namesize = strlen(name) + 1;
itx_t *itx; itx_t *itx;
@ -1869,7 +1869,7 @@ ztest_log_create(ztest_ds_t *zd, dmu_tx_t *tx, lr_create_t *lr)
return; return;
itx = zil_itx_create(TX_CREATE, sizeof (*lr) + namesize); itx = zil_itx_create(TX_CREATE, sizeof (*lr) + namesize);
memcpy(&itx->itx_lr + 1, &lr->lr_common + 1, memcpy(&itx->itx_lr + 1, &lr->lr_create.lr_common + 1,
sizeof (*lr) + namesize - sizeof (lr_t)); sizeof (*lr) + namesize - sizeof (lr_t));
zil_itx_assign(zd->zd_zilog, itx, tx); zil_itx_assign(zd->zd_zilog, itx, tx);
@ -1878,7 +1878,7 @@ ztest_log_create(ztest_ds_t *zd, dmu_tx_t *tx, lr_create_t *lr)
static void static void
ztest_log_remove(ztest_ds_t *zd, dmu_tx_t *tx, lr_remove_t *lr, uint64_t object) ztest_log_remove(ztest_ds_t *zd, dmu_tx_t *tx, lr_remove_t *lr, uint64_t object)
{ {
char *name = (void *)(lr + 1); /* name follows lr */ char *name = (char *)&lr->lr_data[0]; /* name follows lr */
size_t namesize = strlen(name) + 1; size_t namesize = strlen(name) + 1;
itx_t *itx; itx_t *itx;
@ -1964,8 +1964,9 @@ static int
ztest_replay_create(void *arg1, void *arg2, boolean_t byteswap) ztest_replay_create(void *arg1, void *arg2, boolean_t byteswap)
{ {
ztest_ds_t *zd = arg1; ztest_ds_t *zd = arg1;
lr_create_t *lr = arg2; lr_create_t *lrc = arg2;
char *name = (void *)(lr + 1); /* name follows lr */ _lr_create_t *lr = &lrc->lr_create;
char *name = (char *)&lrc->lr_data[0]; /* name follows lr */
objset_t *os = zd->zd_os; objset_t *os = zd->zd_os;
ztest_block_tag_t *bbt; ztest_block_tag_t *bbt;
dmu_buf_t *db; dmu_buf_t *db;
@ -2043,7 +2044,7 @@ ztest_replay_create(void *arg1, void *arg2, boolean_t byteswap)
VERIFY0(zap_add(os, lr->lr_doid, name, sizeof (uint64_t), 1, VERIFY0(zap_add(os, lr->lr_doid, name, sizeof (uint64_t), 1,
&lr->lr_foid, tx)); &lr->lr_foid, tx));
(void) ztest_log_create(zd, tx, lr); (void) ztest_log_create(zd, tx, lrc);
dmu_tx_commit(tx); dmu_tx_commit(tx);
@ -2055,7 +2056,7 @@ ztest_replay_remove(void *arg1, void *arg2, boolean_t byteswap)
{ {
ztest_ds_t *zd = arg1; ztest_ds_t *zd = arg1;
lr_remove_t *lr = arg2; lr_remove_t *lr = arg2;
char *name = (void *)(lr + 1); /* name follows lr */ char *name = (char *)&lr->lr_data[0]; /* name follows lr */
objset_t *os = zd->zd_os; objset_t *os = zd->zd_os;
dmu_object_info_t doi; dmu_object_info_t doi;
dmu_tx_t *tx; dmu_tx_t *tx;
@ -2109,9 +2110,9 @@ ztest_replay_write(void *arg1, void *arg2, boolean_t byteswap)
ztest_ds_t *zd = arg1; ztest_ds_t *zd = arg1;
lr_write_t *lr = arg2; lr_write_t *lr = arg2;
objset_t *os = zd->zd_os; objset_t *os = zd->zd_os;
void *data = lr + 1; /* data follows lr */ uint8_t *data = &lr->lr_data[0]; /* data follows lr */
uint64_t offset, length; uint64_t offset, length;
ztest_block_tag_t *bt = data; ztest_block_tag_t *bt = (ztest_block_tag_t *)data;
ztest_block_tag_t *bbt; ztest_block_tag_t *bbt;
uint64_t gen, txg, lrtxg, crtxg; uint64_t gen, txg, lrtxg, crtxg;
dmu_object_info_t doi; dmu_object_info_t doi;
@ -2563,7 +2564,8 @@ ztest_create(ztest_ds_t *zd, ztest_od_t *od, int count)
continue; continue;
} }
lr_create_t *lr = ztest_lr_alloc(sizeof (*lr), od->od_name); lr_create_t *lrc = ztest_lr_alloc(sizeof (*lrc), od->od_name);
_lr_create_t *lr = &lrc->lr_create;
lr->lr_doid = od->od_dir; lr->lr_doid = od->od_dir;
lr->lr_foid = 0; /* 0 to allocate, > 0 to claim */ lr->lr_foid = 0; /* 0 to allocate, > 0 to claim */
@ -2647,7 +2649,7 @@ ztest_write(ztest_ds_t *zd, uint64_t object, uint64_t offset, uint64_t size,
lr->lr_blkoff = 0; lr->lr_blkoff = 0;
BP_ZERO(&lr->lr_blkptr); BP_ZERO(&lr->lr_blkptr);
memcpy(lr + 1, data, size); memcpy(&lr->lr_data[0], data, size);
error = ztest_replay_write(zd, lr, B_FALSE); error = ztest_replay_write(zd, lr, B_FALSE);

View File

@ -248,6 +248,7 @@ typedef struct {
uint32_t lr_attr_masksize; /* number of elements in array */ uint32_t lr_attr_masksize; /* number of elements in array */
uint32_t lr_attr_bitmap; /* First entry of array */ uint32_t lr_attr_bitmap; /* First entry of array */
/* remainder of array and additional lr_attr_end_t fields */ /* remainder of array and additional lr_attr_end_t fields */
uint8_t lr_attr_data[];
} lr_attr_t; } lr_attr_t;
/* /*
@ -264,9 +265,14 @@ typedef struct {
uint64_t lr_gen; /* generation (txg of creation) */ uint64_t lr_gen; /* generation (txg of creation) */
uint64_t lr_crtime[2]; /* creation time */ uint64_t lr_crtime[2]; /* creation time */
uint64_t lr_rdev; /* rdev of object to create */ uint64_t lr_rdev; /* rdev of object to create */
} _lr_create_t;
typedef struct {
_lr_create_t lr_create; /* common create portion */
/* name of object to create follows this */ /* name of object to create follows this */
/* for symlinks, link content follows name */ /* for symlinks, link content follows name */
/* for creates with xvattr data, the name follows the xvattr info */ /* for creates with xvattr data, the name follows the xvattr info */
uint8_t lr_data[];
} lr_create_t; } lr_create_t;
/* /*
@ -293,18 +299,20 @@ typedef struct {
* and group will be in lr_create. Name follows ACL data. * and group will be in lr_create. Name follows ACL data.
*/ */
typedef struct { typedef struct {
lr_create_t lr_create; /* common create portion */ _lr_create_t lr_create; /* common create portion */
uint64_t lr_aclcnt; /* number of ACEs in ACL */ uint64_t lr_aclcnt; /* number of ACEs in ACL */
uint64_t lr_domcnt; /* number of unique domains */ uint64_t lr_domcnt; /* number of unique domains */
uint64_t lr_fuidcnt; /* number of real fuids */ uint64_t lr_fuidcnt; /* number of real fuids */
uint64_t lr_acl_bytes; /* number of bytes in ACL */ uint64_t lr_acl_bytes; /* number of bytes in ACL */
uint64_t lr_acl_flags; /* ACL flags */ uint64_t lr_acl_flags; /* ACL flags */
uint8_t lr_data[];
} lr_acl_create_t; } lr_acl_create_t;
typedef struct { typedef struct {
lr_t lr_common; /* common portion of log record */ lr_t lr_common; /* common portion of log record */
uint64_t lr_doid; /* obj id of directory */ uint64_t lr_doid; /* obj id of directory */
/* name of object to remove follows this */ /* name of object to remove follows this */
uint8_t lr_data[];
} lr_remove_t; } lr_remove_t;
typedef struct { typedef struct {
@ -312,18 +320,24 @@ typedef struct {
uint64_t lr_doid; /* obj id of directory */ uint64_t lr_doid; /* obj id of directory */
uint64_t lr_link_obj; /* obj id of link */ uint64_t lr_link_obj; /* obj id of link */
/* name of object to link follows this */ /* name of object to link follows this */
uint8_t lr_data[];
} lr_link_t; } lr_link_t;
typedef struct { typedef struct {
lr_t lr_common; /* common portion of log record */ lr_t lr_common; /* common portion of log record */
uint64_t lr_sdoid; /* obj id of source directory */ uint64_t lr_sdoid; /* obj id of source directory */
uint64_t lr_tdoid; /* obj id of target directory */ uint64_t lr_tdoid; /* obj id of target directory */
} _lr_rename_t;
typedef struct {
_lr_rename_t lr_rename; /* common rename portion */
/* 2 strings: names of source and destination follow this */ /* 2 strings: names of source and destination follow this */
uint8_t lr_data[];
} lr_rename_t; } lr_rename_t;
typedef struct { typedef struct {
lr_rename_t lr_rename; /* common rename portion */ _lr_rename_t lr_rename; /* common rename portion */
/* members related to the whiteout file (based on lr_create_t) */ /* members related to the whiteout file (based on _lr_create_t) */
uint64_t lr_wfoid; /* obj id of the new whiteout file */ uint64_t lr_wfoid; /* obj id of the new whiteout file */
uint64_t lr_wmode; /* mode of object */ uint64_t lr_wmode; /* mode of object */
uint64_t lr_wuid; /* uid of whiteout */ uint64_t lr_wuid; /* uid of whiteout */
@ -332,6 +346,7 @@ typedef struct {
uint64_t lr_wcrtime[2]; /* creation time */ uint64_t lr_wcrtime[2]; /* creation time */
uint64_t lr_wrdev; /* always makedev(0, 0) */ uint64_t lr_wrdev; /* always makedev(0, 0) */
/* 2 strings: names of source and destination follow this */ /* 2 strings: names of source and destination follow this */
uint8_t lr_data[];
} lr_rename_whiteout_t; } lr_rename_whiteout_t;
typedef struct { typedef struct {
@ -342,6 +357,7 @@ typedef struct {
uint64_t lr_blkoff; /* no longer used */ uint64_t lr_blkoff; /* no longer used */
blkptr_t lr_blkptr; /* spa block pointer for replay */ blkptr_t lr_blkptr; /* spa block pointer for replay */
/* write data will follow for small writes */ /* write data will follow for small writes */
uint8_t lr_data[];
} lr_write_t; } lr_write_t;
typedef struct { typedef struct {
@ -362,6 +378,7 @@ typedef struct {
uint64_t lr_atime[2]; /* access time */ uint64_t lr_atime[2]; /* access time */
uint64_t lr_mtime[2]; /* modification time */ uint64_t lr_mtime[2]; /* modification time */
/* optional attribute lr_attr_t may be here */ /* optional attribute lr_attr_t may be here */
uint8_t lr_data[];
} lr_setattr_t; } lr_setattr_t;
typedef struct { typedef struct {
@ -369,6 +386,7 @@ typedef struct {
uint64_t lr_foid; /* file object to change attributes */ uint64_t lr_foid; /* file object to change attributes */
uint64_t lr_size; uint64_t lr_size;
/* xattr name and value follows */ /* xattr name and value follows */
uint8_t lr_data[];
} lr_setsaxattr_t; } lr_setsaxattr_t;
typedef struct { typedef struct {
@ -376,6 +394,7 @@ typedef struct {
uint64_t lr_foid; /* obj id of file */ uint64_t lr_foid; /* obj id of file */
uint64_t lr_aclcnt; /* number of acl entries */ uint64_t lr_aclcnt; /* number of acl entries */
/* lr_aclcnt number of ace_t entries follow this */ /* lr_aclcnt number of ace_t entries follow this */
uint8_t lr_data[];
} lr_acl_v0_t; } lr_acl_v0_t;
typedef struct { typedef struct {
@ -387,6 +406,7 @@ typedef struct {
uint64_t lr_acl_bytes; /* number of bytes in ACL */ uint64_t lr_acl_bytes; /* number of bytes in ACL */
uint64_t lr_acl_flags; /* ACL flags */ uint64_t lr_acl_flags; /* ACL flags */
/* lr_acl_bytes number of variable sized ace's follows */ /* lr_acl_bytes number of variable sized ace's follows */
uint8_t lr_data[];
} lr_acl_t; } lr_acl_t;
typedef struct { typedef struct {
@ -396,8 +416,8 @@ typedef struct {
uint64_t lr_length; /* length of the blocks to clone */ uint64_t lr_length; /* length of the blocks to clone */
uint64_t lr_blksz; /* file's block size */ uint64_t lr_blksz; /* file's block size */
uint64_t lr_nbps; /* number of block pointers */ uint64_t lr_nbps; /* number of block pointers */
blkptr_t lr_bps[];
/* block pointers of the blocks to clone follows */ /* block pointers of the blocks to clone follows */
blkptr_t lr_bps[];
} lr_clone_range_t; } lr_clone_range_t;
/* /*
@ -448,7 +468,7 @@ typedef struct itx {
uint64_t itx_oid; /* object id */ uint64_t itx_oid; /* object id */
uint64_t itx_gen; /* gen number for zfs_get_data */ uint64_t itx_gen; /* gen number for zfs_get_data */
lr_t itx_lr; /* common part of log record */ lr_t itx_lr; /* common part of log record */
/* followed by type-specific part of lr_xx_t and its immediate data */ uint8_t itx_lr_data[]; /* type-specific part of lr_xx_t */
} itx_t; } itx_t;
/* /*

View File

@ -300,14 +300,13 @@ zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
zfs_fuid_info_t *fuidp, vattr_t *vap) zfs_fuid_info_t *fuidp, vattr_t *vap)
{ {
itx_t *itx; itx_t *itx;
lr_create_t *lr; _lr_create_t *lr;
lr_acl_create_t *lracl; lr_acl_create_t *lracl = NULL;
uint8_t *lrdata;
size_t aclsize = 0; size_t aclsize = 0;
size_t xvatsize = 0; size_t xvatsize = 0;
size_t txsize; size_t txsize;
xvattr_t *xvap = (xvattr_t *)vap; xvattr_t *xvap = (xvattr_t *)vap;
void *end;
size_t lrsize;
size_t namesize = strlen(name) + 1; size_t namesize = strlen(name) + 1;
size_t fuidsz = 0; size_t fuidsz = 0;
@ -329,18 +328,21 @@ zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
if ((int)txtype == TX_CREATE_ATTR || (int)txtype == TX_MKDIR_ATTR || if ((int)txtype == TX_CREATE_ATTR || (int)txtype == TX_MKDIR_ATTR ||
(int)txtype == TX_CREATE || (int)txtype == TX_MKDIR || (int)txtype == TX_CREATE || (int)txtype == TX_MKDIR ||
(int)txtype == TX_MKXATTR) { (int)txtype == TX_MKXATTR) {
txsize = sizeof (*lr) + namesize + fuidsz + xvatsize; txsize = sizeof (lr_create_t) + namesize + fuidsz + xvatsize;
lrsize = sizeof (*lr); itx = zil_itx_create(txtype, txsize);
lr_create_t *lrc = (lr_create_t *)&itx->itx_lr;
lrdata = &lrc->lr_data[0];
} else { } else {
txsize = txsize =
sizeof (lr_acl_create_t) + namesize + fuidsz + sizeof (lr_acl_create_t) + namesize + fuidsz +
ZIL_ACE_LENGTH(aclsize) + xvatsize; ZIL_ACE_LENGTH(aclsize) + xvatsize;
lrsize = sizeof (lr_acl_create_t); itx = zil_itx_create(txtype, txsize);
lracl = (lr_acl_create_t *)&itx->itx_lr;
lrdata = &lracl->lr_data[0];
} }
itx = zil_itx_create(txtype, txsize);
lr = (lr_create_t *)&itx->itx_lr; lr = (_lr_create_t *)&itx->itx_lr;
lr->lr_doid = dzp->z_id; lr->lr_doid = dzp->z_id;
lr->lr_foid = zp->z_id; lr->lr_foid = zp->z_id;
/* Store dnode slot count in 8 bits above object id. */ /* Store dnode slot count in 8 bits above object id. */
@ -369,16 +371,14 @@ zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
* Fill in xvattr info if any * Fill in xvattr info if any
*/ */
if (vap->va_mask & ATTR_XVATTR) { if (vap->va_mask & ATTR_XVATTR) {
zfs_log_xvattr((lr_attr_t *)((caddr_t)lr + lrsize), xvap); zfs_log_xvattr((lr_attr_t *)lrdata, xvap);
end = (caddr_t)lr + lrsize + xvatsize; lrdata = &lrdata[xvatsize];
} else {
end = (caddr_t)lr + lrsize;
} }
/* Now fill in any ACL info */ /* Now fill in any ACL info */
if (vsecp) { if (vsecp) {
lracl = (lr_acl_create_t *)&itx->itx_lr; ASSERT3P(lracl, !=, NULL);
lracl->lr_aclcnt = vsecp->vsa_aclcnt; lracl->lr_aclcnt = vsecp->vsa_aclcnt;
lracl->lr_acl_bytes = aclsize; lracl->lr_acl_bytes = aclsize;
lracl->lr_domcnt = fuidp ? fuidp->z_domain_cnt : 0; lracl->lr_domcnt = fuidp ? fuidp->z_domain_cnt : 0;
@ -388,19 +388,19 @@ zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
else else
lracl->lr_acl_flags = 0; lracl->lr_acl_flags = 0;
memcpy(end, vsecp->vsa_aclentp, aclsize); memcpy(lrdata, vsecp->vsa_aclentp, aclsize);
end = (caddr_t)end + ZIL_ACE_LENGTH(aclsize); lrdata = &lrdata[ZIL_ACE_LENGTH(aclsize)];
} }
/* drop in FUID info */ /* drop in FUID info */
if (fuidp) { if (fuidp) {
end = zfs_log_fuid_ids(fuidp, end); lrdata = zfs_log_fuid_ids(fuidp, lrdata);
end = zfs_log_fuid_domains(fuidp, end); lrdata = zfs_log_fuid_domains(fuidp, lrdata);
} }
/* /*
* Now place file name in log record * Now place file name in log record
*/ */
memcpy(end, name, namesize); memcpy(lrdata, name, namesize);
zil_itx_assign(zilog, itx, tx); zil_itx_assign(zilog, itx, tx);
} }
@ -422,7 +422,7 @@ zfs_log_remove(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
itx = zil_itx_create(txtype, sizeof (*lr) + namesize); itx = zil_itx_create(txtype, sizeof (*lr) + namesize);
lr = (lr_remove_t *)&itx->itx_lr; lr = (lr_remove_t *)&itx->itx_lr;
lr->lr_doid = dzp->z_id; lr->lr_doid = dzp->z_id;
memcpy(lr + 1, name, namesize); memcpy(&lr->lr_data[0], name, namesize);
itx->itx_oid = foid; itx->itx_oid = foid;
@ -458,7 +458,7 @@ zfs_log_link(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
lr = (lr_link_t *)&itx->itx_lr; lr = (lr_link_t *)&itx->itx_lr;
lr->lr_doid = dzp->z_id; lr->lr_doid = dzp->z_id;
lr->lr_link_obj = zp->z_id; lr->lr_link_obj = zp->z_id;
memcpy(lr + 1, name, namesize); memcpy(&lr->lr_data[0], name, namesize);
zil_itx_assign(zilog, itx, tx); zil_itx_assign(zilog, itx, tx);
} }
@ -471,15 +471,17 @@ zfs_log_symlink(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
znode_t *dzp, znode_t *zp, const char *name, const char *link) znode_t *dzp, znode_t *zp, const char *name, const char *link)
{ {
itx_t *itx; itx_t *itx;
lr_create_t *lr; _lr_create_t *lr;
lr_create_t *lrc;
size_t namesize = strlen(name) + 1; size_t namesize = strlen(name) + 1;
size_t linksize = strlen(link) + 1; size_t linksize = strlen(link) + 1;
if (zil_replaying(zilog, tx)) if (zil_replaying(zilog, tx))
return; return;
itx = zil_itx_create(txtype, sizeof (*lr) + namesize + linksize); itx = zil_itx_create(txtype, sizeof (*lrc) + namesize + linksize);
lr = (lr_create_t *)&itx->itx_lr; lrc = (lr_create_t *)&itx->itx_lr;
lr = &lrc->lr_create;
lr->lr_doid = dzp->z_id; lr->lr_doid = dzp->z_id;
lr->lr_foid = zp->z_id; lr->lr_foid = zp->z_id;
lr->lr_uid = KUID_TO_SUID(ZTOUID(zp)); lr->lr_uid = KUID_TO_SUID(ZTOUID(zp));
@ -489,8 +491,8 @@ zfs_log_symlink(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
sizeof (uint64_t)); sizeof (uint64_t));
(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(ZTOZSB(zp)), (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(ZTOZSB(zp)),
lr->lr_crtime, sizeof (uint64_t) * 2); lr->lr_crtime, sizeof (uint64_t) * 2);
memcpy((char *)(lr + 1), name, namesize); memcpy(&lrc->lr_data[0], name, namesize);
memcpy((char *)(lr + 1) + namesize, link, linksize); memcpy(&lrc->lr_data[namesize], link, linksize);
zil_itx_assign(zilog, itx, tx); zil_itx_assign(zilog, itx, tx);
} }
@ -500,7 +502,8 @@ do_zfs_log_rename(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, znode_t *sdzp,
const char *sname, znode_t *tdzp, const char *dname, znode_t *szp) const char *sname, znode_t *tdzp, const char *dname, znode_t *szp)
{ {
itx_t *itx; itx_t *itx;
lr_rename_t *lr; _lr_rename_t *lr;
lr_rename_t *lrr;
size_t snamesize = strlen(sname) + 1; size_t snamesize = strlen(sname) + 1;
size_t dnamesize = strlen(dname) + 1; size_t dnamesize = strlen(dname) + 1;
@ -508,11 +511,12 @@ do_zfs_log_rename(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, znode_t *sdzp,
return; return;
itx = zil_itx_create(txtype, sizeof (*lr) + snamesize + dnamesize); itx = zil_itx_create(txtype, sizeof (*lr) + snamesize + dnamesize);
lr = (lr_rename_t *)&itx->itx_lr; lrr = (lr_rename_t *)&itx->itx_lr;
lr = &lrr->lr_rename;
lr->lr_sdoid = sdzp->z_id; lr->lr_sdoid = sdzp->z_id;
lr->lr_tdoid = tdzp->z_id; lr->lr_tdoid = tdzp->z_id;
memcpy((char *)(lr + 1), sname, snamesize); memcpy(&lrr->lr_data[0], sname, snamesize);
memcpy((char *)(lr + 1) + snamesize, dname, dnamesize); memcpy(&lrr->lr_data[snamesize], dname, dnamesize);
itx->itx_oid = szp->z_id; itx->itx_oid = szp->z_id;
zil_itx_assign(zilog, itx, tx); zil_itx_assign(zilog, itx, tx);
@ -590,8 +594,8 @@ zfs_log_rename_whiteout(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
(void) sa_lookup(wzp->z_sa_hdl, SA_ZPL_RDEV(ZTOZSB(wzp)), &lr->lr_wrdev, (void) sa_lookup(wzp->z_sa_hdl, SA_ZPL_RDEV(ZTOZSB(wzp)), &lr->lr_wrdev,
sizeof (lr->lr_wrdev)); sizeof (lr->lr_wrdev));
memcpy((char *)(lr + 1), sname, snamesize); memcpy(&lr->lr_data[0], sname, snamesize);
memcpy((char *)(lr + 1) + snamesize, dname, dnamesize); memcpy(&lr->lr_data[snamesize], dname, dnamesize);
itx->itx_oid = szp->z_id; itx->itx_oid = szp->z_id;
zil_itx_assign(zilog, itx, tx); zil_itx_assign(zilog, itx, tx);
@ -668,8 +672,8 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
if (wr_state == WR_COPIED) { if (wr_state == WR_COPIED) {
int err; int err;
DB_DNODE_ENTER(db); DB_DNODE_ENTER(db);
err = dmu_read_by_dnode(DB_DNODE(db), off, len, lr + 1, err = dmu_read_by_dnode(DB_DNODE(db), off, len,
DMU_READ_NO_PREFETCH); &lr->lr_data[0], DMU_READ_NO_PREFETCH);
DB_DNODE_EXIT(db); DB_DNODE_EXIT(db);
if (err != 0) { if (err != 0) {
zil_itx_destroy(itx); zil_itx_destroy(itx);
@ -741,7 +745,7 @@ zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype,
lr_setattr_t *lr; lr_setattr_t *lr;
xvattr_t *xvap = (xvattr_t *)vap; xvattr_t *xvap = (xvattr_t *)vap;
size_t recsize = sizeof (lr_setattr_t); size_t recsize = sizeof (lr_setattr_t);
void *start; uint8_t *start;
if (zil_replaying(zilog, tx) || zp->z_unlinked) if (zil_replaying(zilog, tx) || zp->z_unlinked)
return; return;
@ -775,10 +779,10 @@ zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype,
lr->lr_size = (uint64_t)vap->va_size; lr->lr_size = (uint64_t)vap->va_size;
ZFS_TIME_ENCODE(&vap->va_atime, lr->lr_atime); ZFS_TIME_ENCODE(&vap->va_atime, lr->lr_atime);
ZFS_TIME_ENCODE(&vap->va_mtime, lr->lr_mtime); ZFS_TIME_ENCODE(&vap->va_mtime, lr->lr_mtime);
start = (lr_setattr_t *)(lr + 1); start = &lr->lr_data[0];
if (vap->va_mask & ATTR_XVATTR) { if (vap->va_mask & ATTR_XVATTR) {
zfs_log_xvattr((lr_attr_t *)start, xvap); zfs_log_xvattr((lr_attr_t *)start, xvap);
start = (caddr_t)start + ZIL_XVAT_SIZE(xvap->xva_mapsize); start = &lr->lr_data[ZIL_XVAT_SIZE(xvap->xva_mapsize)];
} }
/* /*
@ -802,7 +806,6 @@ zfs_log_setsaxattr(zilog_t *zilog, dmu_tx_t *tx, int txtype,
itx_t *itx; itx_t *itx;
lr_setsaxattr_t *lr; lr_setsaxattr_t *lr;
size_t recsize = sizeof (lr_setsaxattr_t); size_t recsize = sizeof (lr_setsaxattr_t);
void *xattrstart;
int namelen; int namelen;
if (zil_replaying(zilog, tx) || zp->z_unlinked) if (zil_replaying(zilog, tx) || zp->z_unlinked)
@ -813,10 +816,9 @@ zfs_log_setsaxattr(zilog_t *zilog, dmu_tx_t *tx, int txtype,
itx = zil_itx_create(txtype, recsize); itx = zil_itx_create(txtype, recsize);
lr = (lr_setsaxattr_t *)&itx->itx_lr; lr = (lr_setsaxattr_t *)&itx->itx_lr;
lr->lr_foid = zp->z_id; lr->lr_foid = zp->z_id;
xattrstart = (char *)(lr + 1); memcpy(&lr->lr_data[0], name, namelen);
memcpy(xattrstart, name, namelen);
if (value != NULL) { if (value != NULL) {
memcpy((char *)xattrstart + namelen, value, size); memcpy(&lr->lr_data[namelen], value, size);
lr->lr_size = size; lr->lr_size = size;
} else { } else {
lr->lr_size = 0; lr->lr_size = 0;
@ -874,13 +876,13 @@ zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp,
if (txtype == TX_ACL_V0) { if (txtype == TX_ACL_V0) {
lrv0 = (lr_acl_v0_t *)lr; lrv0 = (lr_acl_v0_t *)lr;
memcpy(lrv0 + 1, vsecp->vsa_aclentp, aclbytes); memcpy(&lrv0->lr_data[0], vsecp->vsa_aclentp, aclbytes);
} else { } else {
void *start = (ace_t *)(lr + 1); uint8_t *start = &lr->lr_data[0];
memcpy(start, vsecp->vsa_aclentp, aclbytes); memcpy(start, vsecp->vsa_aclentp, aclbytes);
start = (caddr_t)start + ZIL_ACE_LENGTH(aclbytes); start = &lr->lr_data[ZIL_ACE_LENGTH(aclbytes)];
if (fuidp) { if (fuidp) {
start = zfs_log_fuid_ids(fuidp, start); start = zfs_log_fuid_ids(fuidp, start);

View File

@ -293,16 +293,16 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap)
{ {
zfsvfs_t *zfsvfs = arg1; zfsvfs_t *zfsvfs = arg1;
lr_acl_create_t *lracl = arg2; lr_acl_create_t *lracl = arg2;
_lr_create_t *lr = &lracl->lr_create;
char *name = NULL; /* location determined later */ char *name = NULL; /* location determined later */
lr_create_t *lr = (lr_create_t *)lracl;
znode_t *dzp; znode_t *dzp;
znode_t *zp; znode_t *zp;
xvattr_t xva; xvattr_t xva;
int vflg = 0; int vflg = 0;
vsecattr_t vsec = { 0 }; vsecattr_t vsec = { 0 };
lr_attr_t *lrattr; lr_attr_t *lrattr;
void *aclstart; uint8_t *aclstart;
void *fuidstart; uint8_t *fuidstart;
size_t xvatlen = 0; size_t xvatlen = 0;
uint64_t txtype; uint64_t txtype;
uint64_t objid; uint64_t objid;
@ -316,17 +316,18 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap)
byteswap_uint64_array(lracl, sizeof (*lracl)); byteswap_uint64_array(lracl, sizeof (*lracl));
if (txtype == TX_CREATE_ACL_ATTR || if (txtype == TX_CREATE_ACL_ATTR ||
txtype == TX_MKDIR_ACL_ATTR) { txtype == TX_MKDIR_ACL_ATTR) {
lrattr = (lr_attr_t *)(caddr_t)(lracl + 1); lrattr = (lr_attr_t *)&lracl->lr_data[0];
zfs_replay_swap_attrs(lrattr); zfs_replay_swap_attrs(lrattr);
xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize); xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize);
} }
aclstart = (caddr_t)(lracl + 1) + xvatlen; aclstart = &lracl->lr_data[xvatlen];
zfs_ace_byteswap(aclstart, lracl->lr_acl_bytes, B_FALSE); zfs_ace_byteswap(aclstart, lracl->lr_acl_bytes, B_FALSE);
/* swap fuids */ /* swap fuids */
if (lracl->lr_fuidcnt) { if (lracl->lr_fuidcnt) {
byteswap_uint64_array((caddr_t)aclstart + byteswap_uint64_array(
ZIL_ACE_LENGTH(lracl->lr_acl_bytes), &aclstart[ZIL_ACE_LENGTH(lracl->lr_acl_bytes)],
lracl->lr_fuidcnt * sizeof (uint64_t)); lracl->lr_fuidcnt * sizeof (uint64_t));
} }
} }
@ -361,28 +362,27 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap)
vflg |= FIGNORECASE; vflg |= FIGNORECASE;
switch (txtype) { switch (txtype) {
case TX_CREATE_ACL: case TX_CREATE_ACL:
aclstart = (caddr_t)(lracl + 1); aclstart = &lracl->lr_data[0];
fuidstart = (caddr_t)aclstart + fuidstart = &aclstart[ZIL_ACE_LENGTH(lracl->lr_acl_bytes)];
ZIL_ACE_LENGTH(lracl->lr_acl_bytes);
zfsvfs->z_fuid_replay = zfs_replay_fuids(fuidstart, zfsvfs->z_fuid_replay = zfs_replay_fuids(fuidstart,
(void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt, (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt,
lr->lr_uid, lr->lr_gid); lr->lr_uid, lr->lr_gid);
zfs_fallthrough; zfs_fallthrough;
case TX_CREATE_ACL_ATTR: case TX_CREATE_ACL_ATTR:
if (name == NULL) { if (name == NULL) {
lrattr = (lr_attr_t *)(caddr_t)(lracl + 1); lrattr = (lr_attr_t *)&lracl->lr_data[0];
xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize); xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize);
xva.xva_vattr.va_mask |= ATTR_XVATTR; xva.xva_vattr.va_mask |= ATTR_XVATTR;
zfs_replay_xvattr(lrattr, &xva); zfs_replay_xvattr(lrattr, &xva);
} }
vsec.vsa_mask = VSA_ACE | VSA_ACE_ACLFLAGS; vsec.vsa_mask = VSA_ACE | VSA_ACE_ACLFLAGS;
vsec.vsa_aclentp = (caddr_t)(lracl + 1) + xvatlen; vsec.vsa_aclentp = &lracl->lr_data[xvatlen];
vsec.vsa_aclcnt = lracl->lr_aclcnt; vsec.vsa_aclcnt = lracl->lr_aclcnt;
vsec.vsa_aclentsz = lracl->lr_acl_bytes; vsec.vsa_aclentsz = lracl->lr_acl_bytes;
vsec.vsa_aclflags = lracl->lr_acl_flags; vsec.vsa_aclflags = lracl->lr_acl_flags;
if (zfsvfs->z_fuid_replay == NULL) { if (zfsvfs->z_fuid_replay == NULL) {
fuidstart = (caddr_t)(lracl + 1) + xvatlen + fuidstart = &lracl->lr_data[xvatlen +
ZIL_ACE_LENGTH(lracl->lr_acl_bytes); ZIL_ACE_LENGTH(lracl->lr_acl_bytes)];
zfsvfs->z_fuid_replay = zfsvfs->z_fuid_replay =
zfs_replay_fuids(fuidstart, zfs_replay_fuids(fuidstart,
(void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt, (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt,
@ -398,9 +398,8 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap)
#endif #endif
break; break;
case TX_MKDIR_ACL: case TX_MKDIR_ACL:
aclstart = (caddr_t)(lracl + 1); aclstart = &lracl->lr_data[0];
fuidstart = (caddr_t)aclstart + fuidstart = &aclstart[ZIL_ACE_LENGTH(lracl->lr_acl_bytes)];
ZIL_ACE_LENGTH(lracl->lr_acl_bytes);
zfsvfs->z_fuid_replay = zfs_replay_fuids(fuidstart, zfsvfs->z_fuid_replay = zfs_replay_fuids(fuidstart,
(void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt, (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt,
lr->lr_uid, lr->lr_gid); lr->lr_uid, lr->lr_gid);
@ -412,13 +411,13 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap)
zfs_replay_xvattr(lrattr, &xva); zfs_replay_xvattr(lrattr, &xva);
} }
vsec.vsa_mask = VSA_ACE | VSA_ACE_ACLFLAGS; vsec.vsa_mask = VSA_ACE | VSA_ACE_ACLFLAGS;
vsec.vsa_aclentp = (caddr_t)(lracl + 1) + xvatlen; vsec.vsa_aclentp = &lracl->lr_data[xvatlen];
vsec.vsa_aclcnt = lracl->lr_aclcnt; vsec.vsa_aclcnt = lracl->lr_aclcnt;
vsec.vsa_aclentsz = lracl->lr_acl_bytes; vsec.vsa_aclentsz = lracl->lr_acl_bytes;
vsec.vsa_aclflags = lracl->lr_acl_flags; vsec.vsa_aclflags = lracl->lr_acl_flags;
if (zfsvfs->z_fuid_replay == NULL) { if (zfsvfs->z_fuid_replay == NULL) {
fuidstart = (caddr_t)(lracl + 1) + xvatlen + fuidstart = &lracl->lr_data[xvatlen +
ZIL_ACE_LENGTH(lracl->lr_acl_bytes); ZIL_ACE_LENGTH(lracl->lr_acl_bytes)];
zfsvfs->z_fuid_replay = zfsvfs->z_fuid_replay =
zfs_replay_fuids(fuidstart, zfs_replay_fuids(fuidstart,
(void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt, (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt,
@ -456,14 +455,14 @@ static int
zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap) zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap)
{ {
zfsvfs_t *zfsvfs = arg1; zfsvfs_t *zfsvfs = arg1;
lr_create_t *lr = arg2; lr_create_t *lrc = arg2;
_lr_create_t *lr = &lrc->lr_create;
char *name = NULL; /* location determined later */ char *name = NULL; /* location determined later */
char *link; /* symlink content follows name */ char *link; /* symlink content follows name */
znode_t *dzp; znode_t *dzp;
znode_t *zp = NULL; znode_t *zp = NULL;
xvattr_t xva; xvattr_t xva;
int vflg = 0; int vflg = 0;
size_t lrsize = sizeof (lr_create_t);
lr_attr_t *lrattr; lr_attr_t *lrattr;
void *start; void *start;
size_t xvatlen; size_t xvatlen;
@ -476,9 +475,9 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap)
txtype = (lr->lr_common.lrc_txtype & ~TX_CI); txtype = (lr->lr_common.lrc_txtype & ~TX_CI);
if (byteswap) { if (byteswap) {
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lrc, sizeof (*lrc));
if (txtype == TX_CREATE_ATTR || txtype == TX_MKDIR_ATTR) if (txtype == TX_CREATE_ATTR || txtype == TX_MKDIR_ATTR)
zfs_replay_swap_attrs((lr_attr_t *)(lr + 1)); zfs_replay_swap_attrs((lr_attr_t *)&lrc->lr_data[0]);
} }
@ -520,7 +519,7 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap)
if (txtype != TX_SYMLINK && if (txtype != TX_SYMLINK &&
txtype != TX_MKDIR_ATTR && txtype != TX_MKDIR_ATTR &&
txtype != TX_CREATE_ATTR) { txtype != TX_CREATE_ATTR) {
start = (lr + 1); start = (void *)&lrc->lr_data[0];
zfsvfs->z_fuid_replay = zfsvfs->z_fuid_replay =
zfs_replay_fuid_domain(start, &start, zfs_replay_fuid_domain(start, &start,
lr->lr_uid, lr->lr_gid); lr->lr_uid, lr->lr_gid);
@ -528,10 +527,10 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap)
switch (txtype) { switch (txtype) {
case TX_CREATE_ATTR: case TX_CREATE_ATTR:
lrattr = (lr_attr_t *)(caddr_t)(lr + 1); lrattr = (lr_attr_t *)&lrc->lr_data[0];
xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize); xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize);
zfs_replay_xvattr((lr_attr_t *)((caddr_t)lr + lrsize), &xva); zfs_replay_xvattr(lrattr, &xva);
start = (caddr_t)(lr + 1) + xvatlen; start = (void *)&lrc->lr_data[xvatlen];
zfsvfs->z_fuid_replay = zfsvfs->z_fuid_replay =
zfs_replay_fuid_domain(start, &start, zfs_replay_fuid_domain(start, &start,
lr->lr_uid, lr->lr_gid); lr->lr_uid, lr->lr_gid);
@ -551,10 +550,10 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap)
#endif #endif
break; break;
case TX_MKDIR_ATTR: case TX_MKDIR_ATTR:
lrattr = (lr_attr_t *)(caddr_t)(lr + 1); lrattr = (lr_attr_t *)&lrc->lr_data[0];
xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize); xvatlen = ZIL_XVAT_SIZE(lrattr->lr_attr_masksize);
zfs_replay_xvattr((lr_attr_t *)((caddr_t)lr + lrsize), &xva); zfs_replay_xvattr(lrattr, &xva);
start = (caddr_t)(lr + 1) + xvatlen; start = &lrc->lr_data[xvatlen];
zfsvfs->z_fuid_replay = zfsvfs->z_fuid_replay =
zfs_replay_fuid_domain(start, &start, zfs_replay_fuid_domain(start, &start,
lr->lr_uid, lr->lr_gid); lr->lr_uid, lr->lr_gid);
@ -563,7 +562,7 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap)
case TX_MKDIR: case TX_MKDIR:
if (name == NULL) if (name == NULL)
name = (char *)(lr + 1); name = (char *)&lrc->lr_data[0];
#if defined(__linux__) #if defined(__linux__)
error = zfs_mkdir(dzp, name, &xva.xva_vattr, error = zfs_mkdir(dzp, name, &xva.xva_vattr,
@ -578,8 +577,8 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap)
error = zfs_make_xattrdir(dzp, &xva.xva_vattr, &zp, kcred); error = zfs_make_xattrdir(dzp, &xva.xva_vattr, &zp, kcred);
break; break;
case TX_SYMLINK: case TX_SYMLINK:
name = (char *)(lr + 1); name = &lrc->lr_data[0];
link = name + strlen(name) + 1; link = &lrc->lr_data[strlen(name) + 1];
#if defined(__linux__) #if defined(__linux__)
error = zfs_symlink(dzp, name, &xva.xva_vattr, error = zfs_symlink(dzp, name, &xva.xva_vattr,
link, &zp, kcred, vflg, zfs_init_idmap); link, &zp, kcred, vflg, zfs_init_idmap);
@ -612,7 +611,7 @@ zfs_replay_remove(void *arg1, void *arg2, boolean_t byteswap)
{ {
zfsvfs_t *zfsvfs = arg1; zfsvfs_t *zfsvfs = arg1;
lr_remove_t *lr = arg2; lr_remove_t *lr = arg2;
char *name = (char *)(lr + 1); /* name follows lr_remove_t */ char *name = (char *)&lr->lr_data[0]; /* name follows lr_remove_t */
znode_t *dzp; znode_t *dzp;
int error; int error;
int vflg = 0; int vflg = 0;
@ -649,7 +648,7 @@ zfs_replay_link(void *arg1, void *arg2, boolean_t byteswap)
{ {
zfsvfs_t *zfsvfs = arg1; zfsvfs_t *zfsvfs = arg1;
lr_link_t *lr = arg2; lr_link_t *lr = arg2;
char *name = (char *)(lr + 1); /* name follows lr_link_t */ char *name = &lr->lr_data[0]; /* name follows lr_link_t */
znode_t *dzp, *zp; znode_t *dzp, *zp;
int error; int error;
int vflg = 0; int vflg = 0;
@ -678,7 +677,7 @@ zfs_replay_link(void *arg1, void *arg2, boolean_t byteswap)
} }
static int static int
do_zfs_replay_rename(zfsvfs_t *zfsvfs, lr_rename_t *lr, char *sname, do_zfs_replay_rename(zfsvfs_t *zfsvfs, _lr_rename_t *lr, char *sname,
char *tname, uint64_t rflags, vattr_t *wo_vap) char *tname, uint64_t rflags, vattr_t *wo_vap)
{ {
znode_t *sdzp, *tdzp; znode_t *sdzp, *tdzp;
@ -722,15 +721,17 @@ static int
zfs_replay_rename(void *arg1, void *arg2, boolean_t byteswap) zfs_replay_rename(void *arg1, void *arg2, boolean_t byteswap)
{ {
zfsvfs_t *zfsvfs = arg1; zfsvfs_t *zfsvfs = arg1;
lr_rename_t *lr = arg2; lr_rename_t *lrr = arg2;
_lr_rename_t *lr = &lrr->lr_rename;
ASSERT3U(lr->lr_common.lrc_reclen, >, sizeof (*lr)); ASSERT3U(lr->lr_common.lrc_reclen, >, sizeof (*lr));
if (byteswap) if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lrr, sizeof (*lrr));
char *sname = (char *)(lr + 1); /* sname and tname follow lr_rename_t */ /* sname and tname follow lr_rename_t */
char *tname = sname + strlen(sname) + 1; char *sname = (char *)&lrr->lr_data[0];
char *tname = (char *)&lrr->lr_data[strlen(sname)+1];
return (do_zfs_replay_rename(zfsvfs, lr, sname, tname, 0, NULL)); return (do_zfs_replay_rename(zfsvfs, lr, sname, tname, 0, NULL));
} }
@ -739,15 +740,17 @@ zfs_replay_rename_exchange(void *arg1, void *arg2, boolean_t byteswap)
{ {
#ifdef __linux__ #ifdef __linux__
zfsvfs_t *zfsvfs = arg1; zfsvfs_t *zfsvfs = arg1;
lr_rename_t *lr = arg2; lr_rename_t *lrr = arg2;
_lr_rename_t *lr = &lrr->lr_rename;
ASSERT3U(lr->lr_common.lrc_reclen, >, sizeof (*lr)); ASSERT3U(lr->lr_common.lrc_reclen, >, sizeof (*lr));
if (byteswap) if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lrr, sizeof (*lrr));
char *sname = (char *)(lr + 1); /* sname and tname follow lr_rename_t */ /* sname and tname follow lr_rename_t */
char *tname = sname + strlen(sname) + 1; char *sname = (char *)&lrr->lr_data[0];
char *tname = (char *)&lrr->lr_data[strlen(sname)+1];
return (do_zfs_replay_rename(zfsvfs, lr, sname, tname, RENAME_EXCHANGE, return (do_zfs_replay_rename(zfsvfs, lr, sname, tname, RENAME_EXCHANGE,
NULL)); NULL));
#else #else
@ -760,24 +763,26 @@ zfs_replay_rename_whiteout(void *arg1, void *arg2, boolean_t byteswap)
{ {
#ifdef __linux__ #ifdef __linux__
zfsvfs_t *zfsvfs = arg1; zfsvfs_t *zfsvfs = arg1;
lr_rename_whiteout_t *lr = arg2; lr_rename_whiteout_t *lrrw = arg2;
_lr_rename_t *lr = &lrrw->lr_rename;
int error; int error;
/* For the whiteout file. */ /* For the whiteout file. */
xvattr_t xva; xvattr_t xva;
uint64_t objid; uint64_t objid;
uint64_t dnodesize; uint64_t dnodesize;
ASSERT3U(lr->lr_rename.lr_common.lrc_reclen, >, sizeof (*lr)); ASSERT3U(lr->lr_common.lrc_reclen, >, sizeof (*lr));
if (byteswap) if (byteswap)
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lrrw, sizeof (*lrrw));
objid = LR_FOID_GET_OBJ(lr->lr_wfoid); objid = LR_FOID_GET_OBJ(lrrw->lr_wfoid);
dnodesize = LR_FOID_GET_SLOTS(lr->lr_wfoid) << DNODE_SHIFT; dnodesize = LR_FOID_GET_SLOTS(lrrw->lr_wfoid) << DNODE_SHIFT;
xva_init(&xva); xva_init(&xva);
zfs_init_vattr(&xva.xva_vattr, ATTR_MODE | ATTR_UID | ATTR_GID, zfs_init_vattr(&xva.xva_vattr, ATTR_MODE | ATTR_UID | ATTR_GID,
lr->lr_wmode, lr->lr_wuid, lr->lr_wgid, lr->lr_wrdev, objid); lrrw->lr_wmode, lrrw->lr_wuid, lrrw->lr_wgid, lrrw->lr_wrdev,
objid);
/* /*
* As with TX_CREATE, RENAME_WHITEOUT ends up in zfs_mknode(), which * As with TX_CREATE, RENAME_WHITEOUT ends up in zfs_mknode(), which
@ -786,8 +791,8 @@ zfs_replay_rename_whiteout(void *arg1, void *arg2, boolean_t byteswap)
* attributes, so we smuggle the values inside the vattr's otherwise * attributes, so we smuggle the values inside the vattr's otherwise
* unused va_ctime, va_nblocks, and va_fsid fields. * unused va_ctime, va_nblocks, and va_fsid fields.
*/ */
ZFS_TIME_DECODE(&xva.xva_vattr.va_ctime, lr->lr_wcrtime); ZFS_TIME_DECODE(&xva.xva_vattr.va_ctime, lrrw->lr_wcrtime);
xva.xva_vattr.va_nblocks = lr->lr_wgen; xva.xva_vattr.va_nblocks = lrrw->lr_wgen;
xva.xva_vattr.va_fsid = dnodesize; xva.xva_vattr.va_fsid = dnodesize;
error = dnode_try_claim(zfsvfs->z_os, objid, dnodesize >> DNODE_SHIFT); error = dnode_try_claim(zfsvfs->z_os, objid, dnodesize >> DNODE_SHIFT);
@ -795,9 +800,9 @@ zfs_replay_rename_whiteout(void *arg1, void *arg2, boolean_t byteswap)
return (error); return (error);
/* sname and tname follow lr_rename_whiteout_t */ /* sname and tname follow lr_rename_whiteout_t */
char *sname = (char *)(lr + 1); char *sname = (char *)&lrrw->lr_data[0];
char *tname = sname + strlen(sname) + 1; char *tname = (char *)&lrrw->lr_data[strlen(sname)+1];
return (do_zfs_replay_rename(zfsvfs, &lr->lr_rename, sname, tname, return (do_zfs_replay_rename(zfsvfs, lr, sname, tname,
RENAME_WHITEOUT, &xva.xva_vattr)); RENAME_WHITEOUT, &xva.xva_vattr));
#else #else
return (SET_ERROR(ENOTSUP)); return (SET_ERROR(ENOTSUP));
@ -809,7 +814,7 @@ zfs_replay_write(void *arg1, void *arg2, boolean_t byteswap)
{ {
zfsvfs_t *zfsvfs = arg1; zfsvfs_t *zfsvfs = arg1;
lr_write_t *lr = arg2; lr_write_t *lr = arg2;
char *data = (char *)(lr + 1); /* data follows lr_write_t */ char *data = &lr->lr_data[0]; /* data follows lr_write_t */
znode_t *zp; znode_t *zp;
int error; int error;
uint64_t eod, offset, length; uint64_t eod, offset, length;
@ -968,7 +973,7 @@ zfs_replay_setattr(void *arg1, void *arg2, boolean_t byteswap)
if ((lr->lr_mask & ATTR_XVATTR) && if ((lr->lr_mask & ATTR_XVATTR) &&
zfsvfs->z_version >= ZPL_VERSION_INITIAL) zfsvfs->z_version >= ZPL_VERSION_INITIAL)
zfs_replay_swap_attrs((lr_attr_t *)(lr + 1)); zfs_replay_swap_attrs((lr_attr_t *)&lr->lr_data[0]);
} }
if ((error = zfs_zget(zfsvfs, lr->lr_foid, &zp)) != 0) if ((error = zfs_zget(zfsvfs, lr->lr_foid, &zp)) != 0)
@ -987,11 +992,11 @@ zfs_replay_setattr(void *arg1, void *arg2, boolean_t byteswap)
* Fill in xvattr_t portions if necessary. * Fill in xvattr_t portions if necessary.
*/ */
start = (lr_setattr_t *)(lr + 1); start = (void *)&lr->lr_data[0];
if (vap->va_mask & ATTR_XVATTR) { if (vap->va_mask & ATTR_XVATTR) {
zfs_replay_xvattr((lr_attr_t *)start, &xva); zfs_replay_xvattr((lr_attr_t *)start, &xva);
start = (caddr_t)start + start = &lr->lr_data[
ZIL_XVAT_SIZE(((lr_attr_t *)start)->lr_attr_masksize); ZIL_XVAT_SIZE(((lr_attr_t *)start)->lr_attr_masksize)];
} else } else
xva.xva_vattr.va_mask &= ~ATTR_XVATTR; xva.xva_vattr.va_mask &= ~ATTR_XVATTR;
@ -1049,12 +1054,12 @@ zfs_replay_setsaxattr(void *arg1, void *arg2, boolean_t byteswap)
/* Get xattr name, value and size from log record */ /* Get xattr name, value and size from log record */
size = lr->lr_size; size = lr->lr_size;
name = (char *)(lr + 1); name = (char *)&lr->lr_data[0];
if (size == 0) { if (size == 0) {
value = NULL; value = NULL;
error = nvlist_remove(nvl, name, DATA_TYPE_BYTE_ARRAY); error = nvlist_remove(nvl, name, DATA_TYPE_BYTE_ARRAY);
} else { } else {
value = name + strlen(name) + 1; value = &lr->lr_data[strlen(name) + 1];
/* Limited to 32k to keep nvpair memory allocations small */ /* Limited to 32k to keep nvpair memory allocations small */
if (size > DXATTR_MAX_ENTRY_SIZE) { if (size > DXATTR_MAX_ENTRY_SIZE) {
error = SET_ERROR(EFBIG); error = SET_ERROR(EFBIG);
@ -1099,7 +1104,7 @@ zfs_replay_acl_v0(void *arg1, void *arg2, boolean_t byteswap)
{ {
zfsvfs_t *zfsvfs = arg1; zfsvfs_t *zfsvfs = arg1;
lr_acl_v0_t *lr = arg2; lr_acl_v0_t *lr = arg2;
ace_t *ace = (ace_t *)(lr + 1); /* ace array follows lr_acl_t */ ace_t *ace = (ace_t *)&lr->lr_data[0];
vsecattr_t vsa = {0}; vsecattr_t vsa = {0};
znode_t *zp; znode_t *zp;
int error; int error;
@ -1148,7 +1153,7 @@ zfs_replay_acl(void *arg1, void *arg2, boolean_t byteswap)
{ {
zfsvfs_t *zfsvfs = arg1; zfsvfs_t *zfsvfs = arg1;
lr_acl_t *lr = arg2; lr_acl_t *lr = arg2;
ace_t *ace = (ace_t *)(lr + 1); ace_t *ace = (ace_t *)&lr->lr_data[0];
vsecattr_t vsa = {0}; vsecattr_t vsa = {0};
znode_t *zp; znode_t *zp;
int error; int error;
@ -1160,8 +1165,8 @@ zfs_replay_acl(void *arg1, void *arg2, boolean_t byteswap)
byteswap_uint64_array(lr, sizeof (*lr)); byteswap_uint64_array(lr, sizeof (*lr));
zfs_ace_byteswap(ace, lr->lr_acl_bytes, B_FALSE); zfs_ace_byteswap(ace, lr->lr_acl_bytes, B_FALSE);
if (lr->lr_fuidcnt) { if (lr->lr_fuidcnt) {
byteswap_uint64_array((caddr_t)ace + byteswap_uint64_array(&lr->lr_data[
ZIL_ACE_LENGTH(lr->lr_acl_bytes), ZIL_ACE_LENGTH(lr->lr_acl_bytes)],
lr->lr_fuidcnt * sizeof (uint64_t)); lr->lr_fuidcnt * sizeof (uint64_t));
} }
} }
@ -1176,8 +1181,8 @@ zfs_replay_acl(void *arg1, void *arg2, boolean_t byteswap)
vsa.vsa_aclflags = lr->lr_acl_flags; vsa.vsa_aclflags = lr->lr_acl_flags;
if (lr->lr_fuidcnt) { if (lr->lr_fuidcnt) {
void *fuidstart = (caddr_t)ace + void *fuidstart = &lr->lr_data[
ZIL_ACE_LENGTH(lr->lr_acl_bytes); ZIL_ACE_LENGTH(lr->lr_acl_bytes)];
zfsvfs->z_fuid_replay = zfsvfs->z_fuid_replay =
zfs_replay_fuids(fuidstart, &fuidstart, zfs_replay_fuids(fuidstart, &fuidstart,