aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2014-10-01 19:04:01 -0400
committerDave Chinner <david@fromorbit.com>2014-10-01 19:04:01 -0400
commitcf53e99d192171a58791136d33fd3fea5d8bab35 (patch)
tree0cb99cd791928ca794364e8aa8620a4d3851f50c /fs
parenta870fe6dfaba1cc67424cde4cfd2cd3eee62bf35 (diff)
xfs: Don't use xfs_buf_iowait in the delwri buffer code
For the special case of delwri buffer submission and waiting, we don't need to issue IO synchronously at all. The second pass to call xfs_buf_iowait() can be replaced with blocking on xfs_buf_lock() - the buffer will be unlocked when the async IO is complete. This formalises a sane the method of waiting for async IO - take an extra reference, submit the IO, call xfs_buf_lock() when you want to wait for IO completion. i.e.: bp = xfs_buf_find(); xfs_buf_hold(bp); bp->b_flags |= XBF_ASYNC; xfs_buf_iosubmit(bp); xfs_buf_lock(bp) error = bp->b_error; .... xfs_buf_relse(bp); While this is somewhat racy for gathering IO errors, none of the code that calls xfs_buf_delwri_submit() will race against other users of the buffers being submitted. Even if they do, we don't really care if the error is detected by the delwri code or the user we raced against. Either way, the error will be detected and handled. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_buf.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index cd7b8ca9b064..9dc4c2223035 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -1813,12 +1813,17 @@ __xfs_buf_delwri_submit(
1813 blk_start_plug(&plug); 1813 blk_start_plug(&plug);
1814 list_for_each_entry_safe(bp, n, io_list, b_list) { 1814 list_for_each_entry_safe(bp, n, io_list, b_list) {
1815 bp->b_flags &= ~(_XBF_DELWRI_Q | XBF_ASYNC | XBF_WRITE_FAIL); 1815 bp->b_flags &= ~(_XBF_DELWRI_Q | XBF_ASYNC | XBF_WRITE_FAIL);
1816 bp->b_flags |= XBF_WRITE; 1816 bp->b_flags |= XBF_WRITE | XBF_ASYNC;
1817 1817
1818 if (!wait) { 1818 /*
1819 bp->b_flags |= XBF_ASYNC; 1819 * we do all Io submission async. This means if we need to wait
1820 * for IO completion we need to take an extra reference so the
1821 * buffer is still valid on the other side.
1822 */
1823 if (wait)
1824 xfs_buf_hold(bp);
1825 else
1820 list_del_init(&bp->b_list); 1826 list_del_init(&bp->b_list);
1821 }
1822 xfs_bdstrat_cb(bp); 1827 xfs_bdstrat_cb(bp);
1823 } 1828 }
1824 blk_finish_plug(&plug); 1829 blk_finish_plug(&plug);
@@ -1866,7 +1871,10 @@ xfs_buf_delwri_submit(
1866 bp = list_first_entry(&io_list, struct xfs_buf, b_list); 1871 bp = list_first_entry(&io_list, struct xfs_buf, b_list);
1867 1872
1868 list_del_init(&bp->b_list); 1873 list_del_init(&bp->b_list);
1869 error2 = xfs_buf_iowait(bp); 1874
1875 /* locking the buffer will wait for async IO completion. */
1876 xfs_buf_lock(bp);
1877 error2 = bp->b_error;
1870 xfs_buf_relse(bp); 1878 xfs_buf_relse(bp);
1871 if (!error) 1879 if (!error)
1872 error = error2; 1880 error = error2;