aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_buf_item.c29
-rw-r--r--fs/xfs/xfs_dquot_item.c19
-rw-r--r--fs/xfs/xfs_extfree_item.c10
-rw-r--r--fs/xfs/xfs_icreate_item.c5
-rw-r--r--fs/xfs/xfs_inode_item.c92
-rw-r--r--fs/xfs/xfs_log.h41
-rw-r--r--fs/xfs/xfs_log_cil.c41
-rw-r--r--fs/xfs/xfs_trans.h2
8 files changed, 125 insertions, 114 deletions
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index d49419d4bb46..764117305438 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -184,6 +184,7 @@ xfs_buf_item_size(
184 184
185static inline void 185static inline void
186xfs_buf_item_copy_iovec( 186xfs_buf_item_copy_iovec(
187 struct xfs_log_vec *lv,
187 struct xfs_log_iovec **vecp, 188 struct xfs_log_iovec **vecp,
188 struct xfs_buf *bp, 189 struct xfs_buf *bp,
189 uint offset, 190 uint offset,
@@ -191,7 +192,7 @@ xfs_buf_item_copy_iovec(
191 uint nbits) 192 uint nbits)
192{ 193{
193 offset += first_bit * XFS_BLF_CHUNK; 194 offset += first_bit * XFS_BLF_CHUNK;
194 xlog_copy_iovec(vecp, XLOG_REG_TYPE_BCHUNK, 195 xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_BCHUNK,
195 xfs_buf_offset(bp, offset), 196 xfs_buf_offset(bp, offset),
196 nbits * XFS_BLF_CHUNK); 197 nbits * XFS_BLF_CHUNK);
197} 198}
@@ -211,13 +212,13 @@ xfs_buf_item_straddle(
211static void 212static void
212xfs_buf_item_format_segment( 213xfs_buf_item_format_segment(
213 struct xfs_buf_log_item *bip, 214 struct xfs_buf_log_item *bip,
215 struct xfs_log_vec *lv,
214 struct xfs_log_iovec **vecp, 216 struct xfs_log_iovec **vecp,
215 uint offset, 217 uint offset,
216 struct xfs_buf_log_format *blfp) 218 struct xfs_buf_log_format *blfp)
217{ 219{
218 struct xfs_buf *bp = bip->bli_buf; 220 struct xfs_buf *bp = bip->bli_buf;
219 uint base_size; 221 uint base_size;
220 uint nvecs;
221 int first_bit; 222 int first_bit;
222 int last_bit; 223 int last_bit;
223 int next_bit; 224 int next_bit;
@@ -233,18 +234,17 @@ xfs_buf_item_format_segment(
233 */ 234 */
234 base_size = xfs_buf_log_format_size(blfp); 235 base_size = xfs_buf_log_format_size(blfp);
235 236
236 nvecs = 0;
237 first_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size, 0); 237 first_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size, 0);
238 if (!(bip->bli_flags & XFS_BLI_STALE) && first_bit == -1) { 238 if (!(bip->bli_flags & XFS_BLI_STALE) && first_bit == -1) {
239 /* 239 /*
240 * If the map is not be dirty in the transaction, mark 240 * If the map is not be dirty in the transaction, mark
241 * the size as zero and do not advance the vector pointer. 241 * the size as zero and do not advance the vector pointer.
242 */ 242 */
243 goto out; 243 return;
244 } 244 }
245 245
246 xlog_copy_iovec(vecp, XLOG_REG_TYPE_BFORMAT, blfp, base_size); 246 blfp = xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_BFORMAT, blfp, base_size);
247 nvecs = 1; 247 blfp->blf_size = 1;
248 248
249 if (bip->bli_flags & XFS_BLI_STALE) { 249 if (bip->bli_flags & XFS_BLI_STALE) {
250 /* 250 /*
@@ -254,7 +254,7 @@ xfs_buf_item_format_segment(
254 */ 254 */
255 trace_xfs_buf_item_format_stale(bip); 255 trace_xfs_buf_item_format_stale(bip);
256 ASSERT(blfp->blf_flags & XFS_BLF_CANCEL); 256 ASSERT(blfp->blf_flags & XFS_BLF_CANCEL);
257 goto out; 257 return;
258 } 258 }
259 259
260 260
@@ -280,15 +280,15 @@ xfs_buf_item_format_segment(
280 * same set of bits so just keep counting and scanning. 280 * same set of bits so just keep counting and scanning.
281 */ 281 */
282 if (next_bit == -1) { 282 if (next_bit == -1) {
283 xfs_buf_item_copy_iovec(vecp, bp, offset, 283 xfs_buf_item_copy_iovec(lv, vecp, bp, offset,
284 first_bit, nbits); 284 first_bit, nbits);
285 nvecs++; 285 blfp->blf_size++;
286 break; 286 break;
287 } else if (next_bit != last_bit + 1 || 287 } else if (next_bit != last_bit + 1 ||
288 xfs_buf_item_straddle(bp, offset, next_bit, last_bit)) { 288 xfs_buf_item_straddle(bp, offset, next_bit, last_bit)) {
289 xfs_buf_item_copy_iovec(vecp, bp, offset, 289 xfs_buf_item_copy_iovec(lv, vecp, bp, offset,
290 first_bit, nbits); 290 first_bit, nbits);
291 nvecs++; 291 blfp->blf_size++;
292 first_bit = next_bit; 292 first_bit = next_bit;
293 last_bit = next_bit; 293 last_bit = next_bit;
294 nbits = 1; 294 nbits = 1;
@@ -297,8 +297,6 @@ xfs_buf_item_format_segment(
297 nbits++; 297 nbits++;
298 } 298 }
299 } 299 }
300out:
301 blfp->blf_size = nvecs;
302} 300}
303 301
304/* 302/*
@@ -310,10 +308,11 @@ out:
310STATIC void 308STATIC void
311xfs_buf_item_format( 309xfs_buf_item_format(
312 struct xfs_log_item *lip, 310 struct xfs_log_item *lip,
313 struct xfs_log_iovec *vecp) 311 struct xfs_log_vec *lv)
314{ 312{
315 struct xfs_buf_log_item *bip = BUF_ITEM(lip); 313 struct xfs_buf_log_item *bip = BUF_ITEM(lip);
316 struct xfs_buf *bp = bip->bli_buf; 314 struct xfs_buf *bp = bip->bli_buf;
315 struct xfs_log_iovec *vecp = NULL;
317 uint offset = 0; 316 uint offset = 0;
318 int i; 317 int i;
319 318
@@ -354,7 +353,7 @@ xfs_buf_item_format(
354 } 353 }
355 354
356 for (i = 0; i < bip->bli_format_count; i++) { 355 for (i = 0; i < bip->bli_format_count; i++) {
357 xfs_buf_item_format_segment(bip, &vecp, offset, 356 xfs_buf_item_format_segment(bip, lv, &vecp, offset,
358 &bip->bli_formats[i]); 357 &bip->bli_formats[i]);
359 offset += bp->b_maps[i].bm_len; 358 offset += bp->b_maps[i].bm_len;
360 } 359 }
diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c
index ca354a821838..946d588070b0 100644
--- a/fs/xfs/xfs_dquot_item.c
+++ b/fs/xfs/xfs_dquot_item.c
@@ -57,18 +57,19 @@ xfs_qm_dquot_logitem_size(
57STATIC void 57STATIC void
58xfs_qm_dquot_logitem_format( 58xfs_qm_dquot_logitem_format(
59 struct xfs_log_item *lip, 59 struct xfs_log_item *lip,
60 struct xfs_log_iovec *vecp) 60 struct xfs_log_vec *lv)
61{ 61{
62 struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip); 62 struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip);
63 struct xfs_log_iovec *vecp = NULL;
63 64
64 xlog_copy_iovec(&vecp, XLOG_REG_TYPE_QFORMAT, 65 qlip->qli_format.qlf_size = 2;
66
67 xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_QFORMAT,
65 &qlip->qli_format, 68 &qlip->qli_format,
66 sizeof(struct xfs_dq_logformat)); 69 sizeof(struct xfs_dq_logformat));
67 xlog_copy_iovec(&vecp, XLOG_REG_TYPE_DQUOT, 70 xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT,
68 &qlip->qli_dquot->q_core, 71 &qlip->qli_dquot->q_core,
69 sizeof(struct xfs_disk_dquot)); 72 sizeof(struct xfs_disk_dquot));
70
71 qlip->qli_format.qlf_size = 2;
72} 73}
73 74
74/* 75/*
@@ -302,17 +303,17 @@ xfs_qm_qoff_logitem_size(
302STATIC void 303STATIC void
303xfs_qm_qoff_logitem_format( 304xfs_qm_qoff_logitem_format(
304 struct xfs_log_item *lip, 305 struct xfs_log_item *lip,
305 struct xfs_log_iovec *vecp) 306 struct xfs_log_vec *lv)
306{ 307{
307 struct xfs_qoff_logitem *qflip = QOFF_ITEM(lip); 308 struct xfs_qoff_logitem *qflip = QOFF_ITEM(lip);
309 struct xfs_log_iovec *vecp = NULL;
308 310
309 ASSERT(qflip->qql_format.qf_type == XFS_LI_QUOTAOFF); 311 ASSERT(qflip->qql_format.qf_type == XFS_LI_QUOTAOFF);
312 qflip->qql_format.qf_size = 1;
310 313
311 xlog_copy_iovec(&vecp, XLOG_REG_TYPE_QUOTAOFF, 314 xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_QUOTAOFF,
312 &qflip->qql_format, 315 &qflip->qql_format,
313 sizeof(struct xfs_qoff_logitem)); 316 sizeof(struct xfs_qoff_logitem));
314
315 qflip->qql_format.qf_size = 1;
316} 317}
317 318
318/* 319/*
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index 08823ecbcd82..fb7a4c1ce1c5 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -102,9 +102,10 @@ xfs_efi_item_size(
102STATIC void 102STATIC void
103xfs_efi_item_format( 103xfs_efi_item_format(
104 struct xfs_log_item *lip, 104 struct xfs_log_item *lip,
105 struct xfs_log_iovec *vecp) 105 struct xfs_log_vec *lv)
106{ 106{
107 struct xfs_efi_log_item *efip = EFI_ITEM(lip); 107 struct xfs_efi_log_item *efip = EFI_ITEM(lip);
108 struct xfs_log_iovec *vecp = NULL;
108 109
109 ASSERT(atomic_read(&efip->efi_next_extent) == 110 ASSERT(atomic_read(&efip->efi_next_extent) ==
110 efip->efi_format.efi_nextents); 111 efip->efi_format.efi_nextents);
@@ -112,7 +113,7 @@ xfs_efi_item_format(
112 efip->efi_format.efi_type = XFS_LI_EFI; 113 efip->efi_format.efi_type = XFS_LI_EFI;
113 efip->efi_format.efi_size = 1; 114 efip->efi_format.efi_size = 1;
114 115
115 xlog_copy_iovec(&vecp, XLOG_REG_TYPE_EFI_FORMAT, 116 xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFI_FORMAT,
116 &efip->efi_format, 117 &efip->efi_format,
117 xfs_efi_item_sizeof(efip)); 118 xfs_efi_item_sizeof(efip));
118} 119}
@@ -368,16 +369,17 @@ xfs_efd_item_size(
368STATIC void 369STATIC void
369xfs_efd_item_format( 370xfs_efd_item_format(
370 struct xfs_log_item *lip, 371 struct xfs_log_item *lip,
371 struct xfs_log_iovec *vecp) 372 struct xfs_log_vec *lv)
372{ 373{
373 struct xfs_efd_log_item *efdp = EFD_ITEM(lip); 374 struct xfs_efd_log_item *efdp = EFD_ITEM(lip);
375 struct xfs_log_iovec *vecp = NULL;
374 376
375 ASSERT(efdp->efd_next_extent == efdp->efd_format.efd_nextents); 377 ASSERT(efdp->efd_next_extent == efdp->efd_format.efd_nextents);
376 378
377 efdp->efd_format.efd_type = XFS_LI_EFD; 379 efdp->efd_format.efd_type = XFS_LI_EFD;
378 efdp->efd_format.efd_size = 1; 380 efdp->efd_format.efd_size = 1;
379 381
380 xlog_copy_iovec(&vecp, XLOG_REG_TYPE_EFD_FORMAT, 382 xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFD_FORMAT,
381 &efdp->efd_format, 383 &efdp->efd_format,
382 xfs_efd_item_sizeof(efdp)); 384 xfs_efd_item_sizeof(efdp));
383} 385}
diff --git a/fs/xfs/xfs_icreate_item.c b/fs/xfs/xfs_icreate_item.c
index 5751fa8580ee..7e4549233251 100644
--- a/fs/xfs/xfs_icreate_item.c
+++ b/fs/xfs/xfs_icreate_item.c
@@ -59,11 +59,12 @@ xfs_icreate_item_size(
59STATIC void 59STATIC void
60xfs_icreate_item_format( 60xfs_icreate_item_format(
61 struct xfs_log_item *lip, 61 struct xfs_log_item *lip,
62 struct xfs_log_iovec *vecp) 62 struct xfs_log_vec *lv)
63{ 63{
64 struct xfs_icreate_item *icp = ICR_ITEM(lip); 64 struct xfs_icreate_item *icp = ICR_ITEM(lip);
65 struct xfs_log_iovec *vecp = NULL;
65 66
66 xlog_copy_iovec(&vecp, XLOG_REG_TYPE_ICREATE, 67 xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ICREATE,
67 &icp->ic_format, 68 &icp->ic_format,
68 sizeof(struct xfs_icreate_log)); 69 sizeof(struct xfs_icreate_log));
69} 70}
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index c75e14beff06..6ab318f80c96 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -163,6 +163,7 @@ xfs_inode_item_size(
163STATIC int 163STATIC int
164xfs_inode_item_format_extents( 164xfs_inode_item_format_extents(
165 struct xfs_inode *ip, 165 struct xfs_inode *ip,
166 struct xfs_log_vec *lv,
166 struct xfs_log_iovec **vecp, 167 struct xfs_log_iovec **vecp,
167 int whichfork, 168 int whichfork,
168 int type) 169 int type)
@@ -177,7 +178,7 @@ xfs_inode_item_format_extents(
177 ip->i_itemp->ili_aextents_buf = ext_buffer; 178 ip->i_itemp->ili_aextents_buf = ext_buffer;
178 179
179 len = xfs_iextents_copy(ip, ext_buffer, whichfork); 180 len = xfs_iextents_copy(ip, ext_buffer, whichfork);
180 xlog_copy_iovec(vecp, type, ext_buffer, len); 181 xlog_copy_iovec(lv, vecp, type, ext_buffer, len);
181 return len; 182 return len;
182} 183}
183 184
@@ -212,8 +213,9 @@ xfs_inode_item_format_v1_inode(
212STATIC void 213STATIC void
213xfs_inode_item_format_data_fork( 214xfs_inode_item_format_data_fork(
214 struct xfs_inode_log_item *iip, 215 struct xfs_inode_log_item *iip,
215 struct xfs_log_iovec **vecp, 216 struct xfs_inode_log_format *ilf,
216 int *nvecs) 217 struct xfs_log_vec *lv,
218 struct xfs_log_iovec **vecp)
217{ 219{
218 struct xfs_inode *ip = iip->ili_inode; 220 struct xfs_inode *ip = iip->ili_inode;
219 size_t data_bytes; 221 size_t data_bytes;
@@ -239,19 +241,19 @@ xfs_inode_item_format_data_fork(
239 * extents, so just point to the 241 * extents, so just point to the
240 * real extents array. 242 * real extents array.
241 */ 243 */
242 xlog_copy_iovec(vecp, XLOG_REG_TYPE_IEXT, 244 xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IEXT,
243 ip->i_df.if_u1.if_extents, 245 ip->i_df.if_u1.if_extents,
244 ip->i_df.if_bytes); 246 ip->i_df.if_bytes);
245 iip->ili_format.ilf_dsize = ip->i_df.if_bytes; 247 ilf->ilf_dsize = ip->i_df.if_bytes;
246 } else 248 } else
247#endif 249#endif
248 { 250 {
249 iip->ili_format.ilf_dsize = 251 ilf->ilf_dsize =
250 xfs_inode_item_format_extents(ip, vecp, 252 xfs_inode_item_format_extents(ip, lv, vecp,
251 XFS_DATA_FORK, XLOG_REG_TYPE_IEXT); 253 XFS_DATA_FORK, XLOG_REG_TYPE_IEXT);
252 ASSERT(iip->ili_format.ilf_dsize <= ip->i_df.if_bytes); 254 ASSERT(iip->ili_format.ilf_dsize <= ip->i_df.if_bytes);
253 } 255 }
254 (*nvecs)++; 256 ilf->ilf_size++;
255 } else { 257 } else {
256 iip->ili_fields &= ~XFS_ILOG_DEXT; 258 iip->ili_fields &= ~XFS_ILOG_DEXT;
257 } 259 }
@@ -264,11 +266,11 @@ xfs_inode_item_format_data_fork(
264 if ((iip->ili_fields & XFS_ILOG_DBROOT) && 266 if ((iip->ili_fields & XFS_ILOG_DBROOT) &&
265 ip->i_df.if_broot_bytes > 0) { 267 ip->i_df.if_broot_bytes > 0) {
266 ASSERT(ip->i_df.if_broot != NULL); 268 ASSERT(ip->i_df.if_broot != NULL);
267 xlog_copy_iovec(vecp, XLOG_REG_TYPE_IBROOT, 269 xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IBROOT,
268 ip->i_df.if_broot, 270 ip->i_df.if_broot,
269 ip->i_df.if_broot_bytes); 271 ip->i_df.if_broot_bytes);
270 (*nvecs)++; 272 ilf->ilf_dsize = ip->i_df.if_broot_bytes;
271 iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes; 273 ilf->ilf_size++;
272 } else { 274 } else {
273 ASSERT(!(iip->ili_fields & 275 ASSERT(!(iip->ili_fields &
274 XFS_ILOG_DBROOT)); 276 XFS_ILOG_DBROOT));
@@ -291,10 +293,10 @@ xfs_inode_item_format_data_fork(
291 ip->i_df.if_real_bytes == data_bytes); 293 ip->i_df.if_real_bytes == data_bytes);
292 ASSERT(ip->i_df.if_u1.if_data != NULL); 294 ASSERT(ip->i_df.if_u1.if_data != NULL);
293 ASSERT(ip->i_d.di_size > 0); 295 ASSERT(ip->i_d.di_size > 0);
294 xlog_copy_iovec(vecp, XLOG_REG_TYPE_ILOCAL, 296 xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_ILOCAL,
295 ip->i_df.if_u1.if_data, data_bytes); 297 ip->i_df.if_u1.if_data, data_bytes);
296 (*nvecs)++; 298 ilf->ilf_dsize = (unsigned)data_bytes;
297 iip->ili_format.ilf_dsize = (unsigned)data_bytes; 299 ilf->ilf_size++;
298 } else { 300 } else {
299 iip->ili_fields &= ~XFS_ILOG_DDATA; 301 iip->ili_fields &= ~XFS_ILOG_DDATA;
300 } 302 }
@@ -303,19 +305,15 @@ xfs_inode_item_format_data_fork(
303 iip->ili_fields &= 305 iip->ili_fields &=
304 ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | 306 ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
305 XFS_ILOG_DEXT | XFS_ILOG_UUID); 307 XFS_ILOG_DEXT | XFS_ILOG_UUID);
306 if (iip->ili_fields & XFS_ILOG_DEV) { 308 if (iip->ili_fields & XFS_ILOG_DEV)
307 iip->ili_format.ilf_u.ilfu_rdev = 309 ilf->ilf_u.ilfu_rdev = ip->i_df.if_u2.if_rdev;
308 ip->i_df.if_u2.if_rdev;
309 }
310 break; 310 break;
311 case XFS_DINODE_FMT_UUID: 311 case XFS_DINODE_FMT_UUID:
312 iip->ili_fields &= 312 iip->ili_fields &=
313 ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | 313 ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
314 XFS_ILOG_DEXT | XFS_ILOG_DEV); 314 XFS_ILOG_DEXT | XFS_ILOG_DEV);
315 if (iip->ili_fields & XFS_ILOG_UUID) { 315 if (iip->ili_fields & XFS_ILOG_UUID)
316 iip->ili_format.ilf_u.ilfu_uuid = 316 ilf->ilf_u.ilfu_uuid = ip->i_df.if_u2.if_uuid;
317 ip->i_df.if_u2.if_uuid;
318 }
319 break; 317 break;
320 default: 318 default:
321 ASSERT(0); 319 ASSERT(0);
@@ -326,8 +324,9 @@ xfs_inode_item_format_data_fork(
326STATIC void 324STATIC void
327xfs_inode_item_format_attr_fork( 325xfs_inode_item_format_attr_fork(
328 struct xfs_inode_log_item *iip, 326 struct xfs_inode_log_item *iip,
329 struct xfs_log_iovec **vecp, 327 struct xfs_inode_log_format *ilf,
330 int *nvecs) 328 struct xfs_log_vec *lv,
329 struct xfs_log_iovec **vecp)
331{ 330{
332 struct xfs_inode *ip = iip->ili_inode; 331 struct xfs_inode *ip = iip->ili_inode;
333 size_t data_bytes; 332 size_t data_bytes;
@@ -348,17 +347,17 @@ xfs_inode_item_format_attr_fork(
348 * There are not delayed allocation extents 347 * There are not delayed allocation extents
349 * for attributes, so just point at the array. 348 * for attributes, so just point at the array.
350 */ 349 */
351 xlog_copy_iovec(vecp, XLOG_REG_TYPE_IATTR_EXT, 350 xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_EXT,
352 ip->i_afp->if_u1.if_extents, 351 ip->i_afp->if_u1.if_extents,
353 ip->i_afp->if_bytes); 352 ip->i_afp->if_bytes);
354 iip->ili_format.ilf_asize = ip->i_afp->if_bytes; 353 ilf->ilf_asize = ip->i_afp->if_bytes;
355#else 354#else
356 ASSERT(iip->ili_aextents_buf == NULL); 355 ASSERT(iip->ili_aextents_buf == NULL);
357 iip->ili_format.ilf_asize = 356 ilf->ilf_asize =
358 xfs_inode_item_format_extents(ip, vecp, 357 xfs_inode_item_format_extents(ip, lv, vecp,
359 XFS_ATTR_FORK, XLOG_REG_TYPE_IATTR_EXT); 358 XFS_ATTR_FORK, XLOG_REG_TYPE_IATTR_EXT);
360#endif 359#endif
361 (*nvecs)++; 360 ilf->ilf_size++;
362 } else { 361 } else {
363 iip->ili_fields &= ~XFS_ILOG_AEXT; 362 iip->ili_fields &= ~XFS_ILOG_AEXT;
364 } 363 }
@@ -371,11 +370,11 @@ xfs_inode_item_format_attr_fork(
371 ip->i_afp->if_broot_bytes > 0) { 370 ip->i_afp->if_broot_bytes > 0) {
372 ASSERT(ip->i_afp->if_broot != NULL); 371 ASSERT(ip->i_afp->if_broot != NULL);
373 372
374 xlog_copy_iovec(vecp, XLOG_REG_TYPE_IATTR_BROOT, 373 xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_BROOT,
375 ip->i_afp->if_broot, 374 ip->i_afp->if_broot,
376 ip->i_afp->if_broot_bytes); 375 ip->i_afp->if_broot_bytes);
377 (*nvecs)++; 376 ilf->ilf_asize = ip->i_afp->if_broot_bytes;
378 iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes; 377 ilf->ilf_size++;
379 } else { 378 } else {
380 iip->ili_fields &= ~XFS_ILOG_ABROOT; 379 iip->ili_fields &= ~XFS_ILOG_ABROOT;
381 } 380 }
@@ -395,11 +394,11 @@ xfs_inode_item_format_attr_fork(
395 ASSERT(ip->i_afp->if_real_bytes == 0 || 394 ASSERT(ip->i_afp->if_real_bytes == 0 ||
396 ip->i_afp->if_real_bytes == data_bytes); 395 ip->i_afp->if_real_bytes == data_bytes);
397 ASSERT(ip->i_afp->if_u1.if_data != NULL); 396 ASSERT(ip->i_afp->if_u1.if_data != NULL);
398 xlog_copy_iovec(vecp, XLOG_REG_TYPE_IATTR_LOCAL, 397 xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_LOCAL,
399 ip->i_afp->if_u1.if_data, 398 ip->i_afp->if_u1.if_data,
400 data_bytes); 399 data_bytes);
401 (*nvecs)++; 400 ilf->ilf_asize = (unsigned)data_bytes;
402 iip->ili_format.ilf_asize = (unsigned)data_bytes; 401 ilf->ilf_size++;
403 } else { 402 } else {
404 iip->ili_fields &= ~XFS_ILOG_ADATA; 403 iip->ili_fields &= ~XFS_ILOG_ADATA;
405 } 404 }
@@ -420,28 +419,28 @@ xfs_inode_item_format_attr_fork(
420STATIC void 419STATIC void
421xfs_inode_item_format( 420xfs_inode_item_format(
422 struct xfs_log_item *lip, 421 struct xfs_log_item *lip,
423 struct xfs_log_iovec *vecp) 422 struct xfs_log_vec *lv)
424{ 423{
425 struct xfs_inode_log_item *iip = INODE_ITEM(lip); 424 struct xfs_inode_log_item *iip = INODE_ITEM(lip);
426 struct xfs_inode *ip = iip->ili_inode; 425 struct xfs_inode *ip = iip->ili_inode;
427 uint nvecs; 426 struct xfs_inode_log_format *ilf;
427 struct xfs_log_iovec *vecp = NULL;
428 428
429 xlog_copy_iovec(&vecp, XLOG_REG_TYPE_IFORMAT, 429 ilf = xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_IFORMAT,
430 &iip->ili_format, 430 &iip->ili_format,
431 sizeof(struct xfs_inode_log_format)); 431 sizeof(struct xfs_inode_log_format));
432 nvecs = 1; 432 ilf->ilf_size = 1;
433
434 xlog_copy_iovec(&vecp, XLOG_REG_TYPE_ICORE,
435 &ip->i_d,
436 xfs_icdinode_size(ip->i_d.di_version));
437 nvecs++;
438 433
439 if (ip->i_d.di_version == 1) 434 if (ip->i_d.di_version == 1)
440 xfs_inode_item_format_v1_inode(ip); 435 xfs_inode_item_format_v1_inode(ip);
436 xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ICORE,
437 &ip->i_d,
438 xfs_icdinode_size(ip->i_d.di_version));
439 ilf->ilf_size++;
441 440
442 xfs_inode_item_format_data_fork(iip, &vecp, &nvecs); 441 xfs_inode_item_format_data_fork(iip, ilf, lv, &vecp);
443 if (XFS_IFORK_Q(ip)) { 442 if (XFS_IFORK_Q(ip)) {
444 xfs_inode_item_format_attr_fork(iip, &vecp, &nvecs); 443 xfs_inode_item_format_attr_fork(iip, ilf, lv, &vecp);
445 } else { 444 } else {
446 iip->ili_fields &= 445 iip->ili_fields &=
447 ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT); 446 ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT);
@@ -455,7 +454,6 @@ xfs_inode_item_format(
455 */ 454 */
456 iip->ili_format.ilf_fields = XFS_ILOG_CORE | 455 iip->ili_format.ilf_fields = XFS_ILOG_CORE |
457 (iip->ili_fields & ~XFS_ILOG_TIMESTAMP); 456 (iip->ili_fields & ~XFS_ILOG_TIMESTAMP);
458 iip->ili_format.ilf_size = nvecs;
459} 457}
460 458
461/* 459/*
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
index 384c6c469661..b0f4ef77fa70 100644
--- a/fs/xfs/xfs_log.h
+++ b/fs/xfs/xfs_log.h
@@ -31,18 +31,51 @@ struct xfs_log_vec {
31#define XFS_LOG_VEC_ORDERED (-1) 31#define XFS_LOG_VEC_ORDERED (-1)
32 32
33static inline void * 33static inline void *
34xlog_copy_iovec(struct xfs_log_iovec **vecp, uint type, void *data, int len) 34xlog_prepare_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec **vecp,
35 uint type)
35{ 36{
36 struct xfs_log_iovec *vec = *vecp; 37 struct xfs_log_iovec *vec = *vecp;
37 38
39 if (vec) {
40 ASSERT(vec - lv->lv_iovecp < lv->lv_niovecs);
41 vec++;
42 } else {
43 vec = &lv->lv_iovecp[0];
44 }
45
38 vec->i_type = type; 46 vec->i_type = type;
39 vec->i_addr = data; 47 vec->i_addr = lv->lv_buf + lv->lv_buf_len;
40 vec->i_len = len; 48
49 ASSERT(IS_ALIGNED((unsigned long)vec->i_addr, sizeof(uint64_t)));
41 50
42 *vecp = vec + 1; 51 *vecp = vec;
43 return vec->i_addr; 52 return vec->i_addr;
44} 53}
45 54
55static inline void
56xlog_finish_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec *vec, int len)
57{
58 /*
59 * We need to make sure the next buffer is naturally aligned for the
60 * biggest basic data type we put into it. We already accounted for
61 * this when sizing the buffer.
62 */
63 lv->lv_buf_len += round_up(len, sizeof(uint64_t));
64 vec->i_len = len;
65}
66
67static inline void *
68xlog_copy_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec **vecp,
69 uint type, void *data, int len)
70{
71 void *buf;
72
73 buf = xlog_prepare_iovec(lv, vecp, type);
74 memcpy(buf, data, len);
75 xlog_finish_iovec(lv, *vecp, len);
76 return buf;
77}
78
46/* 79/*
47 * Structure used to pass callback function and the function's argument 80 * Structure used to pass callback function and the function's argument
48 * to the log manager. 81 * to the log manager.
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
index 0a7a8cef6019..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
85STATIC int
86xlog_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
@@ -272,9 +249,9 @@ xlog_cil_insert_format_items(
272 lv->lv_niovecs = niovecs; 249 lv->lv_niovecs = niovecs;
273 250
274 /* 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;
275 lv->lv_buf = (char *)lv + buf_size - nbytes; 253 lv->lv_buf = (char *)lv + buf_size - nbytes;
276 254 lip->li_ops->iop_format(lip, lv);
277 lv->lv_buf_len = xlog_cil_lv_item_format(lip, lv);
278insert: 255insert:
279 ASSERT(lv->lv_buf_len <= nbytes); 256 ASSERT(lv->lv_buf_len <= nbytes);
280 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);
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index 9b96d35e483d..b5bc1ab3c4da 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -64,7 +64,7 @@ typedef struct xfs_log_item {
64 64
65struct xfs_item_ops { 65struct xfs_item_ops {
66 void (*iop_size)(xfs_log_item_t *, int *, int *); 66 void (*iop_size)(xfs_log_item_t *, int *, int *);
67 void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *); 67 void (*iop_format)(xfs_log_item_t *, struct xfs_log_vec *);
68 void (*iop_pin)(xfs_log_item_t *); 68 void (*iop_pin)(xfs_log_item_t *);
69 void (*iop_unpin)(xfs_log_item_t *, int remove); 69 void (*iop_unpin)(xfs_log_item_t *, int remove);
70 uint (*iop_push)(struct xfs_log_item *, struct list_head *); 70 uint (*iop_push)(struct xfs_log_item *, struct list_head *);