]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/hfs/inode.c
sort out blockdev_direct_IO variants
[karo-tx-linux.git] / fs / hfs / inode.c
index 14f5cb1b9fdcfcd10116d065535831af20a3603a..07b2464b5716aaa3d9868be419938dd646cec3c3 100644 (file)
@@ -112,9 +112,24 @@ static ssize_t hfs_direct_IO(int rw, struct kiocb *iocb,
 {
        struct file *file = iocb->ki_filp;
        struct inode *inode = file->f_path.dentry->d_inode->i_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, hfs_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;
 }
 
 static int hfs_writepages(struct address_space *mapping,