mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	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:
		
							parent
							
								
									56608daa8d
								
							
						
					
					
						commit
						30ea442961
					
				| @ -64,7 +64,8 @@ static void | ||||
| zil_prt_rec_create(zilog_t *zilog, int txtype, const void *arg) | ||||
| { | ||||
| 	(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]; | ||||
| 	char *name, *link; | ||||
| 	lr_attr_t *lrattr; | ||||
| @ -121,7 +122,8 @@ static void | ||||
| zil_prt_rec_rename(zilog_t *zilog, int txtype, const void *arg) | ||||
| { | ||||
| 	(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 *tnm = snm + strlen(snm) + 1; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										24
									
								
								cmd/ztest.c
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								cmd/ztest.c
									
									
									
									
									
								
							| @ -1861,7 +1861,7 @@ ztest_verify_unused_bonus(dmu_buf_t *db, void *end, uint64_t obj, | ||||
| static void | ||||
| 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; | ||||
| 	itx_t *itx; | ||||
| 
 | ||||
| @ -1869,7 +1869,7 @@ ztest_log_create(ztest_ds_t *zd, dmu_tx_t *tx, lr_create_t *lr) | ||||
| 		return; | ||||
| 
 | ||||
| 	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)); | ||||
| 
 | ||||
| 	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 | ||||
| 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; | ||||
| 	itx_t *itx; | ||||
| 
 | ||||
| @ -1964,8 +1964,9 @@ static int | ||||
| ztest_replay_create(void *arg1, void *arg2, boolean_t byteswap) | ||||
| { | ||||
| 	ztest_ds_t *zd = arg1; | ||||
| 	lr_create_t *lr = arg2; | ||||
| 	char *name = (void *)(lr + 1);		/* name follows lr */ | ||||
| 	lr_create_t *lrc = arg2; | ||||
| 	_lr_create_t *lr = &lrc->lr_create; | ||||
| 	char *name = (char *)&lrc->lr_data[0];		/* name follows lr */ | ||||
| 	objset_t *os = zd->zd_os; | ||||
| 	ztest_block_tag_t *bbt; | ||||
| 	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, | ||||
| 	    &lr->lr_foid, tx)); | ||||
| 
 | ||||
| 	(void) ztest_log_create(zd, tx, lr); | ||||
| 	(void) ztest_log_create(zd, tx, lrc); | ||||
| 
 | ||||
| 	dmu_tx_commit(tx); | ||||
| 
 | ||||
| @ -2055,7 +2056,7 @@ ztest_replay_remove(void *arg1, void *arg2, boolean_t byteswap) | ||||
| { | ||||
| 	ztest_ds_t *zd = arg1; | ||||
| 	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; | ||||
| 	dmu_object_info_t doi; | ||||
| 	dmu_tx_t *tx; | ||||
| @ -2109,9 +2110,9 @@ ztest_replay_write(void *arg1, void *arg2, boolean_t byteswap) | ||||
| 	ztest_ds_t *zd = arg1; | ||||
| 	lr_write_t *lr = arg2; | ||||
| 	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; | ||||
| 	ztest_block_tag_t *bt = data; | ||||
| 	ztest_block_tag_t *bt = (ztest_block_tag_t *)data; | ||||
| 	ztest_block_tag_t *bbt; | ||||
| 	uint64_t gen, txg, lrtxg, crtxg; | ||||
| 	dmu_object_info_t doi; | ||||
| @ -2563,7 +2564,8 @@ ztest_create(ztest_ds_t *zd, ztest_od_t *od, int count) | ||||
| 			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_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; | ||||
| 	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); | ||||
| 
 | ||||
|  | ||||
| @ -248,6 +248,7 @@ typedef struct { | ||||
| 	uint32_t	lr_attr_masksize; /* number of elements in array */ | ||||
| 	uint32_t	lr_attr_bitmap; /* First entry of array */ | ||||
| 	/* remainder of array and additional lr_attr_end_t fields */ | ||||
| 	uint8_t		lr_attr_data[]; | ||||
| } lr_attr_t; | ||||
| 
 | ||||
| /*
 | ||||
| @ -264,9 +265,14 @@ typedef struct { | ||||
| 	uint64_t	lr_gen;		/* generation (txg of creation) */ | ||||
| 	uint64_t	lr_crtime[2];	/* creation time */ | ||||
| 	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 */ | ||||
| 	/* for symlinks, link content follows name */ | ||||
| 	/* for creates with xvattr data, the name follows the xvattr info */ | ||||
| 	uint8_t		lr_data[]; | ||||
| } lr_create_t; | ||||
| 
 | ||||
| /*
 | ||||
| @ -293,18 +299,20 @@ typedef struct { | ||||
|  * and group will be in lr_create.  Name follows ACL data. | ||||
|  */ | ||||
| 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_domcnt;	/* number of unique domains */ | ||||
| 	uint64_t	lr_fuidcnt;	/* number of real fuids */ | ||||
| 	uint64_t	lr_acl_bytes;	/* number of bytes in ACL */ | ||||
| 	uint64_t	lr_acl_flags;	/* ACL flags */ | ||||
| 	uint8_t		lr_data[]; | ||||
| } lr_acl_create_t; | ||||
| 
 | ||||
| typedef struct { | ||||
| 	lr_t		lr_common;	/* common portion of log record */ | ||||
| 	uint64_t	lr_doid;	/* obj id of directory */ | ||||
| 	/* name of object to remove follows this */ | ||||
| 	uint8_t		lr_data[]; | ||||
| } lr_remove_t; | ||||
| 
 | ||||
| typedef struct { | ||||
| @ -312,18 +320,24 @@ typedef struct { | ||||
| 	uint64_t	lr_doid;	/* obj id of directory */ | ||||
| 	uint64_t	lr_link_obj;	/* obj id of link */ | ||||
| 	/* name of object to link follows this */ | ||||
| 	uint8_t		lr_data[]; | ||||
| } lr_link_t; | ||||
| 
 | ||||
| typedef struct { | ||||
| 	lr_t		lr_common;	/* common portion of log record */ | ||||
| 	uint64_t	lr_sdoid;	/* obj id of source 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 */ | ||||
| 	uint8_t		lr_data[]; | ||||
| } lr_rename_t; | ||||
| 
 | ||||
| typedef struct { | ||||
| 	lr_rename_t	lr_rename;	/* common rename portion */ | ||||
| 	/* members related to the whiteout file (based on lr_create_t) */ | ||||
| 	_lr_rename_t	lr_rename;	/* common rename portion */ | ||||
| 	/* 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_wmode;	/* mode of object */ | ||||
| 	uint64_t	lr_wuid;	/* uid of whiteout */ | ||||
| @ -332,6 +346,7 @@ typedef struct { | ||||
| 	uint64_t	lr_wcrtime[2];	/* creation time */ | ||||
| 	uint64_t	lr_wrdev;	/* always makedev(0, 0) */ | ||||
| 	/* 2 strings: names of source and destination follow this */ | ||||
| 	uint8_t		lr_data[]; | ||||
| } lr_rename_whiteout_t; | ||||
| 
 | ||||
| typedef struct { | ||||
| @ -342,6 +357,7 @@ typedef struct { | ||||
| 	uint64_t	lr_blkoff;	/* no longer used */ | ||||
| 	blkptr_t	lr_blkptr;	/* spa block pointer for replay */ | ||||
| 	/* write data will follow for small writes */ | ||||
| 	uint8_t		lr_data[]; | ||||
| } lr_write_t; | ||||
| 
 | ||||
| typedef struct { | ||||
| @ -362,6 +378,7 @@ typedef struct { | ||||
| 	uint64_t	lr_atime[2];	/* access time */ | ||||
| 	uint64_t	lr_mtime[2];	/* modification time */ | ||||
| 	/* optional attribute lr_attr_t may be here */ | ||||
| 	uint8_t		lr_data[]; | ||||
| } lr_setattr_t; | ||||
| 
 | ||||
| typedef struct { | ||||
| @ -369,6 +386,7 @@ typedef struct { | ||||
| 	uint64_t	lr_foid;	/* file object to change attributes */ | ||||
| 	uint64_t	lr_size; | ||||
| 	/* xattr name and value follows */ | ||||
| 	uint8_t		lr_data[]; | ||||
| } lr_setsaxattr_t; | ||||
| 
 | ||||
| typedef struct { | ||||
| @ -376,6 +394,7 @@ typedef struct { | ||||
| 	uint64_t	lr_foid;	/* obj id of file */ | ||||
| 	uint64_t	lr_aclcnt;	/* number of acl entries */ | ||||
| 	/* lr_aclcnt number of ace_t entries follow this */ | ||||
| 	uint8_t		lr_data[]; | ||||
| } lr_acl_v0_t; | ||||
| 
 | ||||
| typedef struct { | ||||
| @ -387,6 +406,7 @@ typedef struct { | ||||
| 	uint64_t	lr_acl_bytes;	/* number of bytes in ACL */ | ||||
| 	uint64_t	lr_acl_flags;	/* ACL flags */ | ||||
| 	/* lr_acl_bytes number of variable sized ace's follows */ | ||||
| 	uint8_t		lr_data[]; | ||||
| } lr_acl_t; | ||||
| 
 | ||||
| typedef struct { | ||||
| @ -396,8 +416,8 @@ typedef struct { | ||||
| 	uint64_t	lr_length;	/* length of the blocks to clone */ | ||||
| 	uint64_t	lr_blksz;	/* file's block size */ | ||||
| 	uint64_t	lr_nbps;	/* number of block pointers */ | ||||
| 	blkptr_t	lr_bps[]; | ||||
| 	/* block pointers of the blocks to clone follows */ | ||||
| 	blkptr_t	lr_bps[]; | ||||
| } lr_clone_range_t; | ||||
| 
 | ||||
| /*
 | ||||
| @ -448,7 +468,7 @@ typedef struct itx { | ||||
| 	uint64_t	itx_oid;	/* object id */ | ||||
| 	uint64_t	itx_gen;	/* gen number for zfs_get_data */ | ||||
| 	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; | ||||
| 
 | ||||
| /*
 | ||||
|  | ||||
| @ -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) | ||||
| { | ||||
| 	itx_t *itx; | ||||
| 	lr_create_t *lr; | ||||
| 	lr_acl_create_t *lracl; | ||||
| 	_lr_create_t *lr; | ||||
| 	lr_acl_create_t *lracl = NULL; | ||||
| 	uint8_t *lrdata; | ||||
| 	size_t aclsize = 0; | ||||
| 	size_t xvatsize = 0; | ||||
| 	size_t txsize; | ||||
| 	xvattr_t *xvap = (xvattr_t *)vap; | ||||
| 	void *end; | ||||
| 	size_t lrsize; | ||||
| 	size_t namesize = strlen(name) + 1; | ||||
| 	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 || | ||||
| 	    (int)txtype == TX_CREATE || (int)txtype == TX_MKDIR || | ||||
| 	    (int)txtype == TX_MKXATTR) { | ||||
| 		txsize = sizeof (*lr) + namesize + fuidsz + xvatsize; | ||||
| 		lrsize = sizeof (*lr); | ||||
| 		txsize = sizeof (lr_create_t) + namesize + fuidsz + xvatsize; | ||||
| 		itx = zil_itx_create(txtype, txsize); | ||||
| 		lr_create_t *lrc = (lr_create_t *)&itx->itx_lr; | ||||
| 		lrdata = &lrc->lr_data[0]; | ||||
| 	} else { | ||||
| 		txsize = | ||||
| 		    sizeof (lr_acl_create_t) + namesize + fuidsz + | ||||
| 		    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_foid = zp->z_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 | ||||
| 	 */ | ||||
| 	if (vap->va_mask & ATTR_XVATTR) { | ||||
| 		zfs_log_xvattr((lr_attr_t *)((caddr_t)lr + lrsize), xvap); | ||||
| 		end = (caddr_t)lr + lrsize + xvatsize; | ||||
| 	} else { | ||||
| 		end = (caddr_t)lr + lrsize; | ||||
| 		zfs_log_xvattr((lr_attr_t *)lrdata, xvap); | ||||
| 		lrdata = &lrdata[xvatsize]; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Now fill in any ACL info */ | ||||
| 
 | ||||
| 	if (vsecp) { | ||||
| 		lracl = (lr_acl_create_t *)&itx->itx_lr; | ||||
| 		ASSERT3P(lracl, !=, NULL); | ||||
| 		lracl->lr_aclcnt = vsecp->vsa_aclcnt; | ||||
| 		lracl->lr_acl_bytes = aclsize; | ||||
| 		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 | ||||
| 			lracl->lr_acl_flags = 0; | ||||
| 
 | ||||
| 		memcpy(end, vsecp->vsa_aclentp, aclsize); | ||||
| 		end = (caddr_t)end + ZIL_ACE_LENGTH(aclsize); | ||||
| 		memcpy(lrdata, vsecp->vsa_aclentp, aclsize); | ||||
| 		lrdata = &lrdata[ZIL_ACE_LENGTH(aclsize)]; | ||||
| 	} | ||||
| 
 | ||||
| 	/* drop in FUID info */ | ||||
| 	if (fuidp) { | ||||
| 		end = zfs_log_fuid_ids(fuidp, end); | ||||
| 		end = zfs_log_fuid_domains(fuidp, end); | ||||
| 		lrdata = zfs_log_fuid_ids(fuidp, lrdata); | ||||
| 		lrdata = zfs_log_fuid_domains(fuidp, lrdata); | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * Now place file name in log record | ||||
| 	 */ | ||||
| 	memcpy(end, name, namesize); | ||||
| 	memcpy(lrdata, name, namesize); | ||||
| 
 | ||||
| 	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); | ||||
| 	lr = (lr_remove_t *)&itx->itx_lr; | ||||
| 	lr->lr_doid = dzp->z_id; | ||||
| 	memcpy(lr + 1, name, namesize); | ||||
| 	memcpy(&lr->lr_data[0], name, namesize); | ||||
| 
 | ||||
| 	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_doid = dzp->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); | ||||
| } | ||||
| @ -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) | ||||
| { | ||||
| 	itx_t *itx; | ||||
| 	lr_create_t *lr; | ||||
| 	_lr_create_t *lr; | ||||
| 	lr_create_t *lrc; | ||||
| 	size_t namesize = strlen(name) + 1; | ||||
| 	size_t linksize = strlen(link) + 1; | ||||
| 
 | ||||
| 	if (zil_replaying(zilog, tx)) | ||||
| 		return; | ||||
| 
 | ||||
| 	itx = zil_itx_create(txtype, sizeof (*lr) + namesize + linksize); | ||||
| 	lr = (lr_create_t *)&itx->itx_lr; | ||||
| 	itx = zil_itx_create(txtype, sizeof (*lrc) + namesize + linksize); | ||||
| 	lrc = (lr_create_t *)&itx->itx_lr; | ||||
| 	lr = &lrc->lr_create; | ||||
| 	lr->lr_doid = dzp->z_id; | ||||
| 	lr->lr_foid = zp->z_id; | ||||
| 	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)); | ||||
| 	(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(ZTOZSB(zp)), | ||||
| 	    lr->lr_crtime, sizeof (uint64_t) * 2); | ||||
| 	memcpy((char *)(lr + 1), name, namesize); | ||||
| 	memcpy((char *)(lr + 1) + namesize, link, linksize); | ||||
| 	memcpy(&lrc->lr_data[0], name, namesize); | ||||
| 	memcpy(&lrc->lr_data[namesize], link, linksize); | ||||
| 
 | ||||
| 	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) | ||||
| { | ||||
| 	itx_t *itx; | ||||
| 	lr_rename_t *lr; | ||||
| 	_lr_rename_t *lr; | ||||
| 	lr_rename_t *lrr; | ||||
| 	size_t snamesize = strlen(sname) + 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; | ||||
| 
 | ||||
| 	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_tdoid = tdzp->z_id; | ||||
| 	memcpy((char *)(lr + 1), sname, snamesize); | ||||
| 	memcpy((char *)(lr + 1) + snamesize, dname, dnamesize); | ||||
| 	memcpy(&lrr->lr_data[0], sname, snamesize); | ||||
| 	memcpy(&lrr->lr_data[snamesize], dname, dnamesize); | ||||
| 	itx->itx_oid = szp->z_id; | ||||
| 
 | ||||
| 	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, | ||||
| 	    sizeof (lr->lr_wrdev)); | ||||
| 
 | ||||
| 	memcpy((char *)(lr + 1), sname, snamesize); | ||||
| 	memcpy((char *)(lr + 1) + snamesize, dname, dnamesize); | ||||
| 	memcpy(&lr->lr_data[0], sname, snamesize); | ||||
| 	memcpy(&lr->lr_data[snamesize], dname, dnamesize); | ||||
| 	itx->itx_oid = szp->z_id; | ||||
| 
 | ||||
| 	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) { | ||||
| 			int err; | ||||
| 			DB_DNODE_ENTER(db); | ||||
| 			err = dmu_read_by_dnode(DB_DNODE(db), off, len, lr + 1, | ||||
| 			    DMU_READ_NO_PREFETCH); | ||||
| 			err = dmu_read_by_dnode(DB_DNODE(db), off, len, | ||||
| 			    &lr->lr_data[0], DMU_READ_NO_PREFETCH); | ||||
| 			DB_DNODE_EXIT(db); | ||||
| 			if (err != 0) { | ||||
| 				zil_itx_destroy(itx); | ||||
| @ -741,7 +745,7 @@ zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype, | ||||
| 	lr_setattr_t	*lr; | ||||
| 	xvattr_t	*xvap = (xvattr_t *)vap; | ||||
| 	size_t		recsize = sizeof (lr_setattr_t); | ||||
| 	void		*start; | ||||
| 	uint8_t		*start; | ||||
| 
 | ||||
| 	if (zil_replaying(zilog, tx) || zp->z_unlinked) | ||||
| 		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; | ||||
| 	ZFS_TIME_ENCODE(&vap->va_atime, lr->lr_atime); | ||||
| 	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) { | ||||
| 		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; | ||||
| 	lr_setsaxattr_t	*lr; | ||||
| 	size_t		recsize = sizeof (lr_setsaxattr_t); | ||||
| 	void		*xattrstart; | ||||
| 	int		namelen; | ||||
| 
 | ||||
| 	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); | ||||
| 	lr = (lr_setsaxattr_t *)&itx->itx_lr; | ||||
| 	lr->lr_foid = zp->z_id; | ||||
| 	xattrstart = (char *)(lr + 1); | ||||
| 	memcpy(xattrstart, name, namelen); | ||||
| 	memcpy(&lr->lr_data[0], name, namelen); | ||||
| 	if (value != NULL) { | ||||
| 		memcpy((char *)xattrstart + namelen, value, size); | ||||
| 		memcpy(&lr->lr_data[namelen], value, size); | ||||
| 		lr->lr_size = size; | ||||
| 	} else { | ||||
| 		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) { | ||||
| 		lrv0 = (lr_acl_v0_t *)lr; | ||||
| 		memcpy(lrv0 + 1, vsecp->vsa_aclentp, aclbytes); | ||||
| 		memcpy(&lrv0->lr_data[0], vsecp->vsa_aclentp, aclbytes); | ||||
| 	} else { | ||||
| 		void *start = (ace_t *)(lr + 1); | ||||
| 		uint8_t *start = &lr->lr_data[0]; | ||||
| 
 | ||||
| 		memcpy(start, vsecp->vsa_aclentp, aclbytes); | ||||
| 
 | ||||
| 		start = (caddr_t)start + ZIL_ACE_LENGTH(aclbytes); | ||||
| 		start = &lr->lr_data[ZIL_ACE_LENGTH(aclbytes)]; | ||||
| 
 | ||||
| 		if (fuidp) { | ||||
| 			start = zfs_log_fuid_ids(fuidp, start); | ||||
|  | ||||
| @ -293,16 +293,16 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap) | ||||
| { | ||||
| 	zfsvfs_t *zfsvfs = arg1; | ||||
| 	lr_acl_create_t *lracl = arg2; | ||||
| 	_lr_create_t *lr = &lracl->lr_create; | ||||
| 	char *name = NULL;		/* location determined later */ | ||||
| 	lr_create_t *lr = (lr_create_t *)lracl; | ||||
| 	znode_t *dzp; | ||||
| 	znode_t *zp; | ||||
| 	xvattr_t xva; | ||||
| 	int vflg = 0; | ||||
| 	vsecattr_t vsec = { 0 }; | ||||
| 	lr_attr_t *lrattr; | ||||
| 	void *aclstart; | ||||
| 	void *fuidstart; | ||||
| 	uint8_t *aclstart; | ||||
| 	uint8_t *fuidstart; | ||||
| 	size_t xvatlen = 0; | ||||
| 	uint64_t txtype; | ||||
| 	uint64_t objid; | ||||
| @ -316,17 +316,18 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap) | ||||
| 		byteswap_uint64_array(lracl, sizeof (*lracl)); | ||||
| 		if (txtype == TX_CREATE_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); | ||||
| 			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); | ||||
| 
 | ||||
| 		/* swap fuids */ | ||||
| 		if (lracl->lr_fuidcnt) { | ||||
| 			byteswap_uint64_array((caddr_t)aclstart + | ||||
| 			    ZIL_ACE_LENGTH(lracl->lr_acl_bytes), | ||||
| 			byteswap_uint64_array( | ||||
| 			    &aclstart[ZIL_ACE_LENGTH(lracl->lr_acl_bytes)], | ||||
| 			    lracl->lr_fuidcnt * sizeof (uint64_t)); | ||||
| 		} | ||||
| 	} | ||||
| @ -361,28 +362,27 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap) | ||||
| 		vflg |= FIGNORECASE; | ||||
| 	switch (txtype) { | ||||
| 	case TX_CREATE_ACL: | ||||
| 		aclstart = (caddr_t)(lracl + 1); | ||||
| 		fuidstart = (caddr_t)aclstart + | ||||
| 		    ZIL_ACE_LENGTH(lracl->lr_acl_bytes); | ||||
| 		aclstart = &lracl->lr_data[0]; | ||||
| 		fuidstart = &aclstart[ZIL_ACE_LENGTH(lracl->lr_acl_bytes)]; | ||||
| 		zfsvfs->z_fuid_replay = zfs_replay_fuids(fuidstart, | ||||
| 		    (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt, | ||||
| 		    lr->lr_uid, lr->lr_gid); | ||||
| 		zfs_fallthrough; | ||||
| 	case TX_CREATE_ACL_ATTR: | ||||
| 		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); | ||||
| 			xva.xva_vattr.va_mask |= ATTR_XVATTR; | ||||
| 			zfs_replay_xvattr(lrattr, &xva); | ||||
| 		} | ||||
| 		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_aclentsz = lracl->lr_acl_bytes; | ||||
| 		vsec.vsa_aclflags = lracl->lr_acl_flags; | ||||
| 		if (zfsvfs->z_fuid_replay == NULL) { | ||||
| 			fuidstart = (caddr_t)(lracl + 1) + xvatlen + | ||||
| 			    ZIL_ACE_LENGTH(lracl->lr_acl_bytes); | ||||
| 			fuidstart = &lracl->lr_data[xvatlen + | ||||
| 			    ZIL_ACE_LENGTH(lracl->lr_acl_bytes)]; | ||||
| 			zfsvfs->z_fuid_replay = | ||||
| 			    zfs_replay_fuids(fuidstart, | ||||
| 			    (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt, | ||||
| @ -398,9 +398,8 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap) | ||||
| #endif | ||||
| 		break; | ||||
| 	case TX_MKDIR_ACL: | ||||
| 		aclstart = (caddr_t)(lracl + 1); | ||||
| 		fuidstart = (caddr_t)aclstart + | ||||
| 		    ZIL_ACE_LENGTH(lracl->lr_acl_bytes); | ||||
| 		aclstart = &lracl->lr_data[0]; | ||||
| 		fuidstart = &aclstart[ZIL_ACE_LENGTH(lracl->lr_acl_bytes)]; | ||||
| 		zfsvfs->z_fuid_replay = zfs_replay_fuids(fuidstart, | ||||
| 		    (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt, | ||||
| 		    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); | ||||
| 		} | ||||
| 		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_aclentsz = lracl->lr_acl_bytes; | ||||
| 		vsec.vsa_aclflags = lracl->lr_acl_flags; | ||||
| 		if (zfsvfs->z_fuid_replay == NULL) { | ||||
| 			fuidstart = (caddr_t)(lracl + 1) + xvatlen + | ||||
| 			    ZIL_ACE_LENGTH(lracl->lr_acl_bytes); | ||||
| 			fuidstart = &lracl->lr_data[xvatlen + | ||||
| 			    ZIL_ACE_LENGTH(lracl->lr_acl_bytes)]; | ||||
| 			zfsvfs->z_fuid_replay = | ||||
| 			    zfs_replay_fuids(fuidstart, | ||||
| 			    (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt, | ||||
| @ -456,14 +455,14 @@ static int | ||||
| zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap) | ||||
| { | ||||
| 	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 *link;			/* symlink content follows name */ | ||||
| 	znode_t *dzp; | ||||
| 	znode_t *zp = NULL; | ||||
| 	xvattr_t xva; | ||||
| 	int vflg = 0; | ||||
| 	size_t lrsize = sizeof (lr_create_t); | ||||
| 	lr_attr_t *lrattr; | ||||
| 	void *start; | ||||
| 	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); | ||||
| 	if (byteswap) { | ||||
| 		byteswap_uint64_array(lr, sizeof (*lr)); | ||||
| 		byteswap_uint64_array(lrc, sizeof (*lrc)); | ||||
| 		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 && | ||||
| 	    txtype != TX_MKDIR_ATTR && | ||||
| 	    txtype != TX_CREATE_ATTR) { | ||||
| 		start = (lr + 1); | ||||
| 		start = (void *)&lrc->lr_data[0]; | ||||
| 		zfsvfs->z_fuid_replay = | ||||
| 		    zfs_replay_fuid_domain(start, &start, | ||||
| 		    lr->lr_uid, lr->lr_gid); | ||||
| @ -528,10 +527,10 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap) | ||||
| 
 | ||||
| 	switch (txtype) { | ||||
| 	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); | ||||
| 		zfs_replay_xvattr((lr_attr_t *)((caddr_t)lr + lrsize), &xva); | ||||
| 		start = (caddr_t)(lr + 1) + xvatlen; | ||||
| 		zfs_replay_xvattr(lrattr, &xva); | ||||
| 		start = (void *)&lrc->lr_data[xvatlen]; | ||||
| 		zfsvfs->z_fuid_replay = | ||||
| 		    zfs_replay_fuid_domain(start, &start, | ||||
| 		    lr->lr_uid, lr->lr_gid); | ||||
| @ -551,10 +550,10 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap) | ||||
| #endif | ||||
| 		break; | ||||
| 	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); | ||||
| 		zfs_replay_xvattr((lr_attr_t *)((caddr_t)lr + lrsize), &xva); | ||||
| 		start = (caddr_t)(lr + 1) + xvatlen; | ||||
| 		zfs_replay_xvattr(lrattr, &xva); | ||||
| 		start = &lrc->lr_data[xvatlen]; | ||||
| 		zfsvfs->z_fuid_replay = | ||||
| 		    zfs_replay_fuid_domain(start, &start, | ||||
| 		    lr->lr_uid, lr->lr_gid); | ||||
| @ -563,7 +562,7 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap) | ||||
| 
 | ||||
| 	case TX_MKDIR: | ||||
| 		if (name == NULL) | ||||
| 			name = (char *)(lr + 1); | ||||
| 			name = (char *)&lrc->lr_data[0]; | ||||
| 
 | ||||
| #if defined(__linux__) | ||||
| 		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); | ||||
| 		break; | ||||
| 	case TX_SYMLINK: | ||||
| 		name = (char *)(lr + 1); | ||||
| 		link = name + strlen(name) + 1; | ||||
| 		name = &lrc->lr_data[0]; | ||||
| 		link = &lrc->lr_data[strlen(name) + 1]; | ||||
| #if defined(__linux__) | ||||
| 		error = zfs_symlink(dzp, name, &xva.xva_vattr, | ||||
| 		    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; | ||||
| 	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; | ||||
| 	int error; | ||||
| 	int vflg = 0; | ||||
| @ -649,7 +648,7 @@ zfs_replay_link(void *arg1, void *arg2, boolean_t byteswap) | ||||
| { | ||||
| 	zfsvfs_t *zfsvfs = arg1; | ||||
| 	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; | ||||
| 	int error; | ||||
| 	int vflg = 0; | ||||
| @ -678,7 +677,7 @@ zfs_replay_link(void *arg1, void *arg2, boolean_t byteswap) | ||||
| } | ||||
| 
 | ||||
| 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) | ||||
| { | ||||
| 	znode_t *sdzp, *tdzp; | ||||
| @ -722,15 +721,17 @@ static int | ||||
| zfs_replay_rename(void *arg1, void *arg2, boolean_t byteswap) | ||||
| { | ||||
| 	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)); | ||||
| 
 | ||||
| 	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 */ | ||||
| 	char *tname = sname + strlen(sname) + 1; | ||||
| 	/* sname and tname follow lr_rename_t */ | ||||
| 	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)); | ||||
| } | ||||
| 
 | ||||
| @ -739,15 +740,17 @@ zfs_replay_rename_exchange(void *arg1, void *arg2, boolean_t byteswap) | ||||
| { | ||||
| #ifdef __linux__ | ||||
| 	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)); | ||||
| 
 | ||||
| 	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 */ | ||||
| 	char *tname = sname + strlen(sname) + 1; | ||||
| 	/* sname and tname follow lr_rename_t */ | ||||
| 	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, | ||||
| 	    NULL)); | ||||
| #else | ||||
| @ -760,24 +763,26 @@ zfs_replay_rename_whiteout(void *arg1, void *arg2, boolean_t byteswap) | ||||
| { | ||||
| #ifdef __linux__ | ||||
| 	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; | ||||
| 	/* For the whiteout file. */ | ||||
| 	xvattr_t xva; | ||||
| 	uint64_t objid; | ||||
| 	uint64_t dnodesize; | ||||
| 
 | ||||
| 	ASSERT3U(lr->lr_rename.lr_common.lrc_reclen, >, sizeof (*lr)); | ||||
| 	ASSERT3U(lr->lr_common.lrc_reclen, >, sizeof (*lr)); | ||||
| 
 | ||||
| 	if (byteswap) | ||||
| 		byteswap_uint64_array(lr, sizeof (*lr)); | ||||
| 		byteswap_uint64_array(lrrw, sizeof (*lrrw)); | ||||
| 
 | ||||
| 	objid = LR_FOID_GET_OBJ(lr->lr_wfoid); | ||||
| 	dnodesize = LR_FOID_GET_SLOTS(lr->lr_wfoid) << DNODE_SHIFT; | ||||
| 	objid = LR_FOID_GET_OBJ(lrrw->lr_wfoid); | ||||
| 	dnodesize = LR_FOID_GET_SLOTS(lrrw->lr_wfoid) << DNODE_SHIFT; | ||||
| 
 | ||||
| 	xva_init(&xva); | ||||
| 	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 | ||||
| @ -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 | ||||
| 	 * unused va_ctime, va_nblocks, and va_fsid fields. | ||||
| 	 */ | ||||
| 	ZFS_TIME_DECODE(&xva.xva_vattr.va_ctime, lr->lr_wcrtime); | ||||
| 	xva.xva_vattr.va_nblocks = lr->lr_wgen; | ||||
| 	ZFS_TIME_DECODE(&xva.xva_vattr.va_ctime, lrrw->lr_wcrtime); | ||||
| 	xva.xva_vattr.va_nblocks = lrrw->lr_wgen; | ||||
| 	xva.xva_vattr.va_fsid = dnodesize; | ||||
| 
 | ||||
| 	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); | ||||
| 
 | ||||
| 	/* sname and tname follow lr_rename_whiteout_t */ | ||||
| 	char *sname = (char *)(lr + 1); | ||||
| 	char *tname = sname + strlen(sname) + 1; | ||||
| 	return (do_zfs_replay_rename(zfsvfs, &lr->lr_rename, sname, tname, | ||||
| 	char *sname = (char *)&lrrw->lr_data[0]; | ||||
| 	char *tname = (char *)&lrrw->lr_data[strlen(sname)+1]; | ||||
| 	return (do_zfs_replay_rename(zfsvfs, lr, sname, tname, | ||||
| 	    RENAME_WHITEOUT, &xva.xva_vattr)); | ||||
| #else | ||||
| 	return (SET_ERROR(ENOTSUP)); | ||||
| @ -809,7 +814,7 @@ zfs_replay_write(void *arg1, void *arg2, boolean_t byteswap) | ||||
| { | ||||
| 	zfsvfs_t *zfsvfs = arg1; | ||||
| 	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; | ||||
| 	int error; | ||||
| 	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) && | ||||
| 		    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) | ||||
| @ -987,11 +992,11 @@ zfs_replay_setattr(void *arg1, void *arg2, boolean_t byteswap) | ||||
| 	 * 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) { | ||||
| 		zfs_replay_xvattr((lr_attr_t *)start, &xva); | ||||
| 		start = (caddr_t)start + | ||||
| 		    ZIL_XVAT_SIZE(((lr_attr_t *)start)->lr_attr_masksize); | ||||
| 		start = &lr->lr_data[ | ||||
| 		    ZIL_XVAT_SIZE(((lr_attr_t *)start)->lr_attr_masksize)]; | ||||
| 	} else | ||||
| 		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 */ | ||||
| 	size = lr->lr_size; | ||||
| 	name = (char *)(lr + 1); | ||||
| 	name = (char *)&lr->lr_data[0]; | ||||
| 	if (size == 0) { | ||||
| 		value = NULL; | ||||
| 		error = nvlist_remove(nvl, name, DATA_TYPE_BYTE_ARRAY); | ||||
| 	} else { | ||||
| 		value = name + strlen(name) + 1; | ||||
| 		value = &lr->lr_data[strlen(name) + 1]; | ||||
| 		/* Limited to 32k to keep nvpair memory allocations small */ | ||||
| 		if (size > DXATTR_MAX_ENTRY_SIZE) { | ||||
| 			error = SET_ERROR(EFBIG); | ||||
| @ -1099,7 +1104,7 @@ zfs_replay_acl_v0(void *arg1, void *arg2, boolean_t byteswap) | ||||
| { | ||||
| 	zfsvfs_t *zfsvfs = arg1; | ||||
| 	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}; | ||||
| 	znode_t *zp; | ||||
| 	int error; | ||||
| @ -1148,7 +1153,7 @@ zfs_replay_acl(void *arg1, void *arg2, boolean_t byteswap) | ||||
| { | ||||
| 	zfsvfs_t *zfsvfs = arg1; | ||||
| 	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}; | ||||
| 	znode_t *zp; | ||||
| 	int error; | ||||
| @ -1160,8 +1165,8 @@ zfs_replay_acl(void *arg1, void *arg2, boolean_t byteswap) | ||||
| 		byteswap_uint64_array(lr, sizeof (*lr)); | ||||
| 		zfs_ace_byteswap(ace, lr->lr_acl_bytes, B_FALSE); | ||||
| 		if (lr->lr_fuidcnt) { | ||||
| 			byteswap_uint64_array((caddr_t)ace + | ||||
| 			    ZIL_ACE_LENGTH(lr->lr_acl_bytes), | ||||
| 			byteswap_uint64_array(&lr->lr_data[ | ||||
| 			    ZIL_ACE_LENGTH(lr->lr_acl_bytes)], | ||||
| 			    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; | ||||
| 
 | ||||
| 	if (lr->lr_fuidcnt) { | ||||
| 		void *fuidstart = (caddr_t)ace + | ||||
| 		    ZIL_ACE_LENGTH(lr->lr_acl_bytes); | ||||
| 		void *fuidstart = &lr->lr_data[ | ||||
| 		    ZIL_ACE_LENGTH(lr->lr_acl_bytes)]; | ||||
| 
 | ||||
| 		zfsvfs->z_fuid_replay = | ||||
| 		    zfs_replay_fuids(fuidstart, &fuidstart, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Rob Norris
						Rob Norris