aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_aops.c54
1 files changed, 39 insertions, 15 deletions
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index e562dd43f41f..e57e2daa357c 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -481,11 +481,17 @@ static inline int bio_add_buffer(struct bio *bio, struct buffer_head *bh)
481 * 481 *
482 * The fix is two passes across the ioend list - one to start writeback on the 482 * The fix is two passes across the ioend list - one to start writeback on the
483 * buffer_heads, and then submit them for I/O on the second pass. 483 * buffer_heads, and then submit them for I/O on the second pass.
484 *
485 * If @fail is non-zero, it means that we have a situation where some part of
486 * the submission process has failed after we have marked paged for writeback
487 * and unlocked them. In this situation, we need to fail the ioend chain rather
488 * than submit it to IO. This typically only happens on a filesystem shutdown.
484 */ 489 */
485STATIC void 490STATIC void
486xfs_submit_ioend( 491xfs_submit_ioend(
487 struct writeback_control *wbc, 492 struct writeback_control *wbc,
488 xfs_ioend_t *ioend) 493 xfs_ioend_t *ioend,
494 int fail)
489{ 495{
490 xfs_ioend_t *head = ioend; 496 xfs_ioend_t *head = ioend;
491 xfs_ioend_t *next; 497 xfs_ioend_t *next;
@@ -506,6 +512,18 @@ xfs_submit_ioend(
506 next = ioend->io_list; 512 next = ioend->io_list;
507 bio = NULL; 513 bio = NULL;
508 514
515 /*
516 * If we are failing the IO now, just mark the ioend with an
517 * error and finish it. This will run IO completion immediately
518 * as there is only one reference to the ioend at this point in
519 * time.
520 */
521 if (fail) {
522 ioend->io_error = -fail;
523 xfs_finish_ioend(ioend);
524 continue;
525 }
526
509 for (bh = ioend->io_buffer_head; bh; bh = bh->b_private) { 527 for (bh = ioend->io_buffer_head; bh; bh = bh->b_private) {
510 528
511 if (!bio) { 529 if (!bio) {
@@ -1060,7 +1078,18 @@ xfs_vm_writepage(
1060 1078
1061 xfs_start_page_writeback(page, 1, count); 1079 xfs_start_page_writeback(page, 1, count);
1062 1080
1063 if (ioend && imap_valid) { 1081 /* if there is no IO to be submitted for this page, we are done */
1082 if (!ioend)
1083 return 0;
1084
1085 ASSERT(iohead);
1086
1087 /*
1088 * Any errors from this point onwards need tobe reported through the IO
1089 * completion path as we have marked the initial page as under writeback
1090 * and unlocked it.
1091 */
1092 if (imap_valid) {
1064 xfs_off_t end_index; 1093 xfs_off_t end_index;
1065 1094
1066 end_index = imap.br_startoff + imap.br_blockcount; 1095 end_index = imap.br_startoff + imap.br_blockcount;
@@ -1079,20 +1108,15 @@ xfs_vm_writepage(
1079 wbc, end_index); 1108 wbc, end_index);
1080 } 1109 }
1081 1110
1082 if (iohead) {
1083 /*
1084 * Reserve log space if we might write beyond the on-disk
1085 * inode size.
1086 */
1087 if (ioend->io_type != XFS_IO_UNWRITTEN &&
1088 xfs_ioend_is_append(ioend)) {
1089 err = xfs_setfilesize_trans_alloc(ioend);
1090 if (err)
1091 goto error;
1092 }
1093 1111
1094 xfs_submit_ioend(wbc, iohead); 1112 /*
1095 } 1113 * Reserve log space if we might write beyond the on-disk inode size.
1114 */
1115 err = 0;
1116 if (ioend->io_type != XFS_IO_UNWRITTEN && xfs_ioend_is_append(ioend))
1117 err = xfs_setfilesize_trans_alloc(ioend);
1118
1119 xfs_submit_ioend(wbc, iohead, err);
1096 1120
1097 return 0; 1121 return 0;
1098 1122