aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_vnodeops.c
diff options
context:
space:
mode:
authorDavid Chinner <dgc@sgi.com>2008-03-05 21:43:42 -0500
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-04-17 21:37:32 -0400
commita3f74ffb6d1448d9a8f482e593b80ec15f1695d4 (patch)
treee7a9ea7ba4032340e771605000002da4349719cb /fs/xfs/xfs_vnodeops.c
parent4ae29b4321b99b711bcfde5527c4fbf249eac60f (diff)
[XFS] Don't block pdflush when writing back inodes
When pdflush is writing back inodes, it can get stuck on inode cluster buffers that are currently under I/O. This occurs when we write data to multiple inodes in the same inode cluster at the same time. Effectively, delayed allocation marks the inode dirty during the data writeback. Hence if the inode cluster was flushed during the writeback of the first inode, the writeback of the second inode will block waiting for the inode cluster write to complete before writing it again for the newly dirtied inode. Basically, we want to avoid this from happening so we don't block pdflush and slow down all of writeback. Hence we introduce a non-blocking async inode flush flag that pdflush uses. If this flag is set, we use non-blocking operations (e.g. try locks) whereever we can to avoid blocking or extra I/O being issued. SGI-PV: 970925 SGI-Modid: xfs-linux-melb:xfs-kern:30501a Signed-off-by: David Chinner <dgc@sgi.com> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
-rw-r--r--fs/xfs/xfs_vnodeops.c55
1 files changed, 12 insertions, 43 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 40b95e3a88ba..14140f6225ba 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -3468,29 +3468,6 @@ xfs_inode_flush(
3468 ((iip == NULL) || !(iip->ili_format.ilf_fields & XFS_ILOG_ALL))) 3468 ((iip == NULL) || !(iip->ili_format.ilf_fields & XFS_ILOG_ALL)))
3469 return 0; 3469 return 0;
3470 3470
3471 if (flags & FLUSH_LOG) {
3472 if (iip && iip->ili_last_lsn) {
3473 xlog_t *log = mp->m_log;
3474 xfs_lsn_t sync_lsn;
3475 int log_flags = XFS_LOG_FORCE;
3476
3477 spin_lock(&log->l_grant_lock);
3478 sync_lsn = log->l_last_sync_lsn;
3479 spin_unlock(&log->l_grant_lock);
3480
3481 if ((XFS_LSN_CMP(iip->ili_last_lsn, sync_lsn) > 0)) {
3482 if (flags & FLUSH_SYNC)
3483 log_flags |= XFS_LOG_SYNC;
3484 error = xfs_log_force(mp, iip->ili_last_lsn, log_flags);
3485 if (error)
3486 return error;
3487 }
3488
3489 if (ip->i_update_core == 0)
3490 return 0;
3491 }
3492 }
3493
3494 /* 3471 /*
3495 * We make this non-blocking if the inode is contended, 3472 * We make this non-blocking if the inode is contended,
3496 * return EAGAIN to indicate to the caller that they 3473 * return EAGAIN to indicate to the caller that they
@@ -3498,30 +3475,22 @@ xfs_inode_flush(
3498 * blocking on inodes inside another operation right 3475 * blocking on inodes inside another operation right
3499 * now, they get caught later by xfs_sync. 3476 * now, they get caught later by xfs_sync.
3500 */ 3477 */
3501 if (flags & FLUSH_INODE) { 3478 if (flags & FLUSH_SYNC) {
3502 int flush_flags; 3479 xfs_ilock(ip, XFS_ILOCK_SHARED);
3503 3480 xfs_iflock(ip);
3504 if (flags & FLUSH_SYNC) { 3481 } else if (xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) {
3505 xfs_ilock(ip, XFS_ILOCK_SHARED); 3482 if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) {
3506 xfs_iflock(ip); 3483 xfs_iunlock(ip, XFS_ILOCK_SHARED);
3507 } else if (xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) {
3508 if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) {
3509 xfs_iunlock(ip, XFS_ILOCK_SHARED);
3510 return EAGAIN;
3511 }
3512 } else {
3513 return EAGAIN; 3484 return EAGAIN;
3514 } 3485 }
3515 3486 } else {
3516 if (flags & FLUSH_SYNC) 3487 return EAGAIN;
3517 flush_flags = XFS_IFLUSH_SYNC;
3518 else
3519 flush_flags = XFS_IFLUSH_ASYNC;
3520
3521 error = xfs_iflush(ip, flush_flags);
3522 xfs_iunlock(ip, XFS_ILOCK_SHARED);
3523 } 3488 }
3524 3489
3490 error = xfs_iflush(ip, (flags & FLUSH_SYNC) ? XFS_IFLUSH_SYNC
3491 : XFS_IFLUSH_ASYNC_NOBLOCK);
3492 xfs_iunlock(ip, XFS_ILOCK_SHARED);
3493
3525 return error; 3494 return error;
3526} 3495}
3527 3496