]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/reiserfs/inode.c
sort out blockdev_direct_IO variants
[karo-tx-linux.git] / fs / reiserfs / inode.c
index 0f22fdaf54ac037ecc21dea052d135d340a5d510..4c1fb548ab64d5c8f808a3d6d67b9f8607457d08 100644 (file)
@@ -1138,7 +1138,6 @@ static void init_inode(struct inode *inode, struct treepath *path)
        REISERFS_I(inode)->i_prealloc_count = 0;
        REISERFS_I(inode)->i_trans_id = 0;
        REISERFS_I(inode)->i_jl = NULL;
-       mutex_init(&(REISERFS_I(inode)->i_mmap));
        reiserfs_init_xattr_rwsem(inode);
 
        if (stat_data_v1(ih)) {
@@ -1841,7 +1840,6 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
        REISERFS_I(inode)->i_attrs =
            REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK;
        sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode);
-       mutex_init(&(REISERFS_I(inode)->i_mmap));
        reiserfs_init_xattr_rwsem(inode);
 
        /* key to search for correct place for new stat data */
@@ -3059,10 +3057,25 @@ static ssize_t reiserfs_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,
                                  reiserfs_get_blocks_direct_io, 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;
 }
 
 int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)