aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2009-06-08 09:35:48 -0400
committerChristoph Hellwig <hch@brick.lst.de>2009-06-08 09:35:48 -0400
commit075fe1028699f6a280545dfc2cfc5ac82d555c8c (patch)
treeaf17172ddc4d97d73b6a9a39f6dcf0ca2659fcdc
parentfe588ed32867b42e0d906db558ca92fd9f8b128e (diff)
xfs: split xfs_sync_inodes
xfs_sync_inodes is used to write back either file data or inode metadata. In general we always do these separately, except for one fishy case in xfs_fs_put_super that does both. So separate xfs_sync_inodes into separate xfs_sync_data and xfs_sync_attr functions. In xfs_fs_put_super we first call the data sync and then the attr sync as that was the previous order. The moved log force in that path doesn't make a difference because we will force the log again as part of the real unmount process. The filesystem readonly checks are not performed by the new function but instead moved into the callers, given that most callers alredy have it further up in the stack. Also add debug checks that we do not pass in incorrect flags in the new xfs_sync_data and xfs_sync_attr function and fix the one place that did pass in a wrong flag. Also remove a comment mentioning xfs_sync_inodes that has been incorrect for a while because we always take either the iolock or ilock in the sync path these days. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Eric Sandeen <sandeen@sandeen.net>
-rw-r--r--fs/xfs/linux-2.6/xfs_quotaops.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c13
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c55
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.h5
-rw-r--r--fs/xfs/xfs_filestream.c6
5 files changed, 53 insertions, 30 deletions
diff --git a/fs/xfs/linux-2.6/xfs_quotaops.c b/fs/xfs/linux-2.6/xfs_quotaops.c
index 94d9a633d3d9..cb6e2cca214f 100644
--- a/fs/xfs/linux-2.6/xfs_quotaops.c
+++ b/fs/xfs/linux-2.6/xfs_quotaops.c
@@ -50,9 +50,11 @@ xfs_fs_quota_sync(
50{ 50{
51 struct xfs_mount *mp = XFS_M(sb); 51 struct xfs_mount *mp = XFS_M(sb);
52 52
53 if (sb->s_flags & MS_RDONLY)
54 return -EROFS;
53 if (!XFS_IS_QUOTA_RUNNING(mp)) 55 if (!XFS_IS_QUOTA_RUNNING(mp))
54 return -ENOSYS; 56 return -ENOSYS;
55 return -xfs_sync_inodes(mp, SYNC_DELWRI); 57 return -xfs_sync_data(mp, 0);
56} 58}
57 59
58STATIC int 60STATIC int
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 0d9b64b219e0..d4e7ef8f8df9 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -1071,7 +1071,18 @@ xfs_fs_put_super(
1071 int unmount_event_flags = 0; 1071 int unmount_event_flags = 0;
1072 1072
1073 xfs_syncd_stop(mp); 1073 xfs_syncd_stop(mp);
1074 xfs_sync_inodes(mp, SYNC_ATTR|SYNC_DELWRI); 1074
1075 if (!(sb->s_flags & MS_RDONLY)) {
1076 /*
1077 * XXX(hch): this should be SYNC_WAIT.
1078 *
1079 * Or more likely not needed at all because the VFS is already
1080 * calling ->sync_fs after shutting down all filestem
1081 * operations and just before calling ->put_super.
1082 */
1083 xfs_sync_data(mp, 0);
1084 xfs_sync_attr(mp, 0);
1085 }
1075 1086
1076#ifdef HAVE_DMAPI 1087#ifdef HAVE_DMAPI
1077 if (mp->m_flags & XFS_MOUNT_DMAPI) { 1088 if (mp->m_flags & XFS_MOUNT_DMAPI) {
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index a3d2e7713068..c1a9a1135073 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -268,29 +268,42 @@ xfs_sync_inode_attr(
268 return error; 268 return error;
269} 269}
270 270
271/*
272 * Write out pagecache data for the whole filesystem.
273 */
271int 274int
272xfs_sync_inodes( 275xfs_sync_data(
273 xfs_mount_t *mp, 276 struct xfs_mount *mp,
274 int flags) 277 int flags)
275{ 278{
276 int error = 0; 279 int error;
277 int lflags = XFS_LOG_FORCE;
278 280
279 if (mp->m_flags & XFS_MOUNT_RDONLY) 281 ASSERT((flags & ~(SYNC_TRYLOCK|SYNC_WAIT|SYNC_IOWAIT)) == 0);
280 return 0;
281 282
282 if (flags & SYNC_WAIT) 283 error = xfs_inode_ag_iterator(mp, xfs_sync_inode_data, flags,
283 lflags |= XFS_LOG_SYNC; 284 XFS_ICI_NO_TAG);
285 if (error)
286 return XFS_ERROR(error);
284 287
285 if (flags & SYNC_DELWRI) 288 xfs_log_force(mp, 0,
286 error = xfs_inode_ag_iterator(mp, xfs_sync_inode_data, flags, XFS_ICI_NO_TAG); 289 (flags & SYNC_WAIT) ?
290 XFS_LOG_FORCE | XFS_LOG_SYNC :
291 XFS_LOG_FORCE);
292 return 0;
293}
287 294
288 if (flags & SYNC_ATTR) 295/*
289 error = xfs_inode_ag_iterator(mp, xfs_sync_inode_attr, flags, XFS_ICI_NO_TAG); 296 * Write out inode metadata (attributes) for the whole filesystem.
297 */
298int
299xfs_sync_attr(
300 struct xfs_mount *mp,
301 int flags)
302{
303 ASSERT((flags & ~SYNC_WAIT) == 0);
290 304
291 if (!error && (flags & SYNC_DELWRI)) 305 return xfs_inode_ag_iterator(mp, xfs_sync_inode_attr, flags,
292 xfs_log_force(mp, 0, lflags); 306 XFS_ICI_NO_TAG);
293 return XFS_ERROR(error);
294} 307}
295 308
296STATIC int 309STATIC int
@@ -404,12 +417,12 @@ xfs_quiesce_data(
404 int error; 417 int error;
405 418
406 /* push non-blocking */ 419 /* push non-blocking */
407 xfs_sync_inodes(mp, SYNC_DELWRI|SYNC_BDFLUSH); 420 xfs_sync_data(mp, 0);
408 xfs_qm_sync(mp, SYNC_BDFLUSH); 421 xfs_qm_sync(mp, SYNC_BDFLUSH);
409 xfs_filestream_flush(mp); 422 xfs_filestream_flush(mp);
410 423
411 /* push and block */ 424 /* push and block */
412 xfs_sync_inodes(mp, SYNC_DELWRI|SYNC_WAIT|SYNC_IOWAIT); 425 xfs_sync_data(mp, SYNC_WAIT|SYNC_IOWAIT);
413 xfs_qm_sync(mp, SYNC_WAIT); 426 xfs_qm_sync(mp, SYNC_WAIT);
414 427
415 /* write superblock and hoover up shutdown errors */ 428 /* write superblock and hoover up shutdown errors */
@@ -438,7 +451,7 @@ xfs_quiesce_fs(
438 * logged before we can write the unmount record. 451 * logged before we can write the unmount record.
439 */ 452 */
440 do { 453 do {
441 xfs_sync_inodes(mp, SYNC_ATTR|SYNC_WAIT); 454 xfs_sync_attr(mp, SYNC_WAIT);
442 pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1); 455 pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1);
443 if (!pincount) { 456 if (!pincount) {
444 delay(50); 457 delay(50);
@@ -521,8 +534,8 @@ xfs_flush_inodes_work(
521 void *arg) 534 void *arg)
522{ 535{
523 struct inode *inode = arg; 536 struct inode *inode = arg;
524 xfs_sync_inodes(mp, SYNC_DELWRI | SYNC_TRYLOCK); 537 xfs_sync_data(mp, SYNC_TRYLOCK);
525 xfs_sync_inodes(mp, SYNC_DELWRI | SYNC_TRYLOCK | SYNC_IOWAIT); 538 xfs_sync_data(mp, SYNC_TRYLOCK | SYNC_IOWAIT);
526 iput(inode); 539 iput(inode);
527} 540}
528 541
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h
index 9bb1253a4023..26bfb5c42e76 100644
--- a/fs/xfs/linux-2.6/xfs_sync.h
+++ b/fs/xfs/linux-2.6/xfs_sync.h
@@ -29,8 +29,6 @@ typedef struct xfs_sync_work {
29 struct completion *w_completion; 29 struct completion *w_completion;
30} xfs_sync_work_t; 30} xfs_sync_work_t;
31 31
32#define SYNC_ATTR 0x0001 /* sync attributes */
33#define SYNC_DELWRI 0x0002 /* look at delayed writes */
34#define SYNC_WAIT 0x0004 /* wait for i/o to complete */ 32#define SYNC_WAIT 0x0004 /* wait for i/o to complete */
35#define SYNC_BDFLUSH 0x0008 /* BDFLUSH is calling -- don't block */ 33#define SYNC_BDFLUSH 0x0008 /* BDFLUSH is calling -- don't block */
36#define SYNC_IOWAIT 0x0010 /* wait for all I/O to complete */ 34#define SYNC_IOWAIT 0x0010 /* wait for all I/O to complete */
@@ -39,7 +37,8 @@ typedef struct xfs_sync_work {
39int xfs_syncd_init(struct xfs_mount *mp); 37int xfs_syncd_init(struct xfs_mount *mp);
40void xfs_syncd_stop(struct xfs_mount *mp); 38void xfs_syncd_stop(struct xfs_mount *mp);
41 39
42int xfs_sync_inodes(struct xfs_mount *mp, int flags); 40int xfs_sync_attr(struct xfs_mount *mp, int flags);
41int xfs_sync_data(struct xfs_mount *mp, int flags);
43int xfs_sync_fsdata(struct xfs_mount *mp, int flags); 42int xfs_sync_fsdata(struct xfs_mount *mp, int flags);
44 43
45int xfs_quiesce_data(struct xfs_mount *mp); 44int xfs_quiesce_data(struct xfs_mount *mp);
diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c
index 6c87c8f304ef..edf8bdf4141f 100644
--- a/fs/xfs/xfs_filestream.c
+++ b/fs/xfs/xfs_filestream.c
@@ -542,10 +542,8 @@ xfs_filestream_associate(
542 * waiting for the lock because someone else is waiting on the lock we 542 * waiting for the lock because someone else is waiting on the lock we
543 * hold and we cannot drop that as we are in a transaction here. 543 * hold and we cannot drop that as we are in a transaction here.
544 * 544 *
545 * Lucky for us, this inversion is rarely a problem because it's a 545 * Lucky for us, this inversion is not a problem because it's a
546 * directory inode that we are trying to lock here and that means the 546 * directory inode that we are trying to lock here.
547 * only place that matters is xfs_sync_inodes() and SYNC_DELWRI is
548 * used. i.e. freeze, remount-ro, quotasync or unmount.
549 * 547 *
550 * So, if we can't get the iolock without sleeping then just give up 548 * So, if we can't get the iolock without sleeping then just give up
551 */ 549 */