Skip to content

Commit eaebb51

Browse files
Brian Fosterdjwong
authored andcommitted
xfs: refactor buffer submission into a common helper
Sync and async buffer submission both do generally similar things with a couple odd exceptions. Refactor the core buffer submission code into a common helper to isolate buffer submission from completion handling of synchronous buffer I/O. This patch does not change behavior. It is a step towards support for using synchronous buffer I/O via synchronous delwri queue submission. Designed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
1 parent 5fdd979 commit eaebb51

File tree

2 files changed

+37
-49
lines changed

2 files changed

+37
-49
lines changed

fs/xfs/xfs_buf.c

Lines changed: 37 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,22 +1458,20 @@ _xfs_buf_ioapply(
14581458
* a call to this function unless the caller holds an additional reference
14591459
* itself.
14601460
*/
1461-
void
1462-
xfs_buf_submit(
1461+
static int
1462+
__xfs_buf_submit(
14631463
struct xfs_buf *bp)
14641464
{
14651465
trace_xfs_buf_submit(bp, _RET_IP_);
14661466

14671467
ASSERT(!(bp->b_flags & _XBF_DELWRI_Q));
1468-
ASSERT(bp->b_flags & XBF_ASYNC);
14691468

14701469
/* on shutdown we stale and complete the buffer immediately */
14711470
if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) {
14721471
xfs_buf_ioerror(bp, -EIO);
14731472
bp->b_flags &= ~XBF_DONE;
14741473
xfs_buf_stale(bp);
1475-
xfs_buf_ioend(bp);
1476-
return;
1474+
return -EIO;
14771475
}
14781476

14791477
if (bp->b_flags & XBF_WRITE)
@@ -1482,23 +1480,14 @@ xfs_buf_submit(
14821480
/* clear the internal error state to avoid spurious errors */
14831481
bp->b_io_error = 0;
14841482

1485-
/*
1486-
* The caller's reference is released during I/O completion.
1487-
* This occurs some time after the last b_io_remaining reference is
1488-
* released, so after we drop our Io reference we have to have some
1489-
* other reference to ensure the buffer doesn't go away from underneath
1490-
* us. Take a direct reference to ensure we have safe access to the
1491-
* buffer until we are finished with it.
1492-
*/
1493-
xfs_buf_hold(bp);
1494-
14951483
/*
14961484
* Set the count to 1 initially, this will stop an I/O completion
14971485
* callout which happens before we have started all the I/O from calling
14981486
* xfs_buf_ioend too early.
14991487
*/
15001488
atomic_set(&bp->b_io_remaining, 1);
1501-
xfs_buf_ioacct_inc(bp);
1489+
if (bp->b_flags & XBF_ASYNC)
1490+
xfs_buf_ioacct_inc(bp);
15021491
_xfs_buf_ioapply(bp);
15031492

15041493
/*
@@ -1507,14 +1496,39 @@ xfs_buf_submit(
15071496
* that we don't return to the caller with completion still pending.
15081497
*/
15091498
if (atomic_dec_and_test(&bp->b_io_remaining) == 1) {
1510-
if (bp->b_error)
1499+
if (bp->b_error || !(bp->b_flags & XBF_ASYNC))
15111500
xfs_buf_ioend(bp);
15121501
else
15131502
xfs_buf_ioend_async(bp);
15141503
}
15151504

1516-
xfs_buf_rele(bp);
1505+
return 0;
1506+
}
1507+
1508+
void
1509+
xfs_buf_submit(
1510+
struct xfs_buf *bp)
1511+
{
1512+
int error;
1513+
1514+
ASSERT(bp->b_flags & XBF_ASYNC);
1515+
1516+
/*
1517+
* The caller's reference is released during I/O completion.
1518+
* This occurs some time after the last b_io_remaining reference is
1519+
* released, so after we drop our Io reference we have to have some
1520+
* other reference to ensure the buffer doesn't go away from underneath
1521+
* us. Take a direct reference to ensure we have safe access to the
1522+
* buffer until we are finished with it.
1523+
*/
1524+
xfs_buf_hold(bp);
1525+
1526+
error = __xfs_buf_submit(bp);
1527+
if (error)
1528+
xfs_buf_ioend(bp);
1529+
15171530
/* Note: it is not safe to reference bp now we've dropped our ref */
1531+
xfs_buf_rele(bp);
15181532
}
15191533

15201534
/*
@@ -1526,22 +1540,7 @@ xfs_buf_submit_wait(
15261540
{
15271541
int error;
15281542

1529-
trace_xfs_buf_submit_wait(bp, _RET_IP_);
1530-
1531-
ASSERT(!(bp->b_flags & (_XBF_DELWRI_Q | XBF_ASYNC)));
1532-
1533-
if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) {
1534-
xfs_buf_ioerror(bp, -EIO);
1535-
xfs_buf_stale(bp);
1536-
bp->b_flags &= ~XBF_DONE;
1537-
return -EIO;
1538-
}
1539-
1540-
if (bp->b_flags & XBF_WRITE)
1541-
xfs_buf_wait_unpin(bp);
1542-
1543-
/* clear the internal error state to avoid spurious errors */
1544-
bp->b_io_error = 0;
1543+
ASSERT(!(bp->b_flags & XBF_ASYNC));
15451544

15461545
/*
15471546
* For synchronous IO, the IO does not inherit the submitters reference
@@ -1551,27 +1550,17 @@ xfs_buf_submit_wait(
15511550
*/
15521551
xfs_buf_hold(bp);
15531552

1554-
/*
1555-
* Set the count to 1 initially, this will stop an I/O completion
1556-
* callout which happens before we have started all the I/O from calling
1557-
* xfs_buf_ioend too early.
1558-
*/
1559-
atomic_set(&bp->b_io_remaining, 1);
1560-
_xfs_buf_ioapply(bp);
1561-
1562-
/*
1563-
* make sure we run completion synchronously if it raced with us and is
1564-
* already complete.
1565-
*/
1566-
if (atomic_dec_and_test(&bp->b_io_remaining) == 1)
1567-
xfs_buf_ioend(bp);
1553+
error = __xfs_buf_submit(bp);
1554+
if (error)
1555+
goto out;
15681556

15691557
/* wait for completion before gathering the error from the buffer */
15701558
trace_xfs_buf_iowait(bp, _RET_IP_);
15711559
wait_for_completion(&bp->b_iowait);
15721560
trace_xfs_buf_iowait_done(bp, _RET_IP_);
15731561
error = bp->b_error;
15741562

1563+
out:
15751564
/*
15761565
* all done now, we can release the hold that keeps the buffer
15771566
* referenced for the entire IO.

fs/xfs/xfs_trace.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,6 @@ DEFINE_BUF_EVENT(xfs_buf_hold);
310310
DEFINE_BUF_EVENT(xfs_buf_rele);
311311
DEFINE_BUF_EVENT(xfs_buf_iodone);
312312
DEFINE_BUF_EVENT(xfs_buf_submit);
313-
DEFINE_BUF_EVENT(xfs_buf_submit_wait);
314313
DEFINE_BUF_EVENT(xfs_buf_lock);
315314
DEFINE_BUF_EVENT(xfs_buf_lock_done);
316315
DEFINE_BUF_EVENT(xfs_buf_trylock_fail);

0 commit comments

Comments
 (0)