diff options
| -rw-r--r-- | fs/xfs/xfs_buf_item.c | 29 | ||||
| -rw-r--r-- | fs/xfs/xfs_dquot_item.c | 19 | ||||
| -rw-r--r-- | fs/xfs/xfs_extfree_item.c | 10 | ||||
| -rw-r--r-- | fs/xfs/xfs_icreate_item.c | 5 | ||||
| -rw-r--r-- | fs/xfs/xfs_inode_item.c | 92 | ||||
| -rw-r--r-- | fs/xfs/xfs_log.h | 41 | ||||
| -rw-r--r-- | fs/xfs/xfs_log_cil.c | 41 | ||||
| -rw-r--r-- | fs/xfs/xfs_trans.h | 2 |
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 | ||
| 185 | static inline void | 185 | static inline void |
| 186 | xfs_buf_item_copy_iovec( | 186 | xfs_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( | |||
| 211 | static void | 212 | static void |
| 212 | xfs_buf_item_format_segment( | 213 | xfs_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 | } |
| 300 | out: | ||
| 301 | blfp->blf_size = nvecs; | ||
| 302 | } | 300 | } |
| 303 | 301 | ||
| 304 | /* | 302 | /* |
| @@ -310,10 +308,11 @@ out: | |||
| 310 | STATIC void | 308 | STATIC void |
| 311 | xfs_buf_item_format( | 309 | xfs_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( | |||
| 57 | STATIC void | 57 | STATIC void |
| 58 | xfs_qm_dquot_logitem_format( | 58 | xfs_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( | |||
| 302 | STATIC void | 303 | STATIC void |
| 303 | xfs_qm_qoff_logitem_format( | 304 | xfs_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( | |||
| 102 | STATIC void | 102 | STATIC void |
| 103 | xfs_efi_item_format( | 103 | xfs_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( | |||
| 368 | STATIC void | 369 | STATIC void |
| 369 | xfs_efd_item_format( | 370 | xfs_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( | |||
| 59 | STATIC void | 59 | STATIC void |
| 60 | xfs_icreate_item_format( | 60 | xfs_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( | |||
| 163 | STATIC int | 163 | STATIC int |
| 164 | xfs_inode_item_format_extents( | 164 | xfs_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( | |||
| 212 | STATIC void | 213 | STATIC void |
| 213 | xfs_inode_item_format_data_fork( | 214 | xfs_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( | |||
| 326 | STATIC void | 324 | STATIC void |
| 327 | xfs_inode_item_format_attr_fork( | 325 | xfs_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( | |||
| 420 | STATIC void | 419 | STATIC void |
| 421 | xfs_inode_item_format( | 420 | xfs_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 | ||
| 33 | static inline void * | 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 | 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 | ||
| 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; | ||
| 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 | ||
| 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 | ||
| @@ -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); | ||
| 278 | insert: | 255 | insert: |
| 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 | ||
| 65 | struct xfs_item_ops { | 65 | struct 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 *); |
