aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c25
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c42
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.h3
-rw-r--r--fs/xfs/xfs_vfsops.c1
4 files changed, 50 insertions, 21 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 38d380a7ca23..376f32d92475 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -998,7 +998,6 @@ xfs_fs_put_super(
998 int error; 998 int error;
999 999
1000 xfs_syncd_stop(mp); 1000 xfs_syncd_stop(mp);
1001 xfs_log_force(mp, 0, XFS_LOG_FORCE|XFS_LOG_SYNC);
1002 xfs_sync_inodes(mp, SYNC_ATTR|SYNC_DELWRI); 1001 xfs_sync_inodes(mp, SYNC_ATTR|SYNC_DELWRI);
1003 1002
1004#ifdef HAVE_DMAPI 1003#ifdef HAVE_DMAPI
@@ -1057,7 +1056,7 @@ xfs_fs_write_super(
1057 struct super_block *sb) 1056 struct super_block *sb)
1058{ 1057{
1059 if (!(sb->s_flags & MS_RDONLY)) 1058 if (!(sb->s_flags & MS_RDONLY))
1060 xfs_sync(XFS_M(sb), SYNC_FSDATA); 1059 xfs_sync_fsdata(XFS_M(sb), 0);
1061 sb->s_dirt = 0; 1060 sb->s_dirt = 0;
1062} 1061}
1063 1062
@@ -1068,7 +1067,6 @@ xfs_fs_sync_super(
1068{ 1067{
1069 struct xfs_mount *mp = XFS_M(sb); 1068 struct xfs_mount *mp = XFS_M(sb);
1070 int error; 1069 int error;
1071 int flags;
1072 1070
1073 /* 1071 /*
1074 * Treat a sync operation like a freeze. This is to work 1072 * Treat a sync operation like a freeze. This is to work
@@ -1082,20 +1080,10 @@ xfs_fs_sync_super(
1082 * dirty the Linux inode until after the transaction I/O 1080 * dirty the Linux inode until after the transaction I/O
1083 * completes. 1081 * completes.
1084 */ 1082 */
1085 if (wait || unlikely(sb->s_frozen == SB_FREEZE_WRITE)) { 1083 if (wait || unlikely(sb->s_frozen == SB_FREEZE_WRITE))
1086 /* 1084 error = xfs_quiesce_data(mp);
1087 * First stage of freeze - no more writers will make progress 1085 else
1088 * now we are here, so we flush delwri and delalloc buffers 1086 error = xfs_sync_fsdata(mp, 0);
1089 * here, then wait for all I/O to complete. Data is frozen at
1090 * that point. Metadata is not frozen, transactions can still
1091 * occur here so don't bother flushing the buftarg (i.e
1092 * SYNC_QUIESCE) because it'll just get dirty again.
1093 */
1094 flags = SYNC_DATA_QUIESCE;
1095 } else
1096 flags = SYNC_FSDATA;
1097
1098 error = xfs_sync(mp, flags);
1099 sb->s_dirt = 0; 1087 sb->s_dirt = 0;
1100 1088
1101 if (unlikely(laptop_mode)) { 1089 if (unlikely(laptop_mode)) {
@@ -1233,8 +1221,7 @@ xfs_fs_remount(
1233 1221
1234 /* rw -> ro */ 1222 /* rw -> ro */
1235 if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & MS_RDONLY)) { 1223 if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & MS_RDONLY)) {
1236 xfs_filestream_flush(mp); 1224 xfs_quiesce_data(mp);
1237 xfs_sync(mp, SYNC_DATA_QUIESCE);
1238 xfs_attr_quiesce(mp); 1225 xfs_attr_quiesce(mp);
1239 mp->m_flags |= XFS_MOUNT_RDONLY; 1226 mp->m_flags |= XFS_MOUNT_RDONLY;
1240 } 1227 }
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index 002ccb6f0cbe..838070ce7249 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -217,12 +217,16 @@ xfs_sync_inodes(
217 int error; 217 int error;
218 int last_error; 218 int last_error;
219 int i; 219 int i;
220 int lflags = XFS_LOG_FORCE;
220 221
221 if (mp->m_flags & XFS_MOUNT_RDONLY) 222 if (mp->m_flags & XFS_MOUNT_RDONLY)
222 return 0; 223 return 0;
223 error = 0; 224 error = 0;
224 last_error = 0; 225 last_error = 0;
225 226
227 if (flags & SYNC_WAIT)
228 lflags |= XFS_LOG_SYNC;
229
226 for (i = 0; i < mp->m_sb.sb_agcount; i++) { 230 for (i = 0; i < mp->m_sb.sb_agcount; i++) {
227 if (!mp->m_perag[i].pag_ici_init) 231 if (!mp->m_perag[i].pag_ici_init)
228 continue; 232 continue;
@@ -232,6 +236,9 @@ xfs_sync_inodes(
232 if (error == EFSCORRUPTED) 236 if (error == EFSCORRUPTED)
233 break; 237 break;
234 } 238 }
239 if (flags & SYNC_DELWRI)
240 xfs_log_force(mp, 0, lflags);
241
235 return XFS_ERROR(last_error); 242 return XFS_ERROR(last_error);
236} 243}
237 244
@@ -269,7 +276,7 @@ xfs_commit_dummy_trans(
269 return 0; 276 return 0;
270} 277}
271 278
272STATIC int 279int
273xfs_sync_fsdata( 280xfs_sync_fsdata(
274 struct xfs_mount *mp, 281 struct xfs_mount *mp,
275 int flags) 282 int flags)
@@ -323,6 +330,39 @@ xfs_sync_fsdata(
323} 330}
324 331
325/* 332/*
333 * First stage of freeze - no more writers will make progress now we are here,
334 * so we flush delwri and delalloc buffers here, then wait for all I/O to
335 * complete. Data is frozen at that point. Metadata is not frozen,
336 * transactions can still occur here so don't bother flushing the buftarg (i.e
337 * SYNC_QUIESCE) because it'll just get dirty again.
338 */
339int
340xfs_quiesce_data(
341 struct xfs_mount *mp)
342{
343 int error;
344
345 /* push non-blocking */
346 xfs_sync_inodes(mp, SYNC_DELWRI|SYNC_BDFLUSH);
347 XFS_QM_DQSYNC(mp, SYNC_BDFLUSH);
348 xfs_filestream_flush(mp);
349
350 /* push and block */
351 xfs_sync_inodes(mp, SYNC_DELWRI|SYNC_WAIT|SYNC_IOWAIT);
352 XFS_QM_DQSYNC(mp, SYNC_WAIT);
353
354 /* write superblock and hoover shutdown errors */
355 error = xfs_sync_fsdata(mp, 0);
356
357 /* flush devices */
358 XFS_bflush(mp->m_ddev_targp);
359 if (mp->m_rtdev_targp)
360 XFS_bflush(mp->m_rtdev_targp);
361
362 return error;
363}
364
365/*
326 * xfs_sync flushes any pending I/O to file system vfsp. 366 * xfs_sync flushes any pending I/O to file system vfsp.
327 * 367 *
328 * This routine is called by vfs_sync() to make sure that things make it 368 * This routine is called by vfs_sync() to make sure that things make it
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h
index 5316915c0834..fcd4040c9ad1 100644
--- a/fs/xfs/linux-2.6/xfs_sync.h
+++ b/fs/xfs/linux-2.6/xfs_sync.h
@@ -55,6 +55,9 @@ void xfs_syncd_stop(struct xfs_mount *mp);
55 55
56int xfs_sync(struct xfs_mount *mp, int flags); 56int xfs_sync(struct xfs_mount *mp, int flags);
57int xfs_sync_inodes(struct xfs_mount *mp, int flags); 57int xfs_sync_inodes(struct xfs_mount *mp, int flags);
58int xfs_sync_fsdata(struct xfs_mount *mp, int flags);
59
60int xfs_quiesce_data(struct xfs_mount *mp);
58 61
59void xfs_flush_inode(struct xfs_inode *ip); 62void xfs_flush_inode(struct xfs_inode *ip);
60void xfs_flush_device(struct xfs_inode *ip); 63void xfs_flush_device(struct xfs_inode *ip);
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index c82b9555959b..b55a9bb3a6e3 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -75,7 +75,6 @@ xfs_quiesce_fs(
75 * logged before we can write the unmount record. 75 * logged before we can write the unmount record.
76 */ 76 */
77 do { 77 do {
78 xfs_log_force(mp, 0, XFS_LOG_FORCE|XFS_LOG_SYNC);
79 xfs_sync_inodes(mp, SYNC_ATTR|SYNC_WAIT); 78 xfs_sync_inodes(mp, SYNC_ATTR|SYNC_WAIT);
80 pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1); 79 pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1);
81 if (!pincount) { 80 if (!pincount) {