summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_sync.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2012-01-07 12:30:20 +0000
committerArnd Bergmann <arnd@arndb.de>2012-01-07 12:42:17 +0000
commit237c78beb8a988453bac1993d21f025d070a0d8d (patch)
tree9864f0924650770881141359a2d5bac623949789 /fs/xfs/xfs_sync.c
parent4eb821999086417ab42a15174b51497122fc406e (diff)
parent7b9dd47136c07ffd883aff6926c7b281e4c1eea4 (diff)
Merge branch 'depends/rmk/for-linus' into samsung/dt
Conflicts: arch/arm/mach-exynos/Makefile arch/arm/mach-exynos/cpu.c -> common.c arch/arm/mach-exynos/include/mach/entry-macro.S arch/arm/mach-exynos/init.c -> common.c arch/arm/mach-s5p64x0/init.c -> common.c arch/arm/mach-s5pv210/init.c -> common.c Multiple files were moved into common.c files in the rmk/for-linus branch, so this moves over the samsung/dt changes to the new files. Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'fs/xfs/xfs_sync.c')
-rw-r--r--fs/xfs/xfs_sync.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/fs/xfs/xfs_sync.c b/fs/xfs/xfs_sync.c
index be5c51d8f757..f0994aedcd15 100644
--- a/fs/xfs/xfs_sync.c
+++ b/fs/xfs/xfs_sync.c
@@ -336,6 +336,32 @@ xfs_sync_fsdata(
return error;
}
+int
+xfs_log_dirty_inode(
+ struct xfs_inode *ip,
+ struct xfs_perag *pag,
+ int flags)
+{
+ struct xfs_mount *mp = ip->i_mount;
+ struct xfs_trans *tp;
+ int error;
+
+ if (!ip->i_update_core)
+ return 0;
+
+ tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
+ error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0);
+ if (error) {
+ xfs_trans_cancel(tp, 0);
+ return error;
+ }
+
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+ xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
+ xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+ return xfs_trans_commit(tp, 0);
+}
+
/*
* When remounting a filesystem read-only or freezing the filesystem, we have
* two phases to execute. This first phase is syncing the data before we
@@ -359,6 +385,16 @@ xfs_quiesce_data(
{
int error, error2 = 0;
+ /*
+ * Log all pending size and timestamp updates. The vfs writeback
+ * code is supposed to do this, but due to its overagressive
+ * livelock detection it will skip inodes where appending writes
+ * were written out in the first non-blocking sync phase if their
+ * completion took long enough that it happened after taking the
+ * timestamp for the cut-off in the blocking phase.
+ */
+ xfs_inode_ag_iterator(mp, xfs_log_dirty_inode, 0);
+
xfs_qm_sync(mp, SYNC_TRYLOCK);
xfs_qm_sync(mp, SYNC_WAIT);