summaryrefslogtreecommitdiffstats
path: root/fs/direct-io.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-01-10 12:04:41 +0100
committerIngo Molnar <mingo@elte.hu>2009-01-10 12:04:41 +0100
commitb17304245f0db0ac69b795c411407808f3f2796d (patch)
tree63ed3915d9295bd08f640bf25c322064ba787fad /fs/direct-io.c
parent889c92d21db40be0b7d22a59395060237895bb85 (diff)
parent9a100a4464917b5ffff3a8ce1c2758088fd9bb32 (diff)
Merge branch 'linus' into x86/setup-lzma
Conflicts: init/do_mounts_rd.c
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 af0558dbe8b..b6d43908ff7 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;