diff options
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_buf.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.c | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 44c2b0ef9a41..649ade8ef598 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -37,6 +37,7 @@ | |||
37 | 37 | ||
38 | #include "xfs_sb.h" | 38 | #include "xfs_sb.h" |
39 | #include "xfs_inum.h" | 39 | #include "xfs_inum.h" |
40 | #include "xfs_log.h" | ||
40 | #include "xfs_ag.h" | 41 | #include "xfs_ag.h" |
41 | #include "xfs_dmapi.h" | 42 | #include "xfs_dmapi.h" |
42 | #include "xfs_mount.h" | 43 | #include "xfs_mount.h" |
@@ -850,6 +851,12 @@ xfs_buf_lock_value( | |||
850 | * Note that this in no way locks the underlying pages, so it is only | 851 | * Note that this in no way locks the underlying pages, so it is only |
851 | * useful for synchronizing concurrent use of buffer objects, not for | 852 | * useful for synchronizing concurrent use of buffer objects, not for |
852 | * synchronizing independent access to the underlying pages. | 853 | * synchronizing independent access to the underlying pages. |
854 | * | ||
855 | * If we come across a stale, pinned, locked buffer, we know that we | ||
856 | * are being asked to lock a buffer that has been reallocated. Because | ||
857 | * it is pinned, we know that the log has not been pushed to disk and | ||
858 | * hence it will still be locked. Rather than sleeping until someone | ||
859 | * else pushes the log, push it ourselves before trying to get the lock. | ||
853 | */ | 860 | */ |
854 | void | 861 | void |
855 | xfs_buf_lock( | 862 | xfs_buf_lock( |
@@ -857,6 +864,8 @@ xfs_buf_lock( | |||
857 | { | 864 | { |
858 | trace_xfs_buf_lock(bp, _RET_IP_); | 865 | trace_xfs_buf_lock(bp, _RET_IP_); |
859 | 866 | ||
867 | if (atomic_read(&bp->b_pin_count) && (bp->b_flags & XBF_STALE)) | ||
868 | xfs_log_force(bp->b_mount, 0); | ||
860 | if (atomic_read(&bp->b_io_remaining)) | 869 | if (atomic_read(&bp->b_io_remaining)) |
861 | blk_run_address_space(bp->b_target->bt_mapping); | 870 | blk_run_address_space(bp->b_target->bt_mapping); |
862 | down(&bp->b_sema); | 871 | down(&bp->b_sema); |
@@ -1007,25 +1016,20 @@ xfs_bwrite( | |||
1007 | struct xfs_mount *mp, | 1016 | struct xfs_mount *mp, |
1008 | struct xfs_buf *bp) | 1017 | struct xfs_buf *bp) |
1009 | { | 1018 | { |
1010 | int iowait = (bp->b_flags & XBF_ASYNC) == 0; | 1019 | int error; |
1011 | int error = 0; | ||
1012 | 1020 | ||
1013 | bp->b_strat = xfs_bdstrat_cb; | 1021 | bp->b_strat = xfs_bdstrat_cb; |
1014 | bp->b_mount = mp; | 1022 | bp->b_mount = mp; |
1015 | bp->b_flags |= XBF_WRITE; | 1023 | bp->b_flags |= XBF_WRITE; |
1016 | if (!iowait) | 1024 | bp->b_flags &= ~(XBF_ASYNC | XBF_READ); |
1017 | bp->b_flags |= _XBF_RUN_QUEUES; | ||
1018 | 1025 | ||
1019 | xfs_buf_delwri_dequeue(bp); | 1026 | xfs_buf_delwri_dequeue(bp); |
1020 | xfs_buf_iostrategy(bp); | 1027 | xfs_buf_iostrategy(bp); |
1021 | 1028 | ||
1022 | if (iowait) { | 1029 | error = xfs_buf_iowait(bp); |
1023 | error = xfs_buf_iowait(bp); | 1030 | if (error) |
1024 | if (error) | 1031 | xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR); |
1025 | xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR); | 1032 | xfs_buf_relse(bp); |
1026 | xfs_buf_relse(bp); | ||
1027 | } | ||
1028 | |||
1029 | return error; | 1033 | return error; |
1030 | } | 1034 | } |
1031 | 1035 | ||
@@ -1614,7 +1618,8 @@ xfs_mapping_buftarg( | |||
1614 | 1618 | ||
1615 | STATIC int | 1619 | STATIC int |
1616 | xfs_alloc_delwrite_queue( | 1620 | xfs_alloc_delwrite_queue( |
1617 | xfs_buftarg_t *btp) | 1621 | xfs_buftarg_t *btp, |
1622 | const char *fsname) | ||
1618 | { | 1623 | { |
1619 | int error = 0; | 1624 | int error = 0; |
1620 | 1625 | ||
@@ -1622,7 +1627,7 @@ xfs_alloc_delwrite_queue( | |||
1622 | INIT_LIST_HEAD(&btp->bt_delwrite_queue); | 1627 | INIT_LIST_HEAD(&btp->bt_delwrite_queue); |
1623 | spin_lock_init(&btp->bt_delwrite_lock); | 1628 | spin_lock_init(&btp->bt_delwrite_lock); |
1624 | btp->bt_flags = 0; | 1629 | btp->bt_flags = 0; |
1625 | btp->bt_task = kthread_run(xfsbufd, btp, "xfsbufd"); | 1630 | btp->bt_task = kthread_run(xfsbufd, btp, "xfsbufd/%s", fsname); |
1626 | if (IS_ERR(btp->bt_task)) { | 1631 | if (IS_ERR(btp->bt_task)) { |
1627 | error = PTR_ERR(btp->bt_task); | 1632 | error = PTR_ERR(btp->bt_task); |
1628 | goto out_error; | 1633 | goto out_error; |
@@ -1635,7 +1640,8 @@ out_error: | |||
1635 | xfs_buftarg_t * | 1640 | xfs_buftarg_t * |
1636 | xfs_alloc_buftarg( | 1641 | xfs_alloc_buftarg( |
1637 | struct block_device *bdev, | 1642 | struct block_device *bdev, |
1638 | int external) | 1643 | int external, |
1644 | const char *fsname) | ||
1639 | { | 1645 | { |
1640 | xfs_buftarg_t *btp; | 1646 | xfs_buftarg_t *btp; |
1641 | 1647 | ||
@@ -1647,7 +1653,7 @@ xfs_alloc_buftarg( | |||
1647 | goto error; | 1653 | goto error; |
1648 | if (xfs_mapping_buftarg(btp, bdev)) | 1654 | if (xfs_mapping_buftarg(btp, bdev)) |
1649 | goto error; | 1655 | goto error; |
1650 | if (xfs_alloc_delwrite_queue(btp)) | 1656 | if (xfs_alloc_delwrite_queue(btp, fsname)) |
1651 | goto error; | 1657 | goto error; |
1652 | xfs_alloc_bufhash(btp, external); | 1658 | xfs_alloc_bufhash(btp, external); |
1653 | return btp; | 1659 | return btp; |