]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/jfs/inode.c
sort out blockdev_direct_IO variants
[karo-tx-linux.git] / fs / jfs / inode.c
index ed9ba6fe04f55839f94b21bc20f0c681aebae364..79e6cda28181c9945f6ea8d11d02cee2a0648a71 100644 (file)
@@ -317,9 +317,24 @@ static ssize_t jfs_direct_IO(int rw, struct kiocb *iocb,
 {
        struct file *file = iocb->ki_filp;
        struct inode *inode = file->f_mapping->host;
+       ssize_t ret;
 
-       return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
+       ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
                                offset, nr_segs, jfs_get_block, NULL);
+
+       /*
+        * In case of error extending write may have instantiated a few
+        * blocks outside i_size. Trim these off again.
+        */
+       if (unlikely((rw & WRITE) && ret < 0)) {
+               loff_t isize = i_size_read(inode);
+               loff_t end = offset + iov_length(iov, nr_segs);
+
+               if (end > isize)
+                       vmtruncate(inode, isize);
+       }
+
+       return ret;
 }
 
 const struct address_space_operations jfs_aops = {