Preserve itx alloc size for zio_data_buf_free()
Using zio_data_buf_alloc() to allocate the itx's may be unsafe because the itx->itx_lr.lrc_reclen field is not constant from allocation to free. Using a different itx->itx_lr.lrc_reclen size in zio_data_buf_free() can result in the allocation being returned to the wrong kmem cache. This issue can be avoided entirely by storing the allocation size in itx->itx_size and using that for zio_data_buf_free(). Reviewed by: Prakash Surya <prakash.surya@delphix.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #6912
This commit is contained in:
parent
d4677269f2
commit
72841b9fd9
|
@ -395,6 +395,7 @@ typedef struct itx {
|
||||||
uint8_t itx_sync; /* synchronous transaction */
|
uint8_t itx_sync; /* synchronous transaction */
|
||||||
zil_callback_t itx_callback; /* Called when the itx is persistent */
|
zil_callback_t itx_callback; /* Called when the itx is persistent */
|
||||||
void *itx_callback_data; /* User data for the callback */
|
void *itx_callback_data; /* User data for the callback */
|
||||||
|
size_t itx_size; /* allocated itx structure size */
|
||||||
uint64_t itx_oid; /* object id */
|
uint64_t itx_oid; /* object id */
|
||||||
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 */
|
/* followed by type-specific part of lr_xx_t and its immediate data */
|
||||||
|
|
|
@ -1254,17 +1254,20 @@ cont:
|
||||||
itx_t *
|
itx_t *
|
||||||
zil_itx_create(uint64_t txtype, size_t lrsize)
|
zil_itx_create(uint64_t txtype, size_t lrsize)
|
||||||
{
|
{
|
||||||
|
size_t itxsize;
|
||||||
itx_t *itx;
|
itx_t *itx;
|
||||||
|
|
||||||
lrsize = P2ROUNDUP_TYPED(lrsize, sizeof (uint64_t), size_t);
|
lrsize = P2ROUNDUP_TYPED(lrsize, sizeof (uint64_t), size_t);
|
||||||
|
itxsize = offsetof(itx_t, itx_lr) + lrsize;
|
||||||
|
|
||||||
itx = zio_data_buf_alloc(offsetof(itx_t, itx_lr) + lrsize);
|
itx = zio_data_buf_alloc(itxsize);
|
||||||
itx->itx_lr.lrc_txtype = txtype;
|
itx->itx_lr.lrc_txtype = txtype;
|
||||||
itx->itx_lr.lrc_reclen = lrsize;
|
itx->itx_lr.lrc_reclen = lrsize;
|
||||||
itx->itx_lr.lrc_seq = 0; /* defensive */
|
itx->itx_lr.lrc_seq = 0; /* defensive */
|
||||||
itx->itx_sync = B_TRUE; /* default is synchronous */
|
itx->itx_sync = B_TRUE; /* default is synchronous */
|
||||||
itx->itx_callback = NULL;
|
itx->itx_callback = NULL;
|
||||||
itx->itx_callback_data = NULL;
|
itx->itx_callback_data = NULL;
|
||||||
|
itx->itx_size = itxsize;
|
||||||
|
|
||||||
return (itx);
|
return (itx);
|
||||||
}
|
}
|
||||||
|
@ -1272,7 +1275,7 @@ zil_itx_create(uint64_t txtype, size_t lrsize)
|
||||||
void
|
void
|
||||||
zil_itx_destroy(itx_t *itx)
|
zil_itx_destroy(itx_t *itx)
|
||||||
{
|
{
|
||||||
zio_data_buf_free(itx, offsetof(itx_t, itx_lr)+itx->itx_lr.lrc_reclen);
|
zio_data_buf_free(itx, itx->itx_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue