summaryrefslogtreecommitdiff
path: root/fs/direct-io.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-01-08 16:24:38 +1100
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-01-08 16:24:38 +1100
commit24f030175d30f019be41766cdf88c2ff03de19ff (patch)
tree354232a84e82d5a721ed7b1a9af580ff2a59be8f /fs/direct-io.c
parent4aa12f7b927c3cac0e0cf3503642597527d0ece0 (diff)
parent9e42d0cf5020aaf217433cad1a224745241d212a (diff)
Merge commit 'origin/master' into next
Diffstat (limited to 'fs/direct-io.c')
-rw-r--r--fs/direct-io.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/fs/direct-io.c b/fs/direct-io.c
index af0558dbe8b7..b6d43908ff7a 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -1209,6 +1209,19 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
retval = direct_io_worker(rw, iocb, inode, iov, offset,
nr_segs, blkbits, get_block, end_io, dio);
+ /*
+ * In case of error extending write may have instantiated a few
+ * blocks outside i_size. Trim these off again for DIO_LOCKING.
+ * NOTE: DIO_NO_LOCK/DIO_OWN_LOCK callers have to handle this by
+ * it's own meaner.
+ */
+ if (unlikely(retval < 0 && (rw & WRITE))) {
+ loff_t isize = i_size_read(inode);
+
+ if (end > isize && dio_lock_type == DIO_LOCKING)
+ vmtruncate(inode, isize);
+ }
+
if (rw == READ && dio_lock_type == DIO_LOCKING)
release_i_mutex = 0;