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>

authored by

Christoph Hellwig and committed by
Christoph Hellwig
075fe102 fe588ed3

+53 -30
+3 -1
fs/xfs/linux-2.6/xfs_quotaops.c
··· 50 50 { 51 51 struct xfs_mount *mp = XFS_M(sb); 52 52 53 + if (sb->s_flags & MS_RDONLY) 54 + return -EROFS; 53 55 if (!XFS_IS_QUOTA_RUNNING(mp)) 54 56 return -ENOSYS; 55 - return -xfs_sync_inodes(mp, SYNC_DELWRI); 57 + return -xfs_sync_data(mp, 0); 56 58 } 57 59 58 60 STATIC int
+12 -1
fs/xfs/linux-2.6/xfs_super.c
··· 1071 1071 int unmount_event_flags = 0; 1072 1072 1073 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 1087 #ifdef HAVE_DMAPI 1077 1088 if (mp->m_flags & XFS_MOUNT_DMAPI) {
+34 -21
fs/xfs/linux-2.6/xfs_sync.c
··· 268 268 return error; 269 269 } 270 270 271 + /* 272 + * Write out pagecache data for the whole filesystem. 273 + */ 271 274 int 272 - xfs_sync_inodes( 273 - xfs_mount_t *mp, 274 - int flags) 275 + xfs_sync_data( 276 + struct xfs_mount *mp, 277 + int flags) 275 278 { 276 - int error = 0; 277 - int lflags = XFS_LOG_FORCE; 279 + int error; 278 280 279 - if (mp->m_flags & XFS_MOUNT_RDONLY) 280 - return 0; 281 + ASSERT((flags & ~(SYNC_TRYLOCK|SYNC_WAIT|SYNC_IOWAIT)) == 0); 281 282 282 - if (flags & SYNC_WAIT) 283 - lflags |= XFS_LOG_SYNC; 283 + error = xfs_inode_ag_iterator(mp, xfs_sync_inode_data, flags, 284 + XFS_ICI_NO_TAG); 285 + if (error) 286 + return XFS_ERROR(error); 284 287 285 - if (flags & SYNC_DELWRI) 286 - error = xfs_inode_ag_iterator(mp, xfs_sync_inode_data, flags, XFS_ICI_NO_TAG); 288 + xfs_log_force(mp, 0, 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) 289 - error = xfs_inode_ag_iterator(mp, xfs_sync_inode_attr, flags, XFS_ICI_NO_TAG); 295 + /* 296 + * Write out inode metadata (attributes) for the whole filesystem. 297 + */ 298 + int 299 + xfs_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)) 292 - xfs_log_force(mp, 0, lflags); 293 - return XFS_ERROR(error); 305 + return xfs_inode_ag_iterator(mp, xfs_sync_inode_attr, flags, 306 + XFS_ICI_NO_TAG); 294 307 } 295 308 296 309 STATIC int ··· 417 404 int error; 418 405 419 406 /* push non-blocking */ 420 - xfs_sync_inodes(mp, SYNC_DELWRI|SYNC_BDFLUSH); 407 + xfs_sync_data(mp, 0); 421 408 xfs_qm_sync(mp, SYNC_BDFLUSH); 422 409 xfs_filestream_flush(mp); 423 410 424 411 /* push and block */ 425 - xfs_sync_inodes(mp, SYNC_DELWRI|SYNC_WAIT|SYNC_IOWAIT); 412 + xfs_sync_data(mp, SYNC_WAIT|SYNC_IOWAIT); 426 413 xfs_qm_sync(mp, SYNC_WAIT); 427 414 428 415 /* write superblock and hoover up shutdown errors */ ··· 451 438 * logged before we can write the unmount record. 452 439 */ 453 440 do { 454 - xfs_sync_inodes(mp, SYNC_ATTR|SYNC_WAIT); 441 + xfs_sync_attr(mp, SYNC_WAIT); 455 442 pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1); 456 443 if (!pincount) { 457 444 delay(50); ··· 534 521 void *arg) 535 522 { 536 523 struct inode *inode = arg; 537 - xfs_sync_inodes(mp, SYNC_DELWRI | SYNC_TRYLOCK); 538 - xfs_sync_inodes(mp, SYNC_DELWRI | SYNC_TRYLOCK | SYNC_IOWAIT); 524 + xfs_sync_data(mp, SYNC_TRYLOCK); 525 + xfs_sync_data(mp, SYNC_TRYLOCK | SYNC_IOWAIT); 539 526 iput(inode); 540 527 } 541 528
+2 -3
fs/xfs/linux-2.6/xfs_sync.h
··· 29 29 struct completion *w_completion; 30 30 } xfs_sync_work_t; 31 31 32 - #define SYNC_ATTR 0x0001 /* sync attributes */ 33 - #define SYNC_DELWRI 0x0002 /* look at delayed writes */ 34 32 #define SYNC_WAIT 0x0004 /* wait for i/o to complete */ 35 33 #define SYNC_BDFLUSH 0x0008 /* BDFLUSH is calling -- don't block */ 36 34 #define SYNC_IOWAIT 0x0010 /* wait for all I/O to complete */ ··· 37 39 int xfs_syncd_init(struct xfs_mount *mp); 38 40 void xfs_syncd_stop(struct xfs_mount *mp); 39 41 40 - int xfs_sync_inodes(struct xfs_mount *mp, int flags); 42 + int xfs_sync_attr(struct xfs_mount *mp, int flags); 43 + int xfs_sync_data(struct xfs_mount *mp, int flags); 41 44 int xfs_sync_fsdata(struct xfs_mount *mp, int flags); 42 45 43 46 int xfs_quiesce_data(struct xfs_mount *mp);
+2 -4
fs/xfs/xfs_filestream.c
··· 542 542 * waiting for the lock because someone else is waiting on the lock we 543 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 546 - * directory inode that we are trying to lock here and that means the 547 - * only place that matters is xfs_sync_inodes() and SYNC_DELWRI is 548 - * used. i.e. freeze, remount-ro, quotasync or unmount. 545 + * Lucky for us, this inversion is not a problem because it's a 546 + * directory inode that we are trying to lock here. 549 547 * 550 548 * So, if we can't get the iolock without sleeping then just give up 551 549 */