diff options
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_bmap_util.c | 14 | ||||
-rw-r--r-- | fs/xfs/xfs_buf.c | 169 | ||||
-rw-r--r-- | fs/xfs/xfs_buf.h | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_buf_item.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_log.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 30 | ||||
-rw-r--r-- | fs/xfs/xfs_trace.h | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_buf.c | 19 |
8 files changed, 117 insertions, 128 deletions
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 2f1e30d39a35..c53cc036d6e7 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c | |||
@@ -1157,12 +1157,7 @@ xfs_zero_remaining_bytes( | |||
1157 | XFS_BUF_READ(bp); | 1157 | XFS_BUF_READ(bp); |
1158 | XFS_BUF_SET_ADDR(bp, xfs_fsb_to_db(ip, imap.br_startblock)); | 1158 | XFS_BUF_SET_ADDR(bp, xfs_fsb_to_db(ip, imap.br_startblock)); |
1159 | 1159 | ||
1160 | if (XFS_FORCED_SHUTDOWN(mp)) { | 1160 | error = xfs_buf_submit_wait(bp); |
1161 | error = -EIO; | ||
1162 | break; | ||
1163 | } | ||
1164 | xfs_buf_iorequest(bp); | ||
1165 | error = xfs_buf_iowait(bp); | ||
1166 | if (error) { | 1161 | if (error) { |
1167 | xfs_buf_ioerror_alert(bp, | 1162 | xfs_buf_ioerror_alert(bp, |
1168 | "xfs_zero_remaining_bytes(read)"); | 1163 | "xfs_zero_remaining_bytes(read)"); |
@@ -1175,12 +1170,7 @@ xfs_zero_remaining_bytes( | |||
1175 | XFS_BUF_UNREAD(bp); | 1170 | XFS_BUF_UNREAD(bp); |
1176 | XFS_BUF_WRITE(bp); | 1171 | XFS_BUF_WRITE(bp); |
1177 | 1172 | ||
1178 | if (XFS_FORCED_SHUTDOWN(mp)) { | 1173 | error = xfs_buf_submit_wait(bp); |
1179 | error = -EIO; | ||
1180 | break; | ||
1181 | } | ||
1182 | xfs_buf_iorequest(bp); | ||
1183 | error = xfs_buf_iowait(bp); | ||
1184 | if (error) { | 1174 | if (error) { |
1185 | xfs_buf_ioerror_alert(bp, | 1175 | xfs_buf_ioerror_alert(bp, |
1186 | "xfs_zero_remaining_bytes(write)"); | 1176 | "xfs_zero_remaining_bytes(write)"); |
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 108eba7ad5c1..d99ec8335750 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -623,10 +623,11 @@ _xfs_buf_read( | |||
623 | bp->b_flags &= ~(XBF_WRITE | XBF_ASYNC | XBF_READ_AHEAD); | 623 | bp->b_flags &= ~(XBF_WRITE | XBF_ASYNC | XBF_READ_AHEAD); |
624 | bp->b_flags |= flags & (XBF_READ | XBF_ASYNC | XBF_READ_AHEAD); | 624 | bp->b_flags |= flags & (XBF_READ | XBF_ASYNC | XBF_READ_AHEAD); |
625 | 625 | ||
626 | xfs_buf_iorequest(bp); | 626 | if (flags & XBF_ASYNC) { |
627 | if (flags & XBF_ASYNC) | 627 | xfs_buf_submit(bp); |
628 | return 0; | 628 | return 0; |
629 | return xfs_buf_iowait(bp); | 629 | } |
630 | return xfs_buf_submit_wait(bp); | ||
630 | } | 631 | } |
631 | 632 | ||
632 | xfs_buf_t * | 633 | xfs_buf_t * |
@@ -708,12 +709,7 @@ xfs_buf_read_uncached( | |||
708 | bp->b_flags |= XBF_READ; | 709 | bp->b_flags |= XBF_READ; |
709 | bp->b_ops = ops; | 710 | bp->b_ops = ops; |
710 | 711 | ||
711 | if (XFS_FORCED_SHUTDOWN(target->bt_mount)) { | 712 | xfs_buf_submit_wait(bp); |
712 | xfs_buf_relse(bp); | ||
713 | return NULL; | ||
714 | } | ||
715 | xfs_buf_iorequest(bp); | ||
716 | xfs_buf_iowait(bp); | ||
717 | return bp; | 713 | return bp; |
718 | } | 714 | } |
719 | 715 | ||
@@ -1028,12 +1024,8 @@ xfs_buf_ioend( | |||
1028 | (*(bp->b_iodone))(bp); | 1024 | (*(bp->b_iodone))(bp); |
1029 | else if (bp->b_flags & XBF_ASYNC) | 1025 | else if (bp->b_flags & XBF_ASYNC) |
1030 | xfs_buf_relse(bp); | 1026 | xfs_buf_relse(bp); |
1031 | else { | 1027 | else |
1032 | complete(&bp->b_iowait); | 1028 | complete(&bp->b_iowait); |
1033 | |||
1034 | /* release the !XBF_ASYNC ref now we are done. */ | ||
1035 | xfs_buf_rele(bp); | ||
1036 | } | ||
1037 | } | 1029 | } |
1038 | 1030 | ||
1039 | static void | 1031 | static void |
@@ -1086,21 +1078,7 @@ xfs_bwrite( | |||
1086 | bp->b_flags &= ~(XBF_ASYNC | XBF_READ | _XBF_DELWRI_Q | | 1078 | bp->b_flags &= ~(XBF_ASYNC | XBF_READ | _XBF_DELWRI_Q | |
1087 | XBF_WRITE_FAIL | XBF_DONE); | 1079 | XBF_WRITE_FAIL | XBF_DONE); |
1088 | 1080 | ||
1089 | if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { | 1081 | error = xfs_buf_submit_wait(bp); |
1090 | trace_xfs_bdstrat_shut(bp, _RET_IP_); | ||
1091 | |||
1092 | xfs_buf_ioerror(bp, -EIO); | ||
1093 | xfs_buf_stale(bp); | ||
1094 | |||
1095 | /* sync IO, xfs_buf_ioend is going to remove a ref here */ | ||
1096 | xfs_buf_hold(bp); | ||
1097 | xfs_buf_ioend(bp); | ||
1098 | return -EIO; | ||
1099 | } | ||
1100 | |||
1101 | xfs_buf_iorequest(bp); | ||
1102 | |||
1103 | error = xfs_buf_iowait(bp); | ||
1104 | if (error) { | 1082 | if (error) { |
1105 | xfs_force_shutdown(bp->b_target->bt_mount, | 1083 | xfs_force_shutdown(bp->b_target->bt_mount, |
1106 | SHUTDOWN_META_IO_ERROR); | 1084 | SHUTDOWN_META_IO_ERROR); |
@@ -1209,7 +1187,7 @@ next_chunk: | |||
1209 | } else { | 1187 | } else { |
1210 | /* | 1188 | /* |
1211 | * This is guaranteed not to be the last io reference count | 1189 | * This is guaranteed not to be the last io reference count |
1212 | * because the caller (xfs_buf_iorequest) holds a count itself. | 1190 | * because the caller (xfs_buf_submit) holds a count itself. |
1213 | */ | 1191 | */ |
1214 | atomic_dec(&bp->b_io_remaining); | 1192 | atomic_dec(&bp->b_io_remaining); |
1215 | xfs_buf_ioerror(bp, -EIO); | 1193 | xfs_buf_ioerror(bp, -EIO); |
@@ -1299,13 +1277,29 @@ _xfs_buf_ioapply( | |||
1299 | blk_finish_plug(&plug); | 1277 | blk_finish_plug(&plug); |
1300 | } | 1278 | } |
1301 | 1279 | ||
1280 | /* | ||
1281 | * Asynchronous IO submission path. This transfers the buffer lock ownership and | ||
1282 | * the current reference to the IO. It is not safe to reference the buffer after | ||
1283 | * a call to this function unless the caller holds an additional reference | ||
1284 | * itself. | ||
1285 | */ | ||
1302 | void | 1286 | void |
1303 | xfs_buf_iorequest( | 1287 | xfs_buf_submit( |
1304 | xfs_buf_t *bp) | 1288 | struct xfs_buf *bp) |
1305 | { | 1289 | { |
1306 | trace_xfs_buf_iorequest(bp, _RET_IP_); | 1290 | trace_xfs_buf_submit(bp, _RET_IP_); |
1307 | 1291 | ||
1308 | ASSERT(!(bp->b_flags & _XBF_DELWRI_Q)); | 1292 | ASSERT(!(bp->b_flags & _XBF_DELWRI_Q)); |
1293 | ASSERT(bp->b_flags & XBF_ASYNC); | ||
1294 | |||
1295 | /* on shutdown we stale and complete the buffer immediately */ | ||
1296 | if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { | ||
1297 | xfs_buf_ioerror(bp, -EIO); | ||
1298 | bp->b_flags &= ~XBF_DONE; | ||
1299 | xfs_buf_stale(bp); | ||
1300 | xfs_buf_ioend(bp); | ||
1301 | return; | ||
1302 | } | ||
1309 | 1303 | ||
1310 | if (bp->b_flags & XBF_WRITE) | 1304 | if (bp->b_flags & XBF_WRITE) |
1311 | xfs_buf_wait_unpin(bp); | 1305 | xfs_buf_wait_unpin(bp); |
@@ -1314,25 +1308,14 @@ xfs_buf_iorequest( | |||
1314 | bp->b_io_error = 0; | 1308 | bp->b_io_error = 0; |
1315 | 1309 | ||
1316 | /* | 1310 | /* |
1317 | * Take references to the buffer. For XBF_ASYNC buffers, holding a | 1311 | * The caller's reference is released during I/O completion. |
1318 | * reference for as long as submission takes is all that is necessary | 1312 | * This occurs some time after the last b_io_remaining reference is |
1319 | * here. The IO inherits the lock and hold count from the submitter, | 1313 | * released, so after we drop our Io reference we have to have some |
1320 | * and these are release during IO completion processing. Taking a hold | 1314 | * other reference to ensure the buffer doesn't go away from underneath |
1321 | * over submission ensures that the buffer is not freed until we have | 1315 | * us. Take a direct reference to ensure we have safe access to the |
1322 | * completed all processing, regardless of when IO errors occur or are | 1316 | * buffer until we are finished with it. |
1323 | * reported. | ||
1324 | * | ||
1325 | * However, for synchronous IO, the IO does not inherit the submitters | ||
1326 | * reference count, nor the buffer lock. Hence we need to take an extra | ||
1327 | * reference to the buffer for the for the IO context so that we can | ||
1328 | * guarantee the buffer is not freed until all IO completion processing | ||
1329 | * is done. Otherwise the caller can drop their reference while the IO | ||
1330 | * is still in progress and hence trigger a use-after-free situation. | ||
1331 | */ | 1317 | */ |
1332 | xfs_buf_hold(bp); | 1318 | xfs_buf_hold(bp); |
1333 | if (!(bp->b_flags & XBF_ASYNC)) | ||
1334 | xfs_buf_hold(bp); | ||
1335 | |||
1336 | 1319 | ||
1337 | /* | 1320 | /* |
1338 | * Set the count to 1 initially, this will stop an I/O completion | 1321 | * Set the count to 1 initially, this will stop an I/O completion |
@@ -1343,40 +1326,82 @@ xfs_buf_iorequest( | |||
1343 | _xfs_buf_ioapply(bp); | 1326 | _xfs_buf_ioapply(bp); |
1344 | 1327 | ||
1345 | /* | 1328 | /* |
1346 | * If _xfs_buf_ioapply failed or we are doing synchronous IO that | 1329 | * If _xfs_buf_ioapply failed, we can get back here with only the IO |
1347 | * completes extremely quickly, we can get back here with only the IO | 1330 | * reference we took above. If we drop it to zero, run completion so |
1348 | * reference we took above. If we drop it to zero, run completion | 1331 | * that we don't return to the caller with completion still pending. |
1349 | * processing synchronously so that we don't return to the caller with | ||
1350 | * completion still pending. This avoids unnecessary context switches | ||
1351 | * associated with the end_io workqueue. | ||
1352 | */ | 1332 | */ |
1353 | if (atomic_dec_and_test(&bp->b_io_remaining) == 1) { | 1333 | if (atomic_dec_and_test(&bp->b_io_remaining) == 1) { |
1354 | if (bp->b_error || !(bp->b_flags & XBF_ASYNC)) | 1334 | if (bp->b_error) |
1355 | xfs_buf_ioend(bp); | 1335 | xfs_buf_ioend(bp); |
1356 | else | 1336 | else |
1357 | xfs_buf_ioend_async(bp); | 1337 | xfs_buf_ioend_async(bp); |
1358 | } | 1338 | } |
1359 | 1339 | ||
1360 | xfs_buf_rele(bp); | 1340 | xfs_buf_rele(bp); |
1341 | /* Note: it is not safe to reference bp now we've dropped our ref */ | ||
1361 | } | 1342 | } |
1362 | 1343 | ||
1363 | /* | 1344 | /* |
1364 | * Waits for I/O to complete on the buffer supplied. It returns immediately if | 1345 | * Synchronous buffer IO submission path, read or write. |
1365 | * no I/O is pending or there is already a pending error on the buffer, in which | ||
1366 | * case nothing will ever complete. It returns the I/O error code, if any, or | ||
1367 | * 0 if there was no error. | ||
1368 | */ | 1346 | */ |
1369 | int | 1347 | int |
1370 | xfs_buf_iowait( | 1348 | xfs_buf_submit_wait( |
1371 | xfs_buf_t *bp) | 1349 | struct xfs_buf *bp) |
1372 | { | 1350 | { |
1373 | trace_xfs_buf_iowait(bp, _RET_IP_); | 1351 | int error; |
1374 | 1352 | ||
1375 | if (!bp->b_error) | 1353 | trace_xfs_buf_submit_wait(bp, _RET_IP_); |
1376 | wait_for_completion(&bp->b_iowait); | 1354 | |
1355 | ASSERT(!(bp->b_flags & (_XBF_DELWRI_Q | XBF_ASYNC))); | ||
1377 | 1356 | ||
1357 | if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { | ||
1358 | xfs_buf_ioerror(bp, -EIO); | ||
1359 | xfs_buf_stale(bp); | ||
1360 | bp->b_flags &= ~XBF_DONE; | ||
1361 | return -EIO; | ||
1362 | } | ||
1363 | |||
1364 | if (bp->b_flags & XBF_WRITE) | ||
1365 | xfs_buf_wait_unpin(bp); | ||
1366 | |||
1367 | /* clear the internal error state to avoid spurious errors */ | ||
1368 | bp->b_io_error = 0; | ||
1369 | |||
1370 | /* | ||
1371 | * For synchronous IO, the IO does not inherit the submitters reference | ||
1372 | * count, nor the buffer lock. Hence we cannot release the reference we | ||
1373 | * are about to take until we've waited for all IO completion to occur, | ||
1374 | * including any xfs_buf_ioend_async() work that may be pending. | ||
1375 | */ | ||
1376 | xfs_buf_hold(bp); | ||
1377 | |||
1378 | /* | ||
1379 | * Set the count to 1 initially, this will stop an I/O completion | ||
1380 | * callout which happens before we have started all the I/O from calling | ||
1381 | * xfs_buf_ioend too early. | ||
1382 | */ | ||
1383 | atomic_set(&bp->b_io_remaining, 1); | ||
1384 | _xfs_buf_ioapply(bp); | ||
1385 | |||
1386 | /* | ||
1387 | * make sure we run completion synchronously if it raced with us and is | ||
1388 | * already complete. | ||
1389 | */ | ||
1390 | if (atomic_dec_and_test(&bp->b_io_remaining) == 1) | ||
1391 | xfs_buf_ioend(bp); | ||
1392 | |||
1393 | /* wait for completion before gathering the error from the buffer */ | ||
1394 | trace_xfs_buf_iowait(bp, _RET_IP_); | ||
1395 | wait_for_completion(&bp->b_iowait); | ||
1378 | trace_xfs_buf_iowait_done(bp, _RET_IP_); | 1396 | trace_xfs_buf_iowait_done(bp, _RET_IP_); |
1379 | return bp->b_error; | 1397 | error = bp->b_error; |
1398 | |||
1399 | /* | ||
1400 | * all done now, we can release the hold that keeps the buffer | ||
1401 | * referenced for the entire IO. | ||
1402 | */ | ||
1403 | xfs_buf_rele(bp); | ||
1404 | return error; | ||
1380 | } | 1405 | } |
1381 | 1406 | ||
1382 | xfs_caddr_t | 1407 | xfs_caddr_t |
@@ -1782,15 +1807,7 @@ __xfs_buf_delwri_submit( | |||
1782 | else | 1807 | else |
1783 | list_del_init(&bp->b_list); | 1808 | list_del_init(&bp->b_list); |
1784 | 1809 | ||
1785 | if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { | 1810 | xfs_buf_submit(bp); |
1786 | trace_xfs_bdstrat_shut(bp, _RET_IP_); | ||
1787 | |||
1788 | xfs_buf_ioerror(bp, -EIO); | ||
1789 | xfs_buf_stale(bp); | ||
1790 | xfs_buf_ioend(bp); | ||
1791 | continue; | ||
1792 | } | ||
1793 | xfs_buf_iorequest(bp); | ||
1794 | } | 1811 | } |
1795 | blk_finish_plug(&plug); | 1812 | blk_finish_plug(&plug); |
1796 | 1813 | ||
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index d8f57f654f92..0acfc30ec0fd 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h | |||
@@ -290,8 +290,8 @@ extern int xfs_bwrite(struct xfs_buf *bp); | |||
290 | extern void xfs_buf_ioend(struct xfs_buf *bp); | 290 | extern void xfs_buf_ioend(struct xfs_buf *bp); |
291 | extern void xfs_buf_ioerror(xfs_buf_t *, int); | 291 | extern void xfs_buf_ioerror(xfs_buf_t *, int); |
292 | extern void xfs_buf_ioerror_alert(struct xfs_buf *, const char *func); | 292 | extern void xfs_buf_ioerror_alert(struct xfs_buf *, const char *func); |
293 | extern void xfs_buf_iorequest(xfs_buf_t *); | 293 | extern void xfs_buf_submit(struct xfs_buf *bp); |
294 | extern int xfs_buf_iowait(xfs_buf_t *); | 294 | extern int xfs_buf_submit_wait(struct xfs_buf *bp); |
295 | extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, void *, | 295 | extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, void *, |
296 | xfs_buf_rw_t); | 296 | xfs_buf_rw_t); |
297 | #define xfs_buf_zero(bp, off, len) \ | 297 | #define xfs_buf_zero(bp, off, len) \ |
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 4fd41b58e6d2..cbea9099b843 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
@@ -1081,7 +1081,7 @@ xfs_buf_iodone_callbacks( | |||
1081 | * a way to shut the filesystem down if the writes keep failing. | 1081 | * a way to shut the filesystem down if the writes keep failing. |
1082 | * | 1082 | * |
1083 | * In practice we'll shut the filesystem down soon as non-transient | 1083 | * In practice we'll shut the filesystem down soon as non-transient |
1084 | * erorrs tend to affect the whole device and a failing log write | 1084 | * errors tend to affect the whole device and a failing log write |
1085 | * will make us give up. But we really ought to do better here. | 1085 | * will make us give up. But we really ought to do better here. |
1086 | */ | 1086 | */ |
1087 | if (XFS_BUF_ISASYNC(bp)) { | 1087 | if (XFS_BUF_ISASYNC(bp)) { |
@@ -1094,7 +1094,7 @@ xfs_buf_iodone_callbacks( | |||
1094 | if (!(bp->b_flags & (XBF_STALE|XBF_WRITE_FAIL))) { | 1094 | if (!(bp->b_flags & (XBF_STALE|XBF_WRITE_FAIL))) { |
1095 | bp->b_flags |= XBF_WRITE | XBF_ASYNC | | 1095 | bp->b_flags |= XBF_WRITE | XBF_ASYNC | |
1096 | XBF_DONE | XBF_WRITE_FAIL; | 1096 | XBF_DONE | XBF_WRITE_FAIL; |
1097 | xfs_buf_iorequest(bp); | 1097 | xfs_buf_submit(bp); |
1098 | } else { | 1098 | } else { |
1099 | xfs_buf_relse(bp); | 1099 | xfs_buf_relse(bp); |
1100 | } | 1100 | } |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 3567396f4428..fe88ef67f93a 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -1688,7 +1688,7 @@ xlog_bdstrat( | |||
1688 | return 0; | 1688 | return 0; |
1689 | } | 1689 | } |
1690 | 1690 | ||
1691 | xfs_buf_iorequest(bp); | 1691 | xfs_buf_submit(bp); |
1692 | return 0; | 1692 | return 0; |
1693 | } | 1693 | } |
1694 | 1694 | ||
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 4ba19bf7da1f..980e2968b907 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -193,12 +193,8 @@ xlog_bread_noalign( | |||
193 | bp->b_io_length = nbblks; | 193 | bp->b_io_length = nbblks; |
194 | bp->b_error = 0; | 194 | bp->b_error = 0; |
195 | 195 | ||
196 | if (XFS_FORCED_SHUTDOWN(log->l_mp)) | 196 | error = xfs_buf_submit_wait(bp); |
197 | return -EIO; | 197 | if (error && !XFS_FORCED_SHUTDOWN(log->l_mp)) |
198 | |||
199 | xfs_buf_iorequest(bp); | ||
200 | error = xfs_buf_iowait(bp); | ||
201 | if (error) | ||
202 | xfs_buf_ioerror_alert(bp, __func__); | 198 | xfs_buf_ioerror_alert(bp, __func__); |
203 | return error; | 199 | return error; |
204 | } | 200 | } |
@@ -378,9 +374,11 @@ xlog_recover_iodone( | |||
378 | * We're not going to bother about retrying | 374 | * We're not going to bother about retrying |
379 | * this during recovery. One strike! | 375 | * this during recovery. One strike! |
380 | */ | 376 | */ |
381 | xfs_buf_ioerror_alert(bp, __func__); | 377 | if (!XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { |
382 | xfs_force_shutdown(bp->b_target->bt_mount, | 378 | xfs_buf_ioerror_alert(bp, __func__); |
383 | SHUTDOWN_META_IO_ERROR); | 379 | xfs_force_shutdown(bp->b_target->bt_mount, |
380 | SHUTDOWN_META_IO_ERROR); | ||
381 | } | ||
384 | } | 382 | } |
385 | bp->b_iodone = NULL; | 383 | bp->b_iodone = NULL; |
386 | xfs_buf_ioend(bp); | 384 | xfs_buf_ioend(bp); |
@@ -4427,16 +4425,12 @@ xlog_do_recover( | |||
4427 | XFS_BUF_UNASYNC(bp); | 4425 | XFS_BUF_UNASYNC(bp); |
4428 | bp->b_ops = &xfs_sb_buf_ops; | 4426 | bp->b_ops = &xfs_sb_buf_ops; |
4429 | 4427 | ||
4430 | if (XFS_FORCED_SHUTDOWN(log->l_mp)) { | 4428 | error = xfs_buf_submit_wait(bp); |
4431 | xfs_buf_relse(bp); | ||
4432 | return -EIO; | ||
4433 | } | ||
4434 | |||
4435 | xfs_buf_iorequest(bp); | ||
4436 | error = xfs_buf_iowait(bp); | ||
4437 | if (error) { | 4429 | if (error) { |
4438 | xfs_buf_ioerror_alert(bp, __func__); | 4430 | if (!XFS_FORCED_SHUTDOWN(log->l_mp)) { |
4439 | ASSERT(0); | 4431 | xfs_buf_ioerror_alert(bp, __func__); |
4432 | ASSERT(0); | ||
4433 | } | ||
4440 | xfs_buf_relse(bp); | 4434 | xfs_buf_relse(bp); |
4441 | return error; | 4435 | return error; |
4442 | } | 4436 | } |
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 152f82782630..51372e34d988 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h | |||
@@ -349,7 +349,8 @@ DEFINE_BUF_EVENT(xfs_buf_free); | |||
349 | DEFINE_BUF_EVENT(xfs_buf_hold); | 349 | DEFINE_BUF_EVENT(xfs_buf_hold); |
350 | DEFINE_BUF_EVENT(xfs_buf_rele); | 350 | DEFINE_BUF_EVENT(xfs_buf_rele); |
351 | DEFINE_BUF_EVENT(xfs_buf_iodone); | 351 | DEFINE_BUF_EVENT(xfs_buf_iodone); |
352 | DEFINE_BUF_EVENT(xfs_buf_iorequest); | 352 | DEFINE_BUF_EVENT(xfs_buf_submit); |
353 | DEFINE_BUF_EVENT(xfs_buf_submit_wait); | ||
353 | DEFINE_BUF_EVENT(xfs_buf_bawrite); | 354 | DEFINE_BUF_EVENT(xfs_buf_bawrite); |
354 | DEFINE_BUF_EVENT(xfs_buf_lock); | 355 | DEFINE_BUF_EVENT(xfs_buf_lock); |
355 | DEFINE_BUF_EVENT(xfs_buf_lock_done); | 356 | DEFINE_BUF_EVENT(xfs_buf_lock_done); |
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index db4be5b1d732..e2b2216b1635 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c | |||
@@ -318,23 +318,10 @@ xfs_trans_read_buf_map( | |||
318 | XFS_BUF_READ(bp); | 318 | XFS_BUF_READ(bp); |
319 | bp->b_ops = ops; | 319 | bp->b_ops = ops; |
320 | 320 | ||
321 | /* | 321 | error = xfs_buf_submit_wait(bp); |
322 | * XXX(hch): clean up the error handling here to be less | ||
323 | * of a mess.. | ||
324 | */ | ||
325 | if (XFS_FORCED_SHUTDOWN(mp)) { | ||
326 | trace_xfs_bdstrat_shut(bp, _RET_IP_); | ||
327 | bp->b_flags &= ~(XBF_READ | XBF_DONE); | ||
328 | xfs_buf_ioerror(bp, -EIO); | ||
329 | xfs_buf_stale(bp); | ||
330 | xfs_buf_relse(bp); | ||
331 | return -EIO; | ||
332 | } | ||
333 | |||
334 | xfs_buf_iorequest(bp); | ||
335 | error = xfs_buf_iowait(bp); | ||
336 | if (error) { | 322 | if (error) { |
337 | xfs_buf_ioerror_alert(bp, __func__); | 323 | if (!XFS_FORCED_SHUTDOWN(mp)) |
324 | xfs_buf_ioerror_alert(bp, __func__); | ||
338 | xfs_buf_relse(bp); | 325 | xfs_buf_relse(bp); |
339 | /* | 326 | /* |
340 | * We can gracefully recover from most read | 327 | * We can gracefully recover from most read |