Merge branches 'acpi-resources', 'acpi-battery', 'acpi-doc' and 'acpi-pnp'
[linux-2.6-block.git] / fs / ext4 / extents.c
index bed43081720f718fc30dca204be8509ddcf5eac5..d74e08029643d3e5eeb1f8a14d9a78c290549863 100644 (file)
@@ -1717,12 +1717,6 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1,
 {
        unsigned short ext1_ee_len, ext2_ee_len;
 
-       /*
-        * Make sure that both extents are initialized. We don't merge
-        * unwritten extents so that we can be sure that end_io code has
-        * the extent that was written properly split out and conversion to
-        * initialized is trivial.
-        */
        if (ext4_ext_is_unwritten(ex1) != ext4_ext_is_unwritten(ex2))
                return 0;
 
@@ -3128,6 +3122,9 @@ static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex)
        ee_len    = ext4_ext_get_actual_len(ex);
        ee_pblock = ext4_ext_pblock(ex);
 
+       if (ext4_encrypted_inode(inode))
+               return ext4_encrypted_zeroout(inode, ex);
+
        ret = sb_issue_zeroout(inode->i_sb, ee_pblock, ee_len, GFP_NOFS);
        if (ret > 0)
                ret = 0;
@@ -4535,19 +4532,7 @@ got_allocated_blocks:
                 */
                reserved_clusters = get_reserved_cluster_alloc(inode,
                                                map->m_lblk, allocated);
-               if (map_from_cluster) {
-                       if (reserved_clusters) {
-                               /*
-                                * We have clusters reserved for this range.
-                                * But since we are not doing actual allocation
-                                * and are simply using blocks from previously
-                                * allocated cluster, we should release the
-                                * reservation and not claim quota.
-                                */
-                               ext4_da_update_reserve_space(inode,
-                                               reserved_clusters, 0);
-                       }
-               } else {
+               if (!map_from_cluster) {
                        BUG_ON(allocated_clusters < reserved_clusters);
                        if (reserved_clusters < allocated_clusters) {
                                struct ext4_inode_info *ei = EXT4_I(inode);
@@ -4803,12 +4788,6 @@ static long ext4_zero_range(struct file *file, loff_t offset,
        else
                max_blocks -= lblk;
 
-       flags = EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT |
-               EXT4_GET_BLOCKS_CONVERT_UNWRITTEN |
-               EXT4_EX_NOCACHE;
-       if (mode & FALLOC_FL_KEEP_SIZE)
-               flags |= EXT4_GET_BLOCKS_KEEP_SIZE;
-
        mutex_lock(&inode->i_mutex);
 
        /*
@@ -4825,15 +4804,28 @@ static long ext4_zero_range(struct file *file, loff_t offset,
                ret = inode_newsize_ok(inode, new_size);
                if (ret)
                        goto out_mutex;
-               /*
-                * If we have a partial block after EOF we have to allocate
-                * the entire block.
-                */
-               if (partial_end)
-                       max_blocks += 1;
        }
 
+       flags = EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT;
+       if (mode & FALLOC_FL_KEEP_SIZE)
+               flags |= EXT4_GET_BLOCKS_KEEP_SIZE;
+
+       /* Preallocate the range including the unaligned edges */
+       if (partial_begin || partial_end) {
+               ret = ext4_alloc_file_blocks(file,
+                               round_down(offset, 1 << blkbits) >> blkbits,
+                               (round_up((offset + len), 1 << blkbits) -
+                                round_down(offset, 1 << blkbits)) >> blkbits,
+                               new_size, flags, mode);
+               if (ret)
+                       goto out_mutex;
+
+       }
+
+       /* Zero range excluding the unaligned edges */
        if (max_blocks > 0) {
+               flags |= (EXT4_GET_BLOCKS_CONVERT_UNWRITTEN |
+                         EXT4_EX_NOCACHE);
 
                /* Now release the pages and zero block aligned part of pages*/
                truncate_pagecache_range(inode, start, end - 1);
@@ -4847,19 +4839,6 @@ static long ext4_zero_range(struct file *file, loff_t offset,
                                             flags, mode);
                if (ret)
                        goto out_dio;
-               /*
-                * Remove entire range from the extent status tree.
-                *
-                * ext4_es_remove_extent(inode, lblk, max_blocks) is
-                * NOT sufficient.  I'm not sure why this is the case,
-                * but let's be conservative and remove the extent
-                * status tree for the entire inode.  There should be
-                * no outstanding delalloc extents thanks to the
-                * filemap_write_and_wait_range() call above.
-                */
-               ret = ext4_es_remove_extent(inode, 0, EXT_MAX_BLOCKS);
-               if (ret)
-                       goto out_dio;
        }
        if (!partial_begin && !partial_end)
                goto out_dio;
@@ -4922,6 +4901,20 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
        ext4_lblk_t lblk;
        unsigned int blkbits = inode->i_blkbits;
 
+       /*
+        * Encrypted inodes can't handle collapse range or insert
+        * range since we would need to re-encrypt blocks with a
+        * different IV or XTS tweak (which are based on the logical
+        * block number).
+        *
+        * XXX It's not clear why zero range isn't working, but we'll
+        * leave it disabled for encrypted inodes for now.  This is a
+        * bug we should fix....
+        */
+       if (ext4_encrypted_inode(inode) &&
+           (mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_ZERO_RANGE)))
+               return -EOPNOTSUPP;
+
        /* Return error if mode is not supported */
        if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE |
                     FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_ZERO_RANGE))
@@ -4934,13 +4927,6 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
        if (ret)
                return ret;
 
-       /*
-        * currently supporting (pre)allocate mode for extent-based
-        * files _only_
-        */
-       if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
-               return -EOPNOTSUPP;
-
        if (mode & FALLOC_FL_COLLAPSE_RANGE)
                return ext4_collapse_range(inode, offset, len);
 
@@ -4962,6 +4948,14 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
 
        mutex_lock(&inode->i_mutex);
 
+       /*
+        * We only support preallocation for extent-based files only
+        */
+       if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
+               ret = -EOPNOTSUPP;
+               goto out;
+       }
+
        if (!(mode & FALLOC_FL_KEEP_SIZE) &&
             offset + len > i_size_read(inode)) {
                new_size = offset + len;