|
@@ -205,16 +205,25 @@ xlog_cil_insert_format_items(
|
|
/*
|
|
/*
|
|
* We 64-bit align the length of each iovec so that the start
|
|
* We 64-bit align the length of each iovec so that the start
|
|
* of the next one is naturally aligned. We'll need to
|
|
* of the next one is naturally aligned. We'll need to
|
|
- * account for that slack space here.
|
|
|
|
|
|
+ * account for that slack space here. Then round nbytes up
|
|
|
|
+ * to 64-bit alignment so that the initial buffer alignment is
|
|
|
|
+ * easy to calculate and verify.
|
|
*/
|
|
*/
|
|
nbytes += niovecs * sizeof(uint64_t);
|
|
nbytes += niovecs * sizeof(uint64_t);
|
|
|
|
+ nbytes = round_up(nbytes, sizeof(uint64_t));
|
|
|
|
|
|
/* grab the old item if it exists for reservation accounting */
|
|
/* grab the old item if it exists for reservation accounting */
|
|
old_lv = lip->li_lv;
|
|
old_lv = lip->li_lv;
|
|
|
|
|
|
- /* calc buffer size */
|
|
|
|
- buf_size = sizeof(struct xfs_log_vec) + nbytes +
|
|
|
|
- niovecs * sizeof(struct xfs_log_iovec);
|
|
|
|
|
|
+ /*
|
|
|
|
+ * The data buffer needs to start 64-bit aligned, so round up
|
|
|
|
+ * that space to ensure we can align it appropriately and not
|
|
|
|
+ * overrun the buffer.
|
|
|
|
+ */
|
|
|
|
+ buf_size = nbytes +
|
|
|
|
+ round_up((sizeof(struct xfs_log_vec) +
|
|
|
|
+ niovecs * sizeof(struct xfs_log_iovec)),
|
|
|
|
+ sizeof(uint64_t));
|
|
|
|
|
|
/* compare to existing item size */
|
|
/* compare to existing item size */
|
|
if (lip->li_lv && buf_size <= lip->li_lv->lv_size) {
|
|
if (lip->li_lv && buf_size <= lip->li_lv->lv_size) {
|
|
@@ -251,6 +260,8 @@ xlog_cil_insert_format_items(
|
|
/* The allocated data region lies beyond the iovec region */
|
|
/* The allocated data region lies beyond the iovec region */
|
|
lv->lv_buf_len = 0;
|
|
lv->lv_buf_len = 0;
|
|
lv->lv_buf = (char *)lv + buf_size - nbytes;
|
|
lv->lv_buf = (char *)lv + buf_size - nbytes;
|
|
|
|
+ ASSERT(IS_ALIGNED((unsigned long)lv->lv_buf, sizeof(uint64_t)));
|
|
|
|
+
|
|
lip->li_ops->iop_format(lip, lv);
|
|
lip->li_ops->iop_format(lip, lv);
|
|
insert:
|
|
insert:
|
|
ASSERT(lv->lv_buf_len <= nbytes);
|
|
ASSERT(lv->lv_buf_len <= nbytes);
|