aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_sync.c
diff options
context:
space:
mode:
authorDave Chinner <david@fromorbit.com>2009-04-06 12:45:44 -0400
committerChristoph Hellwig <hch@brick.lst.de>2009-04-06 12:45:44 -0400
commit5825294edd3364cbba6514f70d88debec4f6cec7 (patch)
tree5462388cdb6b36b2f0f1cf75dc6ee60a7c643a23 /fs/xfs/linux-2.6/xfs_sync.c
parenta8d770d987ee20b59fba6c37d7f0f2a351913c4b (diff)
xfs: make inode flush at ENOSPC synchronous
When we are writing to a single file and hit ENOSPC, we trigger a background flush of the inode and try again. Because we hold page locks and the iolock, the flush won't proceed until after we release these locks. This occurs once we've given up and ENOSPC has been reported. Hence if this one is the only dirty inode in the system, we'll get an ENOSPC prematurely. To fix this, remove the async flush from the allocation routines and move it to the top of the write path where we can do a synchronous flush and retry the write again. Only retry once as a second ENOSPC indicates that we really are ENOSPC. This avoids a page cache deadlock when trying to do this flush synchronously in the allocation layer that was identified by Mikulas Patocka. Signed-off-by: Dave Chinner <david@fromorbit.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_sync.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c25
1 files changed, 0 insertions, 25 deletions
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index 88caafc8ef1b..73cf8dc19738 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -426,31 +426,6 @@ xfs_syncd_queue_work(
426 * heads, looking about for more room... 426 * heads, looking about for more room...
427 */ 427 */
428STATIC void 428STATIC void
429xfs_flush_inode_work(
430 struct xfs_mount *mp,
431 void *arg)
432{
433 struct inode *inode = arg;
434 filemap_flush(inode->i_mapping);
435 iput(inode);
436}
437
438void
439xfs_flush_inode(
440 xfs_inode_t *ip)
441{
442 struct inode *inode = VFS_I(ip);
443
444 igrab(inode);
445 xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_inode_work);
446 delay(msecs_to_jiffies(500));
447}
448
449/*
450 * This is the "bigger hammer" version of xfs_flush_inode_work...
451 * (IOW, "If at first you don't succeed, use a Bigger Hammer").
452 */
453STATIC void
454xfs_flush_inodes_work( 429xfs_flush_inodes_work(
455 struct xfs_mount *mp, 430 struct xfs_mount *mp,
456 void *arg) 431 void *arg)