diff options
Diffstat (limited to 'fs/xfs/xfs_buf_item.c')
-rw-r--r-- | fs/xfs/xfs_buf_item.c | 166 |
1 files changed, 85 insertions, 81 deletions
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 240340a4727b..02a80984aa05 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
@@ -64,7 +64,7 @@ xfs_buf_item_log_debug( | |||
64 | nbytes = last - first + 1; | 64 | nbytes = last - first + 1; |
65 | bfset(bip->bli_logged, first, nbytes); | 65 | bfset(bip->bli_logged, first, nbytes); |
66 | for (x = 0; x < nbytes; x++) { | 66 | for (x = 0; x < nbytes; x++) { |
67 | chunk_num = byte >> XFS_BLI_SHIFT; | 67 | chunk_num = byte >> XFS_BLF_SHIFT; |
68 | word_num = chunk_num >> BIT_TO_WORD_SHIFT; | 68 | word_num = chunk_num >> BIT_TO_WORD_SHIFT; |
69 | bit_num = chunk_num & (NBWORD - 1); | 69 | bit_num = chunk_num & (NBWORD - 1); |
70 | wordp = &(bip->bli_format.blf_data_map[word_num]); | 70 | wordp = &(bip->bli_format.blf_data_map[word_num]); |
@@ -166,7 +166,7 @@ xfs_buf_item_size( | |||
166 | * cancel flag in it. | 166 | * cancel flag in it. |
167 | */ | 167 | */ |
168 | trace_xfs_buf_item_size_stale(bip); | 168 | trace_xfs_buf_item_size_stale(bip); |
169 | ASSERT(bip->bli_format.blf_flags & XFS_BLI_CANCEL); | 169 | ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL); |
170 | return 1; | 170 | return 1; |
171 | } | 171 | } |
172 | 172 | ||
@@ -197,9 +197,9 @@ xfs_buf_item_size( | |||
197 | } else if (next_bit != last_bit + 1) { | 197 | } else if (next_bit != last_bit + 1) { |
198 | last_bit = next_bit; | 198 | last_bit = next_bit; |
199 | nvecs++; | 199 | nvecs++; |
200 | } else if (xfs_buf_offset(bp, next_bit * XFS_BLI_CHUNK) != | 200 | } else if (xfs_buf_offset(bp, next_bit * XFS_BLF_CHUNK) != |
201 | (xfs_buf_offset(bp, last_bit * XFS_BLI_CHUNK) + | 201 | (xfs_buf_offset(bp, last_bit * XFS_BLF_CHUNK) + |
202 | XFS_BLI_CHUNK)) { | 202 | XFS_BLF_CHUNK)) { |
203 | last_bit = next_bit; | 203 | last_bit = next_bit; |
204 | nvecs++; | 204 | nvecs++; |
205 | } else { | 205 | } else { |
@@ -254,6 +254,20 @@ xfs_buf_item_format( | |||
254 | vecp++; | 254 | vecp++; |
255 | nvecs = 1; | 255 | nvecs = 1; |
256 | 256 | ||
257 | /* | ||
258 | * If it is an inode buffer, transfer the in-memory state to the | ||
259 | * format flags and clear the in-memory state. We do not transfer | ||
260 | * this state if the inode buffer allocation has not yet been committed | ||
261 | * to the log as setting the XFS_BLI_INODE_BUF flag will prevent | ||
262 | * correct replay of the inode allocation. | ||
263 | */ | ||
264 | if (bip->bli_flags & XFS_BLI_INODE_BUF) { | ||
265 | if (!((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) && | ||
266 | xfs_log_item_in_current_chkpt(&bip->bli_item))) | ||
267 | bip->bli_format.blf_flags |= XFS_BLF_INODE_BUF; | ||
268 | bip->bli_flags &= ~XFS_BLI_INODE_BUF; | ||
269 | } | ||
270 | |||
257 | if (bip->bli_flags & XFS_BLI_STALE) { | 271 | if (bip->bli_flags & XFS_BLI_STALE) { |
258 | /* | 272 | /* |
259 | * The buffer is stale, so all we need to log | 273 | * The buffer is stale, so all we need to log |
@@ -261,7 +275,7 @@ xfs_buf_item_format( | |||
261 | * cancel flag in it. | 275 | * cancel flag in it. |
262 | */ | 276 | */ |
263 | trace_xfs_buf_item_format_stale(bip); | 277 | trace_xfs_buf_item_format_stale(bip); |
264 | ASSERT(bip->bli_format.blf_flags & XFS_BLI_CANCEL); | 278 | ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL); |
265 | bip->bli_format.blf_size = nvecs; | 279 | bip->bli_format.blf_size = nvecs; |
266 | return; | 280 | return; |
267 | } | 281 | } |
@@ -294,28 +308,28 @@ xfs_buf_item_format( | |||
294 | * keep counting and scanning. | 308 | * keep counting and scanning. |
295 | */ | 309 | */ |
296 | if (next_bit == -1) { | 310 | if (next_bit == -1) { |
297 | buffer_offset = first_bit * XFS_BLI_CHUNK; | 311 | buffer_offset = first_bit * XFS_BLF_CHUNK; |
298 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); | 312 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); |
299 | vecp->i_len = nbits * XFS_BLI_CHUNK; | 313 | vecp->i_len = nbits * XFS_BLF_CHUNK; |
300 | vecp->i_type = XLOG_REG_TYPE_BCHUNK; | 314 | vecp->i_type = XLOG_REG_TYPE_BCHUNK; |
301 | nvecs++; | 315 | nvecs++; |
302 | break; | 316 | break; |
303 | } else if (next_bit != last_bit + 1) { | 317 | } else if (next_bit != last_bit + 1) { |
304 | buffer_offset = first_bit * XFS_BLI_CHUNK; | 318 | buffer_offset = first_bit * XFS_BLF_CHUNK; |
305 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); | 319 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); |
306 | vecp->i_len = nbits * XFS_BLI_CHUNK; | 320 | vecp->i_len = nbits * XFS_BLF_CHUNK; |
307 | vecp->i_type = XLOG_REG_TYPE_BCHUNK; | 321 | vecp->i_type = XLOG_REG_TYPE_BCHUNK; |
308 | nvecs++; | 322 | nvecs++; |
309 | vecp++; | 323 | vecp++; |
310 | first_bit = next_bit; | 324 | first_bit = next_bit; |
311 | last_bit = next_bit; | 325 | last_bit = next_bit; |
312 | nbits = 1; | 326 | nbits = 1; |
313 | } else if (xfs_buf_offset(bp, next_bit << XFS_BLI_SHIFT) != | 327 | } else if (xfs_buf_offset(bp, next_bit << XFS_BLF_SHIFT) != |
314 | (xfs_buf_offset(bp, last_bit << XFS_BLI_SHIFT) + | 328 | (xfs_buf_offset(bp, last_bit << XFS_BLF_SHIFT) + |
315 | XFS_BLI_CHUNK)) { | 329 | XFS_BLF_CHUNK)) { |
316 | buffer_offset = first_bit * XFS_BLI_CHUNK; | 330 | buffer_offset = first_bit * XFS_BLF_CHUNK; |
317 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); | 331 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); |
318 | vecp->i_len = nbits * XFS_BLI_CHUNK; | 332 | vecp->i_len = nbits * XFS_BLF_CHUNK; |
319 | vecp->i_type = XLOG_REG_TYPE_BCHUNK; | 333 | vecp->i_type = XLOG_REG_TYPE_BCHUNK; |
320 | /* You would think we need to bump the nvecs here too, but we do not | 334 | /* You would think we need to bump the nvecs here too, but we do not |
321 | * this number is used by recovery, and it gets confused by the boundary | 335 | * this number is used by recovery, and it gets confused by the boundary |
@@ -341,10 +355,15 @@ xfs_buf_item_format( | |||
341 | } | 355 | } |
342 | 356 | ||
343 | /* | 357 | /* |
344 | * This is called to pin the buffer associated with the buf log | 358 | * This is called to pin the buffer associated with the buf log item in memory |
345 | * item in memory so it cannot be written out. Simply call bpin() | 359 | * so it cannot be written out. Simply call bpin() on the buffer to do this. |
346 | * on the buffer to do this. | 360 | * |
361 | * We also always take a reference to the buffer log item here so that the bli | ||
362 | * is held while the item is pinned in memory. This means that we can | ||
363 | * unconditionally drop the reference count a transaction holds when the | ||
364 | * transaction is completed. | ||
347 | */ | 365 | */ |
366 | |||
348 | STATIC void | 367 | STATIC void |
349 | xfs_buf_item_pin( | 368 | xfs_buf_item_pin( |
350 | xfs_buf_log_item_t *bip) | 369 | xfs_buf_log_item_t *bip) |
@@ -356,6 +375,7 @@ xfs_buf_item_pin( | |||
356 | ASSERT(atomic_read(&bip->bli_refcount) > 0); | 375 | ASSERT(atomic_read(&bip->bli_refcount) > 0); |
357 | ASSERT((bip->bli_flags & XFS_BLI_LOGGED) || | 376 | ASSERT((bip->bli_flags & XFS_BLI_LOGGED) || |
358 | (bip->bli_flags & XFS_BLI_STALE)); | 377 | (bip->bli_flags & XFS_BLI_STALE)); |
378 | atomic_inc(&bip->bli_refcount); | ||
359 | trace_xfs_buf_item_pin(bip); | 379 | trace_xfs_buf_item_pin(bip); |
360 | xfs_bpin(bp); | 380 | xfs_bpin(bp); |
361 | } | 381 | } |
@@ -393,7 +413,7 @@ xfs_buf_item_unpin( | |||
393 | ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); | 413 | ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); |
394 | ASSERT(!(XFS_BUF_ISDELAYWRITE(bp))); | 414 | ASSERT(!(XFS_BUF_ISDELAYWRITE(bp))); |
395 | ASSERT(XFS_BUF_ISSTALE(bp)); | 415 | ASSERT(XFS_BUF_ISSTALE(bp)); |
396 | ASSERT(bip->bli_format.blf_flags & XFS_BLI_CANCEL); | 416 | ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL); |
397 | trace_xfs_buf_item_unpin_stale(bip); | 417 | trace_xfs_buf_item_unpin_stale(bip); |
398 | 418 | ||
399 | /* | 419 | /* |
@@ -489,20 +509,23 @@ xfs_buf_item_trylock( | |||
489 | } | 509 | } |
490 | 510 | ||
491 | /* | 511 | /* |
492 | * Release the buffer associated with the buf log item. | 512 | * Release the buffer associated with the buf log item. If there is no dirty |
493 | * If there is no dirty logged data associated with the | 513 | * logged data associated with the buffer recorded in the buf log item, then |
494 | * buffer recorded in the buf log item, then free the | 514 | * free the buf log item and remove the reference to it in the buffer. |
495 | * buf log item and remove the reference to it in the | 515 | * |
496 | * buffer. | 516 | * This call ignores the recursion count. It is only called when the buffer |
517 | * should REALLY be unlocked, regardless of the recursion count. | ||
497 | * | 518 | * |
498 | * This call ignores the recursion count. It is only called | 519 | * We unconditionally drop the transaction's reference to the log item. If the |
499 | * when the buffer should REALLY be unlocked, regardless | 520 | * item was logged, then another reference was taken when it was pinned, so we |
500 | * of the recursion count. | 521 | * can safely drop the transaction reference now. This also allows us to avoid |
522 | * potential races with the unpin code freeing the bli by not referencing the | ||
523 | * bli after we've dropped the reference count. | ||
501 | * | 524 | * |
502 | * If the XFS_BLI_HOLD flag is set in the buf log item, then | 525 | * If the XFS_BLI_HOLD flag is set in the buf log item, then free the log item |
503 | * free the log item if necessary but do not unlock the buffer. | 526 | * if necessary but do not unlock the buffer. This is for support of |
504 | * This is for support of xfs_trans_bhold(). Make sure the | 527 | * xfs_trans_bhold(). Make sure the XFS_BLI_HOLD field is cleared if we don't |
505 | * XFS_BLI_HOLD field is cleared if we don't free the item. | 528 | * free the item. |
506 | */ | 529 | */ |
507 | STATIC void | 530 | STATIC void |
508 | xfs_buf_item_unlock( | 531 | xfs_buf_item_unlock( |
@@ -514,73 +537,54 @@ xfs_buf_item_unlock( | |||
514 | 537 | ||
515 | bp = bip->bli_buf; | 538 | bp = bip->bli_buf; |
516 | 539 | ||
517 | /* | 540 | /* Clear the buffer's association with this transaction. */ |
518 | * Clear the buffer's association with this transaction. | ||
519 | */ | ||
520 | XFS_BUF_SET_FSPRIVATE2(bp, NULL); | 541 | XFS_BUF_SET_FSPRIVATE2(bp, NULL); |
521 | 542 | ||
522 | /* | 543 | /* |
523 | * If this is a transaction abort, don't return early. | 544 | * If this is a transaction abort, don't return early. Instead, allow |
524 | * Instead, allow the brelse to happen. | 545 | * the brelse to happen. Normally it would be done for stale |
525 | * Normally it would be done for stale (cancelled) buffers | 546 | * (cancelled) buffers at unpin time, but we'll never go through the |
526 | * at unpin time, but we'll never go through the pin/unpin | 547 | * pin/unpin cycle if we abort inside commit. |
527 | * cycle if we abort inside commit. | ||
528 | */ | 548 | */ |
529 | aborted = (bip->bli_item.li_flags & XFS_LI_ABORTED) != 0; | 549 | aborted = (bip->bli_item.li_flags & XFS_LI_ABORTED) != 0; |
530 | 550 | ||
531 | /* | 551 | /* |
532 | * If the buf item is marked stale, then don't do anything. | 552 | * Before possibly freeing the buf item, determine if we should |
533 | * We'll unlock the buffer and free the buf item when the | 553 | * release the buffer at the end of this routine. |
534 | * buffer is unpinned for the last time. | ||
535 | */ | 554 | */ |
536 | if (bip->bli_flags & XFS_BLI_STALE) { | 555 | hold = bip->bli_flags & XFS_BLI_HOLD; |
537 | bip->bli_flags &= ~XFS_BLI_LOGGED; | 556 | |
538 | trace_xfs_buf_item_unlock_stale(bip); | 557 | /* Clear the per transaction state. */ |
539 | ASSERT(bip->bli_format.blf_flags & XFS_BLI_CANCEL); | 558 | bip->bli_flags &= ~(XFS_BLI_LOGGED | XFS_BLI_HOLD); |
540 | if (!aborted) | ||
541 | return; | ||
542 | } | ||
543 | 559 | ||
544 | /* | 560 | /* |
545 | * Drop the transaction's reference to the log item if | 561 | * If the buf item is marked stale, then don't do anything. We'll |
546 | * it was not logged as part of the transaction. Otherwise | 562 | * unlock the buffer and free the buf item when the buffer is unpinned |
547 | * we'll drop the reference in xfs_buf_item_unpin() when | 563 | * for the last time. |
548 | * the transaction is really through with the buffer. | ||
549 | */ | 564 | */ |
550 | if (!(bip->bli_flags & XFS_BLI_LOGGED)) { | 565 | if (bip->bli_flags & XFS_BLI_STALE) { |
551 | atomic_dec(&bip->bli_refcount); | 566 | trace_xfs_buf_item_unlock_stale(bip); |
552 | } else { | 567 | ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL); |
553 | /* | 568 | if (!aborted) { |
554 | * Clear the logged flag since this is per | 569 | atomic_dec(&bip->bli_refcount); |
555 | * transaction state. | 570 | return; |
556 | */ | 571 | } |
557 | bip->bli_flags &= ~XFS_BLI_LOGGED; | ||
558 | } | 572 | } |
559 | 573 | ||
560 | /* | ||
561 | * Before possibly freeing the buf item, determine if we should | ||
562 | * release the buffer at the end of this routine. | ||
563 | */ | ||
564 | hold = bip->bli_flags & XFS_BLI_HOLD; | ||
565 | trace_xfs_buf_item_unlock(bip); | 574 | trace_xfs_buf_item_unlock(bip); |
566 | 575 | ||
567 | /* | 576 | /* |
568 | * If the buf item isn't tracking any data, free it. | 577 | * If the buf item isn't tracking any data, free it, otherwise drop the |
569 | * Otherwise, if XFS_BLI_HOLD is set clear it. | 578 | * reference we hold to it. |
570 | */ | 579 | */ |
571 | if (xfs_bitmap_empty(bip->bli_format.blf_data_map, | 580 | if (xfs_bitmap_empty(bip->bli_format.blf_data_map, |
572 | bip->bli_format.blf_map_size)) { | 581 | bip->bli_format.blf_map_size)) |
573 | xfs_buf_item_relse(bp); | 582 | xfs_buf_item_relse(bp); |
574 | } else if (hold) { | 583 | else |
575 | bip->bli_flags &= ~XFS_BLI_HOLD; | 584 | atomic_dec(&bip->bli_refcount); |
576 | } | ||
577 | 585 | ||
578 | /* | 586 | if (!hold) |
579 | * Release the buffer if XFS_BLI_HOLD was not set. | ||
580 | */ | ||
581 | if (!hold) { | ||
582 | xfs_buf_relse(bp); | 587 | xfs_buf_relse(bp); |
583 | } | ||
584 | } | 588 | } |
585 | 589 | ||
586 | /* | 590 | /* |
@@ -717,12 +721,12 @@ xfs_buf_item_init( | |||
717 | } | 721 | } |
718 | 722 | ||
719 | /* | 723 | /* |
720 | * chunks is the number of XFS_BLI_CHUNK size pieces | 724 | * chunks is the number of XFS_BLF_CHUNK size pieces |
721 | * the buffer can be divided into. Make sure not to | 725 | * the buffer can be divided into. Make sure not to |
722 | * truncate any pieces. map_size is the size of the | 726 | * truncate any pieces. map_size is the size of the |
723 | * bitmap needed to describe the chunks of the buffer. | 727 | * bitmap needed to describe the chunks of the buffer. |
724 | */ | 728 | */ |
725 | chunks = (int)((XFS_BUF_COUNT(bp) + (XFS_BLI_CHUNK - 1)) >> XFS_BLI_SHIFT); | 729 | chunks = (int)((XFS_BUF_COUNT(bp) + (XFS_BLF_CHUNK - 1)) >> XFS_BLF_SHIFT); |
726 | map_size = (int)((chunks + NBWORD) >> BIT_TO_WORD_SHIFT); | 730 | map_size = (int)((chunks + NBWORD) >> BIT_TO_WORD_SHIFT); |
727 | 731 | ||
728 | bip = (xfs_buf_log_item_t*)kmem_zone_zalloc(xfs_buf_item_zone, | 732 | bip = (xfs_buf_log_item_t*)kmem_zone_zalloc(xfs_buf_item_zone, |
@@ -790,8 +794,8 @@ xfs_buf_item_log( | |||
790 | /* | 794 | /* |
791 | * Convert byte offsets to bit numbers. | 795 | * Convert byte offsets to bit numbers. |
792 | */ | 796 | */ |
793 | first_bit = first >> XFS_BLI_SHIFT; | 797 | first_bit = first >> XFS_BLF_SHIFT; |
794 | last_bit = last >> XFS_BLI_SHIFT; | 798 | last_bit = last >> XFS_BLF_SHIFT; |
795 | 799 | ||
796 | /* | 800 | /* |
797 | * Calculate the total number of bits to be set. | 801 | * Calculate the total number of bits to be set. |