aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c29
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;