diff options
-rw-r--r-- | fs/xfs/xfs_buf.c | 88 | ||||
-rw-r--r-- | fs/xfs/xfs_buf.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_buf_item.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_log.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 2 |
6 files changed, 45 insertions, 55 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 48b1e2989ea4..a046149e6099 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -998,26 +998,30 @@ xfs_buf_wait_unpin( | |||
998 | * Buffer Utility Routines | 998 | * Buffer Utility Routines |
999 | */ | 999 | */ |
1000 | 1000 | ||
1001 | STATIC void | 1001 | void |
1002 | xfs_buf_iodone_work( | 1002 | xfs_buf_ioend( |
1003 | struct work_struct *work) | 1003 | struct xfs_buf *bp) |
1004 | { | 1004 | { |
1005 | struct xfs_buf *bp = | 1005 | bool read = bp->b_flags & XBF_READ; |
1006 | container_of(work, xfs_buf_t, b_iodone_work); | 1006 | |
1007 | bool read = !!(bp->b_flags & XBF_READ); | 1007 | trace_xfs_buf_iodone(bp, _RET_IP_); |
1008 | 1008 | ||
1009 | bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_READ_AHEAD); | 1009 | bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_READ_AHEAD); |
1010 | 1010 | ||
1011 | /* only validate buffers that were read without errors */ | 1011 | /* Only validate buffers that were read without errors */ |
1012 | if (read && bp->b_ops && !bp->b_error && (bp->b_flags & XBF_DONE)) | 1012 | if (read && !bp->b_error && bp->b_ops) { |
1013 | ASSERT(!bp->b_iodone); | ||
1013 | bp->b_ops->verify_read(bp); | 1014 | bp->b_ops->verify_read(bp); |
1015 | } | ||
1016 | |||
1017 | if (!bp->b_error) | ||
1018 | bp->b_flags |= XBF_DONE; | ||
1014 | 1019 | ||
1015 | if (bp->b_iodone) | 1020 | if (bp->b_iodone) |
1016 | (*(bp->b_iodone))(bp); | 1021 | (*(bp->b_iodone))(bp); |
1017 | else if (bp->b_flags & XBF_ASYNC) | 1022 | else if (bp->b_flags & XBF_ASYNC) |
1018 | xfs_buf_relse(bp); | 1023 | xfs_buf_relse(bp); |
1019 | else { | 1024 | else { |
1020 | ASSERT(read && bp->b_ops); | ||
1021 | complete(&bp->b_iowait); | 1025 | complete(&bp->b_iowait); |
1022 | 1026 | ||
1023 | /* release the !XBF_ASYNC ref now we are done. */ | 1027 | /* release the !XBF_ASYNC ref now we are done. */ |
@@ -1025,30 +1029,22 @@ xfs_buf_iodone_work( | |||
1025 | } | 1029 | } |
1026 | } | 1030 | } |
1027 | 1031 | ||
1028 | void | 1032 | static void |
1029 | xfs_buf_ioend( | 1033 | xfs_buf_ioend_work( |
1030 | struct xfs_buf *bp, | 1034 | struct work_struct *work) |
1031 | int schedule) | ||
1032 | { | 1035 | { |
1033 | bool read = !!(bp->b_flags & XBF_READ); | 1036 | struct xfs_buf *bp = |
1034 | 1037 | container_of(work, xfs_buf_t, b_iodone_work); | |
1035 | trace_xfs_buf_iodone(bp, _RET_IP_); | ||
1036 | 1038 | ||
1037 | if (bp->b_error == 0) | 1039 | xfs_buf_ioend(bp); |
1038 | bp->b_flags |= XBF_DONE; | 1040 | } |
1039 | 1041 | ||
1040 | if (bp->b_iodone || (read && bp->b_ops) || (bp->b_flags & XBF_ASYNC)) { | 1042 | void |
1041 | if (schedule) { | 1043 | xfs_buf_ioend_async( |
1042 | INIT_WORK(&bp->b_iodone_work, xfs_buf_iodone_work); | 1044 | struct xfs_buf *bp) |
1043 | queue_work(xfslogd_workqueue, &bp->b_iodone_work); | 1045 | { |
1044 | } else { | 1046 | INIT_WORK(&bp->b_iodone_work, xfs_buf_ioend_work); |
1045 | xfs_buf_iodone_work(&bp->b_iodone_work); | 1047 | queue_work(xfslogd_workqueue, &bp->b_iodone_work); |
1046 | } | ||
1047 | } else { | ||
1048 | bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_READ_AHEAD); | ||
1049 | complete(&bp->b_iowait); | ||
1050 | xfs_buf_rele(bp); | ||
1051 | } | ||
1052 | } | 1048 | } |
1053 | 1049 | ||
1054 | void | 1050 | void |
@@ -1099,7 +1095,7 @@ xfs_bioerror( | |||
1099 | XFS_BUF_UNDONE(bp); | 1095 | XFS_BUF_UNDONE(bp); |
1100 | xfs_buf_stale(bp); | 1096 | xfs_buf_stale(bp); |
1101 | 1097 | ||
1102 | xfs_buf_ioend(bp, 0); | 1098 | xfs_buf_ioend(bp); |
1103 | 1099 | ||
1104 | return -EIO; | 1100 | return -EIO; |
1105 | } | 1101 | } |
@@ -1186,15 +1182,6 @@ xfs_bwrite( | |||
1186 | } | 1182 | } |
1187 | 1183 | ||
1188 | STATIC void | 1184 | STATIC void |
1189 | _xfs_buf_ioend( | ||
1190 | xfs_buf_t *bp, | ||
1191 | int schedule) | ||
1192 | { | ||
1193 | if (atomic_dec_and_test(&bp->b_io_remaining) == 1) | ||
1194 | xfs_buf_ioend(bp, schedule); | ||
1195 | } | ||
1196 | |||
1197 | STATIC void | ||
1198 | xfs_buf_bio_end_io( | 1185 | xfs_buf_bio_end_io( |
1199 | struct bio *bio, | 1186 | struct bio *bio, |
1200 | int error) | 1187 | int error) |
@@ -1211,7 +1198,8 @@ xfs_buf_bio_end_io( | |||
1211 | if (!bp->b_error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ)) | 1198 | if (!bp->b_error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ)) |
1212 | invalidate_kernel_vmap_range(bp->b_addr, xfs_buf_vmap_len(bp)); | 1199 | invalidate_kernel_vmap_range(bp->b_addr, xfs_buf_vmap_len(bp)); |
1213 | 1200 | ||
1214 | _xfs_buf_ioend(bp, 1); | 1201 | if (atomic_dec_and_test(&bp->b_io_remaining) == 1) |
1202 | xfs_buf_ioend_async(bp); | ||
1215 | bio_put(bio); | 1203 | bio_put(bio); |
1216 | } | 1204 | } |
1217 | 1205 | ||
@@ -1423,15 +1411,17 @@ xfs_buf_iorequest( | |||
1423 | /* | 1411 | /* |
1424 | * If _xfs_buf_ioapply failed or we are doing synchronous IO that | 1412 | * If _xfs_buf_ioapply failed or we are doing synchronous IO that |
1425 | * completes extremely quickly, we can get back here with only the IO | 1413 | * completes extremely quickly, we can get back here with only the IO |
1426 | * reference we took above. _xfs_buf_ioend will drop it to zero. Run | 1414 | * reference we took above. If we drop it to zero, run completion |
1427 | * completion processing synchronously so that we don't return to the | 1415 | * processing synchronously so that we don't return to the caller with |
1428 | * caller with completion still pending. This avoids unnecessary context | 1416 | * completion still pending. This avoids unnecessary context switches |
1429 | * switches associated with the end_io workqueue. | 1417 | * associated with the end_io workqueue. |
1430 | */ | 1418 | */ |
1431 | if (bp->b_error || !(bp->b_flags & XBF_ASYNC)) | 1419 | if (atomic_dec_and_test(&bp->b_io_remaining) == 1) { |
1432 | _xfs_buf_ioend(bp, 0); | 1420 | if (bp->b_error || !(bp->b_flags & XBF_ASYNC)) |
1433 | else | 1421 | xfs_buf_ioend(bp); |
1434 | _xfs_buf_ioend(bp, 1); | 1422 | else |
1423 | xfs_buf_ioend_async(bp); | ||
1424 | } | ||
1435 | 1425 | ||
1436 | xfs_buf_rele(bp); | 1426 | xfs_buf_rele(bp); |
1437 | } | 1427 | } |
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index c753183900b3..4585c1595a98 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h | |||
@@ -286,7 +286,7 @@ extern void xfs_buf_unlock(xfs_buf_t *); | |||
286 | 286 | ||
287 | /* Buffer Read and Write Routines */ | 287 | /* Buffer Read and Write Routines */ |
288 | extern int xfs_bwrite(struct xfs_buf *bp); | 288 | extern int xfs_bwrite(struct xfs_buf *bp); |
289 | extern void xfs_buf_ioend(xfs_buf_t *, int); | 289 | extern void xfs_buf_ioend(struct xfs_buf *bp); |
290 | extern void xfs_buf_ioerror(xfs_buf_t *, int); | 290 | extern void xfs_buf_ioerror(xfs_buf_t *, int); |
291 | extern void xfs_buf_ioerror_alert(struct xfs_buf *, const char *func); | 291 | extern void xfs_buf_ioerror_alert(struct xfs_buf *, const char *func); |
292 | extern void xfs_buf_iorequest(xfs_buf_t *); | 292 | extern void xfs_buf_iorequest(xfs_buf_t *); |
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 76007deed31f..4fd41b58e6d2 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
@@ -491,7 +491,7 @@ xfs_buf_item_unpin( | |||
491 | xfs_buf_ioerror(bp, -EIO); | 491 | xfs_buf_ioerror(bp, -EIO); |
492 | XFS_BUF_UNDONE(bp); | 492 | XFS_BUF_UNDONE(bp); |
493 | xfs_buf_stale(bp); | 493 | xfs_buf_stale(bp); |
494 | xfs_buf_ioend(bp, 0); | 494 | xfs_buf_ioend(bp); |
495 | } | 495 | } |
496 | } | 496 | } |
497 | 497 | ||
@@ -1115,7 +1115,7 @@ do_callbacks: | |||
1115 | xfs_buf_do_callbacks(bp); | 1115 | xfs_buf_do_callbacks(bp); |
1116 | bp->b_fspriv = NULL; | 1116 | bp->b_fspriv = NULL; |
1117 | bp->b_iodone = NULL; | 1117 | bp->b_iodone = NULL; |
1118 | xfs_buf_ioend(bp, 0); | 1118 | xfs_buf_ioend(bp); |
1119 | } | 1119 | } |
1120 | 1120 | ||
1121 | /* | 1121 | /* |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index fea3c92fb3f0..00d210bbf3c3 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -3056,7 +3056,7 @@ cluster_corrupt_out: | |||
3056 | XFS_BUF_UNDONE(bp); | 3056 | XFS_BUF_UNDONE(bp); |
3057 | xfs_buf_stale(bp); | 3057 | xfs_buf_stale(bp); |
3058 | xfs_buf_ioerror(bp, -EIO); | 3058 | xfs_buf_ioerror(bp, -EIO); |
3059 | xfs_buf_ioend(bp, 0); | 3059 | xfs_buf_ioend(bp); |
3060 | } else { | 3060 | } else { |
3061 | xfs_buf_stale(bp); | 3061 | xfs_buf_stale(bp); |
3062 | xfs_buf_relse(bp); | 3062 | xfs_buf_relse(bp); |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 85f36f212641..3567396f4428 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -1678,7 +1678,7 @@ xlog_bdstrat( | |||
1678 | if (iclog->ic_state & XLOG_STATE_IOERROR) { | 1678 | if (iclog->ic_state & XLOG_STATE_IOERROR) { |
1679 | xfs_buf_ioerror(bp, -EIO); | 1679 | xfs_buf_ioerror(bp, -EIO); |
1680 | xfs_buf_stale(bp); | 1680 | xfs_buf_stale(bp); |
1681 | xfs_buf_ioend(bp, 0); | 1681 | xfs_buf_ioend(bp); |
1682 | /* | 1682 | /* |
1683 | * It would seem logical to return EIO here, but we rely on | 1683 | * It would seem logical to return EIO here, but we rely on |
1684 | * the log state machine to propagate I/O errors instead of | 1684 | * the log state machine to propagate I/O errors instead of |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 1fd5787add99..4ba19bf7da1f 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -383,7 +383,7 @@ xlog_recover_iodone( | |||
383 | SHUTDOWN_META_IO_ERROR); | 383 | SHUTDOWN_META_IO_ERROR); |
384 | } | 384 | } |
385 | bp->b_iodone = NULL; | 385 | bp->b_iodone = NULL; |
386 | xfs_buf_ioend(bp, 0); | 386 | xfs_buf_ioend(bp); |
387 | } | 387 | } |
388 | 388 | ||
389 | /* | 389 | /* |