diff options
Diffstat (limited to 'fs/xfs/xfs_log_cil.c')
-rw-r--r-- | fs/xfs/xfs_log_cil.c | 74 |
1 files changed, 22 insertions, 52 deletions
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index 5eb51fc5eb84..cdebd832c3db 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c | |||
@@ -82,36 +82,6 @@ xlog_cil_init_post_recovery( | |||
82 | log->l_curr_block); | 82 | log->l_curr_block); |
83 | } | 83 | } |
84 | 84 | ||
85 | STATIC int | ||
86 | xlog_cil_lv_item_format( | ||
87 | struct xfs_log_item *lip, | ||
88 | struct xfs_log_vec *lv) | ||
89 | { | ||
90 | int index; | ||
91 | char *ptr; | ||
92 | |||
93 | /* format new vectors into array */ | ||
94 | lip->li_ops->iop_format(lip, lv->lv_iovecp); | ||
95 | |||
96 | /* copy data into existing array */ | ||
97 | ptr = lv->lv_buf; | ||
98 | for (index = 0; index < lv->lv_niovecs; index++) { | ||
99 | struct xfs_log_iovec *vec = &lv->lv_iovecp[index]; | ||
100 | |||
101 | memcpy(ptr, vec->i_addr, vec->i_len); | ||
102 | vec->i_addr = ptr; | ||
103 | ptr += vec->i_len; | ||
104 | } | ||
105 | |||
106 | /* | ||
107 | * some size calculations for log vectors over-estimate, so the caller | ||
108 | * doesn't know the amount of space actually used by the item. Return | ||
109 | * the byte count to the caller so they can check and store it | ||
110 | * appropriately. | ||
111 | */ | ||
112 | return ptr - lv->lv_buf; | ||
113 | } | ||
114 | |||
115 | /* | 85 | /* |
116 | * Prepare the log item for insertion into the CIL. Calculate the difference in | 86 | * Prepare the log item for insertion into the CIL. Calculate the difference in |
117 | * log space and vectors it will consume, and if it is a new item pin it as | 87 | * log space and vectors it will consume, and if it is a new item pin it as |
@@ -232,6 +202,13 @@ xlog_cil_insert_format_items( | |||
232 | nbytes = 0; | 202 | nbytes = 0; |
233 | } | 203 | } |
234 | 204 | ||
205 | /* | ||
206 | * We 64-bit align the length of each iovec so that the start | ||
207 | * of the next one is naturally aligned. We'll need to | ||
208 | * account for that slack space here. | ||
209 | */ | ||
210 | nbytes += niovecs * sizeof(uint64_t); | ||
211 | |||
235 | /* grab the old item if it exists for reservation accounting */ | 212 | /* grab the old item if it exists for reservation accounting */ |
236 | old_lv = lip->li_lv; | 213 | old_lv = lip->li_lv; |
237 | 214 | ||
@@ -254,34 +231,27 @@ xlog_cil_insert_format_items( | |||
254 | */ | 231 | */ |
255 | *diff_iovecs -= lv->lv_niovecs; | 232 | *diff_iovecs -= lv->lv_niovecs; |
256 | *diff_len -= lv->lv_buf_len; | 233 | *diff_len -= lv->lv_buf_len; |
257 | 234 | } else { | |
258 | /* Ensure the lv is set up according to ->iop_size */ | 235 | /* allocate new data chunk */ |
259 | lv->lv_niovecs = niovecs; | 236 | lv = kmem_zalloc(buf_size, KM_SLEEP|KM_NOFS); |
260 | lv->lv_buf = (char *)lv + buf_size - nbytes; | 237 | lv->lv_item = lip; |
261 | 238 | lv->lv_size = buf_size; | |
262 | lv->lv_buf_len = xlog_cil_lv_item_format(lip, lv); | 239 | if (ordered) { |
263 | goto insert; | 240 | /* track as an ordered logvec */ |
241 | ASSERT(lip->li_lv == NULL); | ||
242 | lv->lv_buf_len = XFS_LOG_VEC_ORDERED; | ||
243 | goto insert; | ||
244 | } | ||
245 | lv->lv_iovecp = (struct xfs_log_iovec *)&lv[1]; | ||
264 | } | 246 | } |
265 | 247 | ||
266 | /* allocate new data chunk */ | 248 | /* Ensure the lv is set up according to ->iop_size */ |
267 | lv = kmem_zalloc(buf_size, KM_SLEEP|KM_NOFS); | ||
268 | lv->lv_item = lip; | ||
269 | lv->lv_size = buf_size; | ||
270 | lv->lv_niovecs = niovecs; | 249 | lv->lv_niovecs = niovecs; |
271 | if (ordered) { | ||
272 | /* track as an ordered logvec */ | ||
273 | ASSERT(lip->li_lv == NULL); | ||
274 | lv->lv_buf_len = XFS_LOG_VEC_ORDERED; | ||
275 | goto insert; | ||
276 | } | ||
277 | |||
278 | /* The allocated iovec region lies beyond the log vector. */ | ||
279 | lv->lv_iovecp = (struct xfs_log_iovec *)&lv[1]; | ||
280 | 250 | ||
281 | /* The allocated data region lies beyond the iovec region */ | 251 | /* The allocated data region lies beyond the iovec region */ |
252 | lv->lv_buf_len = 0; | ||
282 | lv->lv_buf = (char *)lv + buf_size - nbytes; | 253 | lv->lv_buf = (char *)lv + buf_size - nbytes; |
283 | 254 | lip->li_ops->iop_format(lip, lv); | |
284 | lv->lv_buf_len = xlog_cil_lv_item_format(lip, lv); | ||
285 | insert: | 255 | insert: |
286 | ASSERT(lv->lv_buf_len <= nbytes); | 256 | ASSERT(lv->lv_buf_len <= nbytes); |
287 | xfs_cil_prepare_item(log, lv, old_lv, diff_len, diff_iovecs); | 257 | xfs_cil_prepare_item(log, lv, old_lv, diff_len, diff_iovecs); |