aboutsummaryrefslogtreecommitdiff
path: root/fs/xfs/linux-2.6/xfs_lrw.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-04-13 14:35:13 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-13 14:35:13 -0700
commit3c1795cc4bd9d57281bebc314315b8afa217b9c7 (patch)
tree97972fe4970e5074ec3944c7cd5179fb2bfe5b36 /fs/xfs/linux-2.6/xfs_lrw.c
parent80a04d3f2f94fb68b5df05e3ac6697130bc3467a (diff)
parentdc2a5536d633dd2318f82f3d5ad3c9e43cfc21d7 (diff)
Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
* 'for-linus' of git://oss.sgi.com/xfs/xfs: xfs: remove xfs_flush_space xfs: flush delayed allcoation blocks on ENOSPC in create xfs: block callers of xfs_flush_inodes() correctly xfs: make inode flush at ENOSPC synchronous xfs: use xfs_sync_inodes() for device flushing xfs: inform the xfsaild of the push target before sleeping xfs: prevent unwritten extent conversion from blocking I/O completion xfs: fix double free of inode xfs: validate log feature fields correctly
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_lrw.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 7e90daa0d1d..9142192ccbe 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -751,10 +751,26 @@ start:
goto relock;
}
} else {
+ int enospc = 0;
+ ssize_t ret2 = 0;
+
+write_retry:
xfs_rw_enter_trace(XFS_WRITE_ENTER, xip, (void *)iovp, segs,
*offset, ioflags);
- ret = generic_file_buffered_write(iocb, iovp, segs,
+ ret2 = generic_file_buffered_write(iocb, iovp, segs,
pos, offset, count, ret);
+ /*
+ * if we just got an ENOSPC, flush the inode now we
+ * aren't holding any page locks and retry *once*
+ */
+ if (ret2 == -ENOSPC && !enospc) {
+ error = xfs_flush_pages(xip, 0, -1, 0, FI_NONE);
+ if (error)
+ goto out_unlock_internal;
+ enospc = 1;
+ goto write_retry;
+ }
+ ret = ret2;
}
current->backing_dev_info = NULL;