|
@@ -159,37 +159,72 @@ xlog_cil_init_post_recovery(
|
|
|
* format the regions into the iclog as though they are being formatted
|
|
|
* directly out of the objects themselves.
|
|
|
*/
|
|
|
-static void
|
|
|
-xlog_cil_format_items(
|
|
|
- struct log *log,
|
|
|
- struct xfs_log_vec *log_vector)
|
|
|
+static struct xfs_log_vec *
|
|
|
+xlog_cil_prepare_log_vecs(
|
|
|
+ struct xfs_trans *tp)
|
|
|
{
|
|
|
- struct xfs_log_vec *lv;
|
|
|
+ struct xfs_log_item_desc *lidp;
|
|
|
+ struct xfs_log_vec *lv = NULL;
|
|
|
+ struct xfs_log_vec *ret_lv = NULL;
|
|
|
|
|
|
- ASSERT(log_vector);
|
|
|
- for (lv = log_vector; lv; lv = lv->lv_next) {
|
|
|
+
|
|
|
+ /* Bail out if we didn't find a log item. */
|
|
|
+ if (list_empty(&tp->t_items)) {
|
|
|
+ ASSERT(0);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ list_for_each_entry(lidp, &tp->t_items, lid_trans) {
|
|
|
+ struct xfs_log_vec *new_lv;
|
|
|
void *ptr;
|
|
|
int index;
|
|
|
int len = 0;
|
|
|
|
|
|
+ /* Skip items which aren't dirty in this transaction. */
|
|
|
+ if (!(lidp->lid_flags & XFS_LID_DIRTY))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ /* Skip items that do not have any vectors for writing */
|
|
|
+ lidp->lid_size = IOP_SIZE(lidp->lid_item);
|
|
|
+ if (!lidp->lid_size)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ new_lv = kmem_zalloc(sizeof(*new_lv) +
|
|
|
+ lidp->lid_size * sizeof(struct xfs_log_iovec),
|
|
|
+ KM_SLEEP);
|
|
|
+
|
|
|
+ /* The allocated iovec region lies beyond the log vector. */
|
|
|
+ new_lv->lv_iovecp = (struct xfs_log_iovec *)&new_lv[1];
|
|
|
+ new_lv->lv_niovecs = lidp->lid_size;
|
|
|
+ new_lv->lv_item = lidp->lid_item;
|
|
|
+
|
|
|
/* build the vector array and calculate it's length */
|
|
|
- IOP_FORMAT(lv->lv_item, lv->lv_iovecp);
|
|
|
- for (index = 0; index < lv->lv_niovecs; index++)
|
|
|
- len += lv->lv_iovecp[index].i_len;
|
|
|
+ IOP_FORMAT(new_lv->lv_item, new_lv->lv_iovecp);
|
|
|
+ for (index = 0; index < new_lv->lv_niovecs; index++)
|
|
|
+ len += new_lv->lv_iovecp[index].i_len;
|
|
|
|
|
|
- lv->lv_buf_len = len;
|
|
|
- lv->lv_buf = kmem_alloc(lv->lv_buf_len, KM_SLEEP|KM_NOFS);
|
|
|
- ptr = lv->lv_buf;
|
|
|
+ new_lv->lv_buf_len = len;
|
|
|
+ new_lv->lv_buf = kmem_alloc(new_lv->lv_buf_len,
|
|
|
+ KM_SLEEP|KM_NOFS);
|
|
|
+ ptr = new_lv->lv_buf;
|
|
|
|
|
|
- for (index = 0; index < lv->lv_niovecs; index++) {
|
|
|
- struct xfs_log_iovec *vec = &lv->lv_iovecp[index];
|
|
|
+ for (index = 0; index < new_lv->lv_niovecs; index++) {
|
|
|
+ struct xfs_log_iovec *vec = &new_lv->lv_iovecp[index];
|
|
|
|
|
|
memcpy(ptr, vec->i_addr, vec->i_len);
|
|
|
vec->i_addr = ptr;
|
|
|
ptr += vec->i_len;
|
|
|
}
|
|
|
- ASSERT(ptr == lv->lv_buf + lv->lv_buf_len);
|
|
|
+ ASSERT(ptr == new_lv->lv_buf + new_lv->lv_buf_len);
|
|
|
+
|
|
|
+ if (!ret_lv)
|
|
|
+ ret_lv = new_lv;
|
|
|
+ else
|
|
|
+ lv->lv_next = new_lv;
|
|
|
+ lv = new_lv;
|
|
|
}
|
|
|
+
|
|
|
+ return ret_lv;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -622,28 +657,30 @@ out_abort:
|
|
|
* background commit, returns without it held once background commits are
|
|
|
* allowed again.
|
|
|
*/
|
|
|
-void
|
|
|
+int
|
|
|
xfs_log_commit_cil(
|
|
|
struct xfs_mount *mp,
|
|
|
struct xfs_trans *tp,
|
|
|
- struct xfs_log_vec *log_vector,
|
|
|
xfs_lsn_t *commit_lsn,
|
|
|
int flags)
|
|
|
{
|
|
|
struct log *log = mp->m_log;
|
|
|
int log_flags = 0;
|
|
|
int push = 0;
|
|
|
+ struct xfs_log_vec *log_vector;
|
|
|
|
|
|
if (flags & XFS_TRANS_RELEASE_LOG_RES)
|
|
|
log_flags = XFS_LOG_REL_PERM_RESERV;
|
|
|
|
|
|
/*
|
|
|
- * do all the hard work of formatting items (including memory
|
|
|
+ * Do all the hard work of formatting items (including memory
|
|
|
* allocation) outside the CIL context lock. This prevents stalling CIL
|
|
|
* pushes when we are low on memory and a transaction commit spends a
|
|
|
* lot of time in memory reclaim.
|
|
|
*/
|
|
|
- xlog_cil_format_items(log, log_vector);
|
|
|
+ log_vector = xlog_cil_prepare_log_vecs(tp);
|
|
|
+ if (!log_vector)
|
|
|
+ return ENOMEM;
|
|
|
|
|
|
/* lock out background commit */
|
|
|
down_read(&log->l_cilp->xc_ctx_lock);
|
|
@@ -696,6 +733,7 @@ xfs_log_commit_cil(
|
|
|
*/
|
|
|
if (push)
|
|
|
xlog_cil_push(log, 0);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
/*
|