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 *); |