Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xfs: format log items write directly into the linear CIL buffer

Instead of setting up pointers to memory locations in iop_format which then
get copied into the CIL linear buffer after return move the copy into
the individual inode items. This avoids the need to always have a memory
block in the exact same layout that gets written into the log around, and
allow the log items to be much more flexible in their in-memory layouts.

The only caveat is that we need to properly align the data for each
iovec so that don't have structures misaligned in subsequent iovecs.

Note that all log item format routines now need to be careful to modify
the copy of the item that was placed into the CIL after calls to
xlog_copy_iovec instead of the in-memory copy.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>

authored by

Christoph Hellwig and committed by
Dave Chinner
bde7cff6 1234351c

+129 -118
+14 -15
fs/xfs/xfs_buf_item.c
··· 184 184 185 185 static inline void 186 186 xfs_buf_item_copy_iovec( 187 + struct xfs_log_vec *lv, 187 188 struct xfs_log_iovec **vecp, 188 189 struct xfs_buf *bp, 189 190 uint offset, ··· 192 191 uint nbits) 193 192 { 194 193 offset += first_bit * XFS_BLF_CHUNK; 195 - xlog_copy_iovec(vecp, XLOG_REG_TYPE_BCHUNK, 194 + xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_BCHUNK, 196 195 xfs_buf_offset(bp, offset), 197 196 nbits * XFS_BLF_CHUNK); 198 197 } ··· 212 211 static void 213 212 xfs_buf_item_format_segment( 214 213 struct xfs_buf_log_item *bip, 214 + struct xfs_log_vec *lv, 215 215 struct xfs_log_iovec **vecp, 216 216 uint offset, 217 217 struct xfs_buf_log_format *blfp) 218 218 { 219 219 struct xfs_buf *bp = bip->bli_buf; 220 220 uint base_size; 221 - uint nvecs; 222 221 int first_bit; 223 222 int last_bit; 224 223 int next_bit; ··· 234 233 */ 235 234 base_size = xfs_buf_log_format_size(blfp); 236 235 237 - nvecs = 0; 238 236 first_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size, 0); 239 237 if (!(bip->bli_flags & XFS_BLI_STALE) && first_bit == -1) { 240 238 /* 241 239 * If the map is not be dirty in the transaction, mark 242 240 * the size as zero and do not advance the vector pointer. 243 241 */ 244 - goto out; 242 + return; 245 243 } 246 244 247 - xlog_copy_iovec(vecp, XLOG_REG_TYPE_BFORMAT, blfp, base_size); 248 - nvecs = 1; 245 + blfp = xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_BFORMAT, blfp, base_size); 246 + blfp->blf_size = 1; 249 247 250 248 if (bip->bli_flags & XFS_BLI_STALE) { 251 249 /* ··· 254 254 */ 255 255 trace_xfs_buf_item_format_stale(bip); 256 256 ASSERT(blfp->blf_flags & XFS_BLF_CANCEL); 257 - goto out; 257 + return; 258 258 } 259 259 260 260 ··· 280 280 * same set of bits so just keep counting and scanning. 281 281 */ 282 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 284 first_bit, nbits); 285 - nvecs++; 285 + blfp->blf_size++; 286 286 break; 287 287 } else if (next_bit != last_bit + 1 || 288 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 290 first_bit, nbits); 291 - nvecs++; 291 + blfp->blf_size++; 292 292 first_bit = next_bit; 293 293 last_bit = next_bit; 294 294 nbits = 1; ··· 297 297 nbits++; 298 298 } 299 299 } 300 - out: 301 - blfp->blf_size = nvecs; 302 300 } 303 301 304 302 /* ··· 308 310 STATIC void 309 311 xfs_buf_item_format( 310 312 struct xfs_log_item *lip, 311 - struct xfs_log_iovec *vecp) 313 + struct xfs_log_vec *lv) 312 314 { 313 315 struct xfs_buf_log_item *bip = BUF_ITEM(lip); 314 316 struct xfs_buf *bp = bip->bli_buf; 317 + struct xfs_log_iovec *vecp = NULL; 315 318 uint offset = 0; 316 319 int i; 317 320 ··· 353 354 } 354 355 355 356 for (i = 0; i < bip->bli_format_count; i++) { 356 - xfs_buf_item_format_segment(bip, &vecp, offset, 357 + xfs_buf_item_format_segment(bip, lv, &vecp, offset, 357 358 &bip->bli_formats[i]); 358 359 offset += bp->b_maps[i].bm_len; 359 360 }
+13 -12
fs/xfs/xfs_dquot_item.c
··· 57 57 STATIC void 58 58 xfs_qm_dquot_logitem_format( 59 59 struct xfs_log_item *lip, 60 - struct xfs_log_iovec *vecp) 60 + struct xfs_log_vec *lv) 61 61 { 62 62 struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip); 63 - 64 - xlog_copy_iovec(&vecp, XLOG_REG_TYPE_QFORMAT, 65 - &qlip->qli_format, 66 - sizeof(struct xfs_dq_logformat)); 67 - xlog_copy_iovec(&vecp, XLOG_REG_TYPE_DQUOT, 68 - &qlip->qli_dquot->q_core, 69 - sizeof(struct xfs_disk_dquot)); 63 + struct xfs_log_iovec *vecp = NULL; 70 64 71 65 qlip->qli_format.qlf_size = 2; 66 + 67 + xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_QFORMAT, 68 + &qlip->qli_format, 69 + sizeof(struct xfs_dq_logformat)); 70 + xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT, 71 + &qlip->qli_dquot->q_core, 72 + sizeof(struct xfs_disk_dquot)); 72 73 } 73 74 74 75 /* ··· 303 302 STATIC void 304 303 xfs_qm_qoff_logitem_format( 305 304 struct xfs_log_item *lip, 306 - struct xfs_log_iovec *vecp) 305 + struct xfs_log_vec *lv) 307 306 { 308 307 struct xfs_qoff_logitem *qflip = QOFF_ITEM(lip); 308 + struct xfs_log_iovec *vecp = NULL; 309 309 310 310 ASSERT(qflip->qql_format.qf_type == XFS_LI_QUOTAOFF); 311 + qflip->qql_format.qf_size = 1; 311 312 312 - xlog_copy_iovec(&vecp, XLOG_REG_TYPE_QUOTAOFF, 313 + xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_QUOTAOFF, 313 314 &qflip->qql_format, 314 315 sizeof(struct xfs_qoff_logitem)); 315 - 316 - qflip->qql_format.qf_size = 1; 317 316 } 318 317 319 318 /*
+6 -4
fs/xfs/xfs_extfree_item.c
··· 102 102 STATIC void 103 103 xfs_efi_item_format( 104 104 struct xfs_log_item *lip, 105 - struct xfs_log_iovec *vecp) 105 + struct xfs_log_vec *lv) 106 106 { 107 107 struct xfs_efi_log_item *efip = EFI_ITEM(lip); 108 + struct xfs_log_iovec *vecp = NULL; 108 109 109 110 ASSERT(atomic_read(&efip->efi_next_extent) == 110 111 efip->efi_format.efi_nextents); ··· 113 112 efip->efi_format.efi_type = XFS_LI_EFI; 114 113 efip->efi_format.efi_size = 1; 115 114 116 - xlog_copy_iovec(&vecp, XLOG_REG_TYPE_EFI_FORMAT, 115 + xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFI_FORMAT, 117 116 &efip->efi_format, 118 117 xfs_efi_item_sizeof(efip)); 119 118 } ··· 369 368 STATIC void 370 369 xfs_efd_item_format( 371 370 struct xfs_log_item *lip, 372 - struct xfs_log_iovec *vecp) 371 + struct xfs_log_vec *lv) 373 372 { 374 373 struct xfs_efd_log_item *efdp = EFD_ITEM(lip); 374 + struct xfs_log_iovec *vecp = NULL; 375 375 376 376 ASSERT(efdp->efd_next_extent == efdp->efd_format.efd_nextents); 377 377 378 378 efdp->efd_format.efd_type = XFS_LI_EFD; 379 379 efdp->efd_format.efd_size = 1; 380 380 381 - xlog_copy_iovec(&vecp, XLOG_REG_TYPE_EFD_FORMAT, 381 + xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFD_FORMAT, 382 382 &efdp->efd_format, 383 383 xfs_efd_item_sizeof(efdp)); 384 384 }
+3 -2
fs/xfs/xfs_icreate_item.c
··· 59 59 STATIC void 60 60 xfs_icreate_item_format( 61 61 struct xfs_log_item *lip, 62 - struct xfs_log_iovec *vecp) 62 + struct xfs_log_vec *lv) 63 63 { 64 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 68 &icp->ic_format, 68 69 sizeof(struct xfs_icreate_log)); 69 70 }
+45 -47
fs/xfs/xfs_inode_item.c
··· 163 163 STATIC int 164 164 xfs_inode_item_format_extents( 165 165 struct xfs_inode *ip, 166 + struct xfs_log_vec *lv, 166 167 struct xfs_log_iovec **vecp, 167 168 int whichfork, 168 169 int type) ··· 178 177 ip->i_itemp->ili_aextents_buf = ext_buffer; 179 178 180 179 len = xfs_iextents_copy(ip, ext_buffer, whichfork); 181 - xlog_copy_iovec(vecp, type, ext_buffer, len); 180 + xlog_copy_iovec(lv, vecp, type, ext_buffer, len); 182 181 return len; 183 182 } 184 183 ··· 213 212 STATIC void 214 213 xfs_inode_item_format_data_fork( 215 214 struct xfs_inode_log_item *iip, 216 - struct xfs_log_iovec **vecp, 217 - int *nvecs) 215 + struct xfs_inode_log_format *ilf, 216 + struct xfs_log_vec *lv, 217 + struct xfs_log_iovec **vecp) 218 218 { 219 219 struct xfs_inode *ip = iip->ili_inode; 220 220 size_t data_bytes; ··· 241 239 * extents, so just point to the 242 240 * real extents array. 243 241 */ 244 - xlog_copy_iovec(vecp, XLOG_REG_TYPE_IEXT, 242 + xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IEXT, 245 243 ip->i_df.if_u1.if_extents, 246 244 ip->i_df.if_bytes); 247 - iip->ili_format.ilf_dsize = ip->i_df.if_bytes; 245 + ilf->ilf_dsize = ip->i_df.if_bytes; 248 246 } else 249 247 #endif 250 248 { 251 - iip->ili_format.ilf_dsize = 252 - xfs_inode_item_format_extents(ip, vecp, 249 + ilf->ilf_dsize = 250 + xfs_inode_item_format_extents(ip, lv, vecp, 253 251 XFS_DATA_FORK, XLOG_REG_TYPE_IEXT); 254 252 ASSERT(iip->ili_format.ilf_dsize <= ip->i_df.if_bytes); 255 253 } 256 - (*nvecs)++; 254 + ilf->ilf_size++; 257 255 } else { 258 256 iip->ili_fields &= ~XFS_ILOG_DEXT; 259 257 } ··· 266 264 if ((iip->ili_fields & XFS_ILOG_DBROOT) && 267 265 ip->i_df.if_broot_bytes > 0) { 268 266 ASSERT(ip->i_df.if_broot != NULL); 269 - xlog_copy_iovec(vecp, XLOG_REG_TYPE_IBROOT, 267 + xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IBROOT, 270 268 ip->i_df.if_broot, 271 269 ip->i_df.if_broot_bytes); 272 - (*nvecs)++; 273 - iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes; 270 + ilf->ilf_dsize = ip->i_df.if_broot_bytes; 271 + ilf->ilf_size++; 274 272 } else { 275 273 ASSERT(!(iip->ili_fields & 276 274 XFS_ILOG_DBROOT)); ··· 293 291 ip->i_df.if_real_bytes == data_bytes); 294 292 ASSERT(ip->i_df.if_u1.if_data != NULL); 295 293 ASSERT(ip->i_d.di_size > 0); 296 - xlog_copy_iovec(vecp, XLOG_REG_TYPE_ILOCAL, 294 + xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_ILOCAL, 297 295 ip->i_df.if_u1.if_data, data_bytes); 298 - (*nvecs)++; 299 - iip->ili_format.ilf_dsize = (unsigned)data_bytes; 296 + ilf->ilf_dsize = (unsigned)data_bytes; 297 + ilf->ilf_size++; 300 298 } else { 301 299 iip->ili_fields &= ~XFS_ILOG_DDATA; 302 300 } ··· 305 303 iip->ili_fields &= 306 304 ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | 307 305 XFS_ILOG_DEXT | XFS_ILOG_UUID); 308 - if (iip->ili_fields & XFS_ILOG_DEV) { 309 - iip->ili_format.ilf_u.ilfu_rdev = 310 - ip->i_df.if_u2.if_rdev; 311 - } 306 + if (iip->ili_fields & XFS_ILOG_DEV) 307 + ilf->ilf_u.ilfu_rdev = ip->i_df.if_u2.if_rdev; 312 308 break; 313 309 case XFS_DINODE_FMT_UUID: 314 310 iip->ili_fields &= 315 311 ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | 316 312 XFS_ILOG_DEXT | XFS_ILOG_DEV); 317 - if (iip->ili_fields & XFS_ILOG_UUID) { 318 - iip->ili_format.ilf_u.ilfu_uuid = 319 - ip->i_df.if_u2.if_uuid; 320 - } 313 + if (iip->ili_fields & XFS_ILOG_UUID) 314 + ilf->ilf_u.ilfu_uuid = ip->i_df.if_u2.if_uuid; 321 315 break; 322 316 default: 323 317 ASSERT(0); ··· 324 326 STATIC void 325 327 xfs_inode_item_format_attr_fork( 326 328 struct xfs_inode_log_item *iip, 327 - struct xfs_log_iovec **vecp, 328 - int *nvecs) 329 + struct xfs_inode_log_format *ilf, 330 + struct xfs_log_vec *lv, 331 + struct xfs_log_iovec **vecp) 329 332 { 330 333 struct xfs_inode *ip = iip->ili_inode; 331 334 size_t data_bytes; ··· 347 348 * There are not delayed allocation extents 348 349 * for attributes, so just point at the array. 349 350 */ 350 - xlog_copy_iovec(vecp, XLOG_REG_TYPE_IATTR_EXT, 351 + xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_EXT, 351 352 ip->i_afp->if_u1.if_extents, 352 353 ip->i_afp->if_bytes); 353 - iip->ili_format.ilf_asize = ip->i_afp->if_bytes; 354 + ilf->ilf_asize = ip->i_afp->if_bytes; 354 355 #else 355 356 ASSERT(iip->ili_aextents_buf == NULL); 356 - iip->ili_format.ilf_asize = 357 - xfs_inode_item_format_extents(ip, vecp, 357 + ilf->ilf_asize = 358 + xfs_inode_item_format_extents(ip, lv, vecp, 358 359 XFS_ATTR_FORK, XLOG_REG_TYPE_IATTR_EXT); 359 360 #endif 360 - (*nvecs)++; 361 + ilf->ilf_size++; 361 362 } else { 362 363 iip->ili_fields &= ~XFS_ILOG_AEXT; 363 364 } ··· 370 371 ip->i_afp->if_broot_bytes > 0) { 371 372 ASSERT(ip->i_afp->if_broot != NULL); 372 373 373 - xlog_copy_iovec(vecp, XLOG_REG_TYPE_IATTR_BROOT, 374 + xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_BROOT, 374 375 ip->i_afp->if_broot, 375 376 ip->i_afp->if_broot_bytes); 376 - (*nvecs)++; 377 - iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes; 377 + ilf->ilf_asize = ip->i_afp->if_broot_bytes; 378 + ilf->ilf_size++; 378 379 } else { 379 380 iip->ili_fields &= ~XFS_ILOG_ABROOT; 380 381 } ··· 394 395 ASSERT(ip->i_afp->if_real_bytes == 0 || 395 396 ip->i_afp->if_real_bytes == data_bytes); 396 397 ASSERT(ip->i_afp->if_u1.if_data != NULL); 397 - xlog_copy_iovec(vecp, XLOG_REG_TYPE_IATTR_LOCAL, 398 + xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_LOCAL, 398 399 ip->i_afp->if_u1.if_data, 399 400 data_bytes); 400 - (*nvecs)++; 401 - iip->ili_format.ilf_asize = (unsigned)data_bytes; 401 + ilf->ilf_asize = (unsigned)data_bytes; 402 + ilf->ilf_size++; 402 403 } else { 403 404 iip->ili_fields &= ~XFS_ILOG_ADATA; 404 405 } ··· 419 420 STATIC void 420 421 xfs_inode_item_format( 421 422 struct xfs_log_item *lip, 422 - struct xfs_log_iovec *vecp) 423 + struct xfs_log_vec *lv) 423 424 { 424 425 struct xfs_inode_log_item *iip = INODE_ITEM(lip); 425 426 struct xfs_inode *ip = iip->ili_inode; 426 - uint nvecs; 427 + struct xfs_inode_log_format *ilf; 428 + struct xfs_log_iovec *vecp = NULL; 427 429 428 - xlog_copy_iovec(&vecp, XLOG_REG_TYPE_IFORMAT, 430 + ilf = xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_IFORMAT, 429 431 &iip->ili_format, 430 432 sizeof(struct xfs_inode_log_format)); 431 - nvecs = 1; 432 - 433 - xlog_copy_iovec(&vecp, XLOG_REG_TYPE_ICORE, 434 - &ip->i_d, 435 - xfs_icdinode_size(ip->i_d.di_version)); 436 - nvecs++; 433 + ilf->ilf_size = 1; 437 434 438 435 if (ip->i_d.di_version == 1) 439 436 xfs_inode_item_format_v1_inode(ip); 437 + xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ICORE, 438 + &ip->i_d, 439 + xfs_icdinode_size(ip->i_d.di_version)); 440 + ilf->ilf_size++; 440 441 441 - xfs_inode_item_format_data_fork(iip, &vecp, &nvecs); 442 + xfs_inode_item_format_data_fork(iip, ilf, lv, &vecp); 442 443 if (XFS_IFORK_Q(ip)) { 443 - xfs_inode_item_format_attr_fork(iip, &vecp, &nvecs); 444 + xfs_inode_item_format_attr_fork(iip, ilf, lv, &vecp); 444 445 } else { 445 446 iip->ili_fields &= 446 447 ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT); ··· 454 455 */ 455 456 iip->ili_format.ilf_fields = XFS_ILOG_CORE | 456 457 (iip->ili_fields & ~XFS_ILOG_TIMESTAMP); 457 - iip->ili_format.ilf_size = nvecs; 458 458 } 459 459 460 460 /*
+38 -5
fs/xfs/xfs_log.h
··· 31 31 #define XFS_LOG_VEC_ORDERED (-1) 32 32 33 33 static inline void * 34 - xlog_copy_iovec(struct xfs_log_iovec **vecp, uint type, void *data, int len) 34 + xlog_prepare_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec **vecp, 35 + uint type) 35 36 { 36 37 struct xfs_log_iovec *vec = *vecp; 37 38 38 - vec->i_type = type; 39 - vec->i_addr = data; 40 - vec->i_len = len; 39 + if (vec) { 40 + ASSERT(vec - lv->lv_iovecp < lv->lv_niovecs); 41 + vec++; 42 + } else { 43 + vec = &lv->lv_iovecp[0]; 44 + } 41 45 42 - *vecp = vec + 1; 46 + vec->i_type = type; 47 + vec->i_addr = lv->lv_buf + lv->lv_buf_len; 48 + 49 + ASSERT(IS_ALIGNED((unsigned long)vec->i_addr, sizeof(uint64_t))); 50 + 51 + *vecp = vec; 43 52 return vec->i_addr; 53 + } 54 + 55 + static inline void 56 + xlog_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 + 67 + static inline void * 68 + xlog_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; 44 77 } 45 78 46 79 /*
+9 -32
fs/xfs/xfs_log_cil.c
··· 82 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 86 * Prepare the log item for insertion into the CIL. Calculate the difference in 117 87 * log space and vectors it will consume, and if it is a new item pin it as ··· 202 232 nbytes = 0; 203 233 } 204 234 235 + /* 236 + * We 64-bit align the length of each iovec so that the start 237 + * of the next one is naturally aligned. We'll need to 238 + * account for that slack space here. 239 + */ 240 + nbytes += niovecs * sizeof(uint64_t); 241 + 205 242 /* grab the old item if it exists for reservation accounting */ 206 243 old_lv = lip->li_lv; 207 244 ··· 249 272 lv->lv_niovecs = niovecs; 250 273 251 274 /* The allocated data region lies beyond the iovec region */ 275 + lv->lv_buf_len = 0; 252 276 lv->lv_buf = (char *)lv + buf_size - nbytes; 253 - 254 - lv->lv_buf_len = xlog_cil_lv_item_format(lip, lv); 277 + lip->li_ops->iop_format(lip, lv); 255 278 insert: 256 279 ASSERT(lv->lv_buf_len <= nbytes); 257 280 xfs_cil_prepare_item(log, lv, old_lv, diff_len, diff_iovecs);
+1 -1
fs/xfs/xfs_trans.h
··· 64 64 65 65 struct xfs_item_ops { 66 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 68 void (*iop_pin)(xfs_log_item_t *); 69 69 void (*iop_unpin)(xfs_log_item_t *, int remove); 70 70 uint (*iop_push)(struct xfs_log_item *, struct list_head *);