diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/xfs_buf.c | 51 |
1 files changed, 42 insertions, 9 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 9dc4c2223035..48b1e2989ea4 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -1019,6 +1019,9 @@ xfs_buf_iodone_work( | |||
1019 | else { | 1019 | else { |
1020 | ASSERT(read && bp->b_ops); | 1020 | ASSERT(read && bp->b_ops); |
1021 | complete(&bp->b_iowait); | 1021 | complete(&bp->b_iowait); |
1022 | |||
1023 | /* release the !XBF_ASYNC ref now we are done. */ | ||
1024 | xfs_buf_rele(bp); | ||
1022 | } | 1025 | } |
1023 | } | 1026 | } |
1024 | 1027 | ||
@@ -1044,6 +1047,7 @@ xfs_buf_ioend( | |||
1044 | } else { | 1047 | } else { |
1045 | bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_READ_AHEAD); | 1048 | bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_READ_AHEAD); |
1046 | complete(&bp->b_iowait); | 1049 | complete(&bp->b_iowait); |
1050 | xfs_buf_rele(bp); | ||
1047 | } | 1051 | } |
1048 | } | 1052 | } |
1049 | 1053 | ||
@@ -1086,8 +1090,11 @@ xfs_bioerror( | |||
1086 | xfs_buf_ioerror(bp, -EIO); | 1090 | xfs_buf_ioerror(bp, -EIO); |
1087 | 1091 | ||
1088 | /* | 1092 | /* |
1089 | * We're calling xfs_buf_ioend, so delete XBF_DONE flag. | 1093 | * We're calling xfs_buf_ioend, so delete XBF_DONE flag. For |
1094 | * sync IO, xfs_buf_ioend is going to remove a ref here. | ||
1090 | */ | 1095 | */ |
1096 | if (!(bp->b_flags & XBF_ASYNC)) | ||
1097 | xfs_buf_hold(bp); | ||
1091 | XFS_BUF_UNREAD(bp); | 1098 | XFS_BUF_UNREAD(bp); |
1092 | XFS_BUF_UNDONE(bp); | 1099 | XFS_BUF_UNDONE(bp); |
1093 | xfs_buf_stale(bp); | 1100 | xfs_buf_stale(bp); |
@@ -1383,22 +1390,48 @@ xfs_buf_iorequest( | |||
1383 | 1390 | ||
1384 | if (bp->b_flags & XBF_WRITE) | 1391 | if (bp->b_flags & XBF_WRITE) |
1385 | xfs_buf_wait_unpin(bp); | 1392 | xfs_buf_wait_unpin(bp); |
1393 | |||
1394 | /* | ||
1395 | * Take references to the buffer. For XBF_ASYNC buffers, holding a | ||
1396 | * reference for as long as submission takes is all that is necessary | ||
1397 | * here. The IO inherits the lock and hold count from the submitter, | ||
1398 | * and these are release during IO completion processing. Taking a hold | ||
1399 | * over submission ensures that the buffer is not freed until we have | ||
1400 | * completed all processing, regardless of when IO errors occur or are | ||
1401 | * reported. | ||
1402 | * | ||
1403 | * However, for synchronous IO, the IO does not inherit the submitters | ||
1404 | * reference count, nor the buffer lock. Hence we need to take an extra | ||
1405 | * reference to the buffer for the for the IO context so that we can | ||
1406 | * guarantee the buffer is not freed until all IO completion processing | ||
1407 | * is done. Otherwise the caller can drop their reference while the IO | ||
1408 | * is still in progress and hence trigger a use-after-free situation. | ||
1409 | */ | ||
1386 | xfs_buf_hold(bp); | 1410 | xfs_buf_hold(bp); |
1411 | if (!(bp->b_flags & XBF_ASYNC)) | ||
1412 | xfs_buf_hold(bp); | ||
1413 | |||
1387 | 1414 | ||
1388 | /* | 1415 | /* |
1389 | * Set the count to 1 initially, this will stop an I/O | 1416 | * Set the count to 1 initially, this will stop an I/O completion |
1390 | * completion callout which happens before we have started | 1417 | * callout which happens before we have started all the I/O from calling |
1391 | * all the I/O from calling xfs_buf_ioend too early. | 1418 | * xfs_buf_ioend too early. |
1392 | */ | 1419 | */ |
1393 | atomic_set(&bp->b_io_remaining, 1); | 1420 | atomic_set(&bp->b_io_remaining, 1); |
1394 | _xfs_buf_ioapply(bp); | 1421 | _xfs_buf_ioapply(bp); |
1422 | |||
1395 | /* | 1423 | /* |
1396 | * If _xfs_buf_ioapply failed, we'll get back here with | 1424 | * If _xfs_buf_ioapply failed or we are doing synchronous IO that |
1397 | * only the reference we took above. _xfs_buf_ioend will | 1425 | * completes extremely quickly, we can get back here with only the IO |
1398 | * drop it to zero, so we'd better not queue it for later, | 1426 | * reference we took above. _xfs_buf_ioend will drop it to zero. Run |
1399 | * or we'll free it before it's done. | 1427 | * completion processing synchronously so that we don't return to the |
1428 | * caller with completion still pending. This avoids unnecessary context | ||
1429 | * switches associated with the end_io workqueue. | ||
1400 | */ | 1430 | */ |
1401 | _xfs_buf_ioend(bp, bp->b_error ? 0 : 1); | 1431 | if (bp->b_error || !(bp->b_flags & XBF_ASYNC)) |
1432 | _xfs_buf_ioend(bp, 0); | ||
1433 | else | ||
1434 | _xfs_buf_ioend(bp, 1); | ||
1402 | 1435 | ||
1403 | xfs_buf_rele(bp); | 1436 | xfs_buf_rele(bp); |
1404 | } | 1437 | } |