diff options
author | Christoph Hellwig <hch@lst.de> | 2009-02-04 09:36:19 +0100 |
---|---|---|
committer | Christoph Hellwig <hch@brick.lst.de> | 2009-02-04 09:36:19 +0100 |
commit | d4bb6d0698090c485e2e80e8a13852be5a8bfb04 (patch) | |
tree | bc94a63f218d64976e11d67c6b8d6f0f2859d2c4 /fs/xfs/linux-2.6/xfs_super.c | |
parent | e1486dea0bf4bc75a52a983281076f454a894b66 (diff) | |
download | lwn-d4bb6d0698090c485e2e80e8a13852be5a8bfb04.tar.gz lwn-d4bb6d0698090c485e2e80e8a13852be5a8bfb04.zip |
xfs: merge xfs_inode_flush into xfs_fs_write_inode
Splitting the task for a VFS-induced inode flush into two functions doesn't
make any sense, so merge the two functions dealing with it.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Felix Blyakher <felixb@sgi.com>
Reviewed-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_super.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index c71e226da7f5..faf3aa3ca154 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -990,26 +990,57 @@ xfs_fs_write_inode( int sync) { struct xfs_inode *ip = XFS_I(inode); + struct xfs_mount *mp = ip->i_mount; int error = 0; - int flags = 0; xfs_itrace_entry(ip); + + if (XFS_FORCED_SHUTDOWN(mp)) + return XFS_ERROR(EIO); + if (sync) { error = xfs_wait_on_pages(ip, 0, -1); if (error) - goto out_error; - flags |= FLUSH_SYNC; + goto out; + } + + /* + * Bypass inodes which have already been cleaned by + * the inode flush clustering code inside xfs_iflush + */ + if (xfs_inode_clean(ip)) + goto out; + + /* + * We make this non-blocking if the inode is contended, return + * EAGAIN to indicate to the caller that they did not succeed. + * This prevents the flush path from blocking on inodes inside + * another operation right now, they get caught later by xfs_sync. + */ + if (sync) { + xfs_ilock(ip, XFS_ILOCK_SHARED); + xfs_iflock(ip); + + error = xfs_iflush(ip, XFS_IFLUSH_SYNC); + } else { + error = EAGAIN; + if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) + goto out; + if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) + goto out_unlock; + + error = xfs_iflush(ip, XFS_IFLUSH_ASYNC_NOBLOCK); } - error = xfs_inode_flush(ip, flags); -out_error: + out_unlock: + xfs_iunlock(ip, XFS_ILOCK_SHARED); + out: /* * if we failed to write out the inode then mark * it dirty again so we'll try again later. */ if (error) xfs_mark_inode_dirty_sync(ip); - return -error; } |