diff options
Diffstat (limited to 'fs/xfs/xfs_buf_item.c')
-rw-r--r-- | fs/xfs/xfs_buf_item.c | 72 |
1 files changed, 39 insertions, 33 deletions
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index a30f7e9eb2b9..f3c49e69eab9 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
@@ -250,7 +250,7 @@ xfs_buf_item_format( | |||
250 | ((bip->bli_format.blf_map_size - 1) * sizeof(uint))); | 250 | ((bip->bli_format.blf_map_size - 1) * sizeof(uint))); |
251 | vecp->i_addr = (xfs_caddr_t)&bip->bli_format; | 251 | vecp->i_addr = (xfs_caddr_t)&bip->bli_format; |
252 | vecp->i_len = base_size; | 252 | vecp->i_len = base_size; |
253 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_BFORMAT); | 253 | vecp->i_type = XLOG_REG_TYPE_BFORMAT; |
254 | vecp++; | 254 | vecp++; |
255 | nvecs = 1; | 255 | nvecs = 1; |
256 | 256 | ||
@@ -297,14 +297,14 @@ xfs_buf_item_format( | |||
297 | buffer_offset = first_bit * XFS_BLI_CHUNK; | 297 | buffer_offset = first_bit * XFS_BLI_CHUNK; |
298 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); | 298 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); |
299 | vecp->i_len = nbits * XFS_BLI_CHUNK; | 299 | vecp->i_len = nbits * XFS_BLI_CHUNK; |
300 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_BCHUNK); | 300 | vecp->i_type = XLOG_REG_TYPE_BCHUNK; |
301 | nvecs++; | 301 | nvecs++; |
302 | break; | 302 | break; |
303 | } else if (next_bit != last_bit + 1) { | 303 | } else if (next_bit != last_bit + 1) { |
304 | buffer_offset = first_bit * XFS_BLI_CHUNK; | 304 | buffer_offset = first_bit * XFS_BLI_CHUNK; |
305 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); | 305 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); |
306 | vecp->i_len = nbits * XFS_BLI_CHUNK; | 306 | vecp->i_len = nbits * XFS_BLI_CHUNK; |
307 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_BCHUNK); | 307 | vecp->i_type = XLOG_REG_TYPE_BCHUNK; |
308 | nvecs++; | 308 | nvecs++; |
309 | vecp++; | 309 | vecp++; |
310 | first_bit = next_bit; | 310 | first_bit = next_bit; |
@@ -316,7 +316,7 @@ xfs_buf_item_format( | |||
316 | buffer_offset = first_bit * XFS_BLI_CHUNK; | 316 | buffer_offset = first_bit * XFS_BLI_CHUNK; |
317 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); | 317 | vecp->i_addr = xfs_buf_offset(bp, buffer_offset); |
318 | vecp->i_len = nbits * XFS_BLI_CHUNK; | 318 | vecp->i_len = nbits * XFS_BLI_CHUNK; |
319 | XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_BCHUNK); | 319 | vecp->i_type = XLOG_REG_TYPE_BCHUNK; |
320 | /* You would think we need to bump the nvecs here too, but we do not | 320 | /* 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 | 321 | * this number is used by recovery, and it gets confused by the boundary |
322 | * split here | 322 | * split here |
@@ -467,8 +467,10 @@ xfs_buf_item_unpin_remove( | |||
467 | /* | 467 | /* |
468 | * This is called to attempt to lock the buffer associated with this | 468 | * This is called to attempt to lock the buffer associated with this |
469 | * buf log item. Don't sleep on the buffer lock. If we can't get | 469 | * buf log item. Don't sleep on the buffer lock. If we can't get |
470 | * the lock right away, return 0. If we can get the lock, pull the | 470 | * the lock right away, return 0. If we can get the lock, take a |
471 | * buffer from the free list, mark it busy, and return 1. | 471 | * reference to the buffer. If this is a delayed write buffer that |
472 | * needs AIL help to be written back, invoke the pushbuf routine | ||
473 | * rather than the normal success path. | ||
472 | */ | 474 | */ |
473 | STATIC uint | 475 | STATIC uint |
474 | xfs_buf_item_trylock( | 476 | xfs_buf_item_trylock( |
@@ -477,24 +479,18 @@ xfs_buf_item_trylock( | |||
477 | xfs_buf_t *bp; | 479 | xfs_buf_t *bp; |
478 | 480 | ||
479 | bp = bip->bli_buf; | 481 | bp = bip->bli_buf; |
480 | 482 | if (XFS_BUF_ISPINNED(bp)) | |
481 | if (XFS_BUF_ISPINNED(bp)) { | ||
482 | return XFS_ITEM_PINNED; | 483 | return XFS_ITEM_PINNED; |
483 | } | 484 | if (!XFS_BUF_CPSEMA(bp)) |
484 | |||
485 | if (!XFS_BUF_CPSEMA(bp)) { | ||
486 | return XFS_ITEM_LOCKED; | 485 | return XFS_ITEM_LOCKED; |
487 | } | ||
488 | 486 | ||
489 | /* | 487 | /* take a reference to the buffer. */ |
490 | * Remove the buffer from the free list. Only do this | ||
491 | * if it's on the free list. Private buffers like the | ||
492 | * superblock buffer are not. | ||
493 | */ | ||
494 | XFS_BUF_HOLD(bp); | 488 | XFS_BUF_HOLD(bp); |
495 | 489 | ||
496 | ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); | 490 | ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); |
497 | trace_xfs_buf_item_trylock(bip); | 491 | trace_xfs_buf_item_trylock(bip); |
492 | if (XFS_BUF_ISDELAYWRITE(bp)) | ||
493 | return XFS_ITEM_PUSHBUF; | ||
498 | return XFS_ITEM_SUCCESS; | 494 | return XFS_ITEM_SUCCESS; |
499 | } | 495 | } |
500 | 496 | ||
@@ -626,11 +622,9 @@ xfs_buf_item_committed( | |||
626 | } | 622 | } |
627 | 623 | ||
628 | /* | 624 | /* |
629 | * This is called to asynchronously write the buffer associated with this | 625 | * The buffer is locked, but is not a delayed write buffer. This happens |
630 | * buf log item out to disk. The buffer will already have been locked by | 626 | * if we race with IO completion and hence we don't want to try to write it |
631 | * a successful call to xfs_buf_item_trylock(). If the buffer still has | 627 | * again. Just release the buffer. |
632 | * B_DELWRI set, then get it going out to disk with a call to bawrite(). | ||
633 | * If not, then just release the buffer. | ||
634 | */ | 628 | */ |
635 | STATIC void | 629 | STATIC void |
636 | xfs_buf_item_push( | 630 | xfs_buf_item_push( |
@@ -642,17 +636,29 @@ xfs_buf_item_push( | |||
642 | trace_xfs_buf_item_push(bip); | 636 | trace_xfs_buf_item_push(bip); |
643 | 637 | ||
644 | bp = bip->bli_buf; | 638 | bp = bip->bli_buf; |
639 | ASSERT(!XFS_BUF_ISDELAYWRITE(bp)); | ||
640 | xfs_buf_relse(bp); | ||
641 | } | ||
645 | 642 | ||
646 | if (XFS_BUF_ISDELAYWRITE(bp)) { | 643 | /* |
647 | int error; | 644 | * The buffer is locked and is a delayed write buffer. Promote the buffer |
648 | error = xfs_bawrite(bip->bli_item.li_mountp, bp); | 645 | * in the delayed write queue as the caller knows that they must invoke |
649 | if (error) | 646 | * the xfsbufd to get this buffer written. We have to unlock the buffer |
650 | xfs_fs_cmn_err(CE_WARN, bip->bli_item.li_mountp, | 647 | * to allow the xfsbufd to write it, too. |
651 | "xfs_buf_item_push: pushbuf error %d on bip %p, bp %p", | 648 | */ |
652 | error, bip, bp); | 649 | STATIC void |
653 | } else { | 650 | xfs_buf_item_pushbuf( |
654 | xfs_buf_relse(bp); | 651 | xfs_buf_log_item_t *bip) |
655 | } | 652 | { |
653 | xfs_buf_t *bp; | ||
654 | |||
655 | ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); | ||
656 | trace_xfs_buf_item_pushbuf(bip); | ||
657 | |||
658 | bp = bip->bli_buf; | ||
659 | ASSERT(XFS_BUF_ISDELAYWRITE(bp)); | ||
660 | xfs_buf_delwri_promote(bp); | ||
661 | xfs_buf_relse(bp); | ||
656 | } | 662 | } |
657 | 663 | ||
658 | /* ARGSUSED */ | 664 | /* ARGSUSED */ |
@@ -677,7 +683,7 @@ static struct xfs_item_ops xfs_buf_item_ops = { | |||
677 | .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) | 683 | .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) |
678 | xfs_buf_item_committed, | 684 | xfs_buf_item_committed, |
679 | .iop_push = (void(*)(xfs_log_item_t*))xfs_buf_item_push, | 685 | .iop_push = (void(*)(xfs_log_item_t*))xfs_buf_item_push, |
680 | .iop_pushbuf = NULL, | 686 | .iop_pushbuf = (void(*)(xfs_log_item_t*))xfs_buf_item_pushbuf, |
681 | .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) | 687 | .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) |
682 | xfs_buf_item_committing | 688 | xfs_buf_item_committing |
683 | }; | 689 | }; |