diff options
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index a1e3f3ea334b..02ec14eeb0ce 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -410,13 +410,12 @@ xfs_fs_write_inode( | |||
410 | flags |= FLUSH_SYNC; | 410 | flags |= FLUSH_SYNC; |
411 | } | 411 | } |
412 | error = xfs_inode_flush(XFS_I(inode), flags); | 412 | error = xfs_inode_flush(XFS_I(inode), flags); |
413 | if (error == EAGAIN) { | 413 | /* |
414 | if (sync) | 414 | * if we failed to write out the inode then mark |
415 | error = xfs_inode_flush(XFS_I(inode), | 415 | * it dirty again so we'll try again later. |
416 | flags | FLUSH_LOG); | 416 | */ |
417 | else | 417 | if (error) |
418 | error = 0; | 418 | mark_inode_dirty_sync(inode); |
419 | } | ||
420 | 419 | ||
421 | return -error; | 420 | return -error; |
422 | } | 421 | } |
@@ -622,7 +621,19 @@ xfs_fs_sync_super( | |||
622 | int error; | 621 | int error; |
623 | int flags; | 622 | int flags; |
624 | 623 | ||
625 | if (unlikely(sb->s_frozen == SB_FREEZE_WRITE)) { | 624 | /* |
625 | * Treat a sync operation like a freeze. This is to work | ||
626 | * around a race in sync_inodes() which works in two phases | ||
627 | * - an asynchronous flush, which can write out an inode | ||
628 | * without waiting for file size updates to complete, and a | ||
629 | * synchronous flush, which wont do anything because the | ||
630 | * async flush removed the inode's dirty flag. Also | ||
631 | * sync_inodes() will not see any files that just have | ||
632 | * outstanding transactions to be flushed because we don't | ||
633 | * dirty the Linux inode until after the transaction I/O | ||
634 | * completes. | ||
635 | */ | ||
636 | if (wait || unlikely(sb->s_frozen == SB_FREEZE_WRITE)) { | ||
626 | /* | 637 | /* |
627 | * First stage of freeze - no more writers will make progress | 638 | * First stage of freeze - no more writers will make progress |
628 | * now we are here, so we flush delwri and delalloc buffers | 639 | * now we are here, so we flush delwri and delalloc buffers |
@@ -633,7 +644,7 @@ xfs_fs_sync_super( | |||
633 | */ | 644 | */ |
634 | flags = SYNC_DATA_QUIESCE; | 645 | flags = SYNC_DATA_QUIESCE; |
635 | } else | 646 | } else |
636 | flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0); | 647 | flags = SYNC_FSDATA; |
637 | 648 | ||
638 | error = xfs_sync(mp, flags); | 649 | error = xfs_sync(mp, flags); |
639 | sb->s_dirt = 0; | 650 | sb->s_dirt = 0; |