aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_bmap_util.c14
-rw-r--r--fs/xfs/xfs_buf.c169
-rw-r--r--fs/xfs/xfs_buf.h4
-rw-r--r--fs/xfs/xfs_buf_item.c4
-rw-r--r--fs/xfs/xfs_log.c2
-rw-r--r--fs/xfs/xfs_log_recover.c30
-rw-r--r--fs/xfs/xfs_trace.h3
-rw-r--r--fs/xfs/xfs_trans_buf.c19
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
632xfs_buf_t * 633xfs_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
1039static void 1031static 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 */
1302void 1286void
1303xfs_buf_iorequest( 1287xfs_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 */
1369int 1347int
1370xfs_buf_iowait( 1348xfs_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
1382xfs_caddr_t 1407xfs_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);
290extern void xfs_buf_ioend(struct xfs_buf *bp); 290extern void xfs_buf_ioend(struct xfs_buf *bp);
291extern void xfs_buf_ioerror(xfs_buf_t *, int); 291extern void xfs_buf_ioerror(xfs_buf_t *, int);
292extern void xfs_buf_ioerror_alert(struct xfs_buf *, const char *func); 292extern void xfs_buf_ioerror_alert(struct xfs_buf *, const char *func);
293extern void xfs_buf_iorequest(xfs_buf_t *); 293extern void xfs_buf_submit(struct xfs_buf *bp);
294extern int xfs_buf_iowait(xfs_buf_t *); 294extern int xfs_buf_submit_wait(struct xfs_buf *bp);
295extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, void *, 295extern 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);
349DEFINE_BUF_EVENT(xfs_buf_hold); 349DEFINE_BUF_EVENT(xfs_buf_hold);
350DEFINE_BUF_EVENT(xfs_buf_rele); 350DEFINE_BUF_EVENT(xfs_buf_rele);
351DEFINE_BUF_EVENT(xfs_buf_iodone); 351DEFINE_BUF_EVENT(xfs_buf_iodone);
352DEFINE_BUF_EVENT(xfs_buf_iorequest); 352DEFINE_BUF_EVENT(xfs_buf_submit);
353DEFINE_BUF_EVENT(xfs_buf_submit_wait);
353DEFINE_BUF_EVENT(xfs_buf_bawrite); 354DEFINE_BUF_EVENT(xfs_buf_bawrite);
354DEFINE_BUF_EVENT(xfs_buf_lock); 355DEFINE_BUF_EVENT(xfs_buf_lock);
355DEFINE_BUF_EVENT(xfs_buf_lock_done); 356DEFINE_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