Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso...
[linux-2.6-block.git] / fs / ext4 / extents.c
index 79d986dbf5af551533dd95d5ec61e4f53ca586fc..0f89f5190cd7241aa1b6da7d878816d6787a52db 100644 (file)
@@ -2956,14 +2956,17 @@ again:
                        if (err < 0)
                                goto out;
 
-               } else if (sbi->s_cluster_ratio > 1 && end >= ex_end) {
+               } else if (sbi->s_cluster_ratio > 1 && end >= ex_end &&
+                          partial.state == initial) {
                        /*
-                        * If there's an extent to the right its first cluster
-                        * contains the immediate right boundary of the
-                        * truncated/punched region.  Set partial_cluster to
-                        * its negative value so it won't be freed if shared
-                        * with the current extent.  The end < ee_block case
-                        * is handled in ext4_ext_rm_leaf().
+                        * If we're punching, there's an extent to the right.
+                        * If the partial cluster hasn't been set, set it to
+                        * that extent's first cluster and its state to nofree
+                        * so it won't be freed should it contain blocks to be
+                        * removed. If it's already set (tofree/nofree), we're
+                        * retrying and keep the original partial cluster info
+                        * so a cluster marked tofree as a result of earlier
+                        * extent removal is not lost.
                         */
                        lblk = ex_end + 1;
                        err = ext4_ext_search_right(inode, path, &lblk, &pblk,
@@ -4048,18 +4051,8 @@ out:
        } else
                allocated = ret;
        map->m_flags |= EXT4_MAP_NEW;
-       /*
-        * if we allocated more blocks than requested
-        * we need to make sure we unmap the extra block
-        * allocated. The actual needed block will get
-        * unmapped later when we find the buffer_head marked
-        * new.
-        */
-       if (allocated > map->m_len) {
-               clean_bdev_aliases(inode->i_sb->s_bdev, newblock + map->m_len,
-                                  allocated - map->m_len);
+       if (allocated > map->m_len)
                allocated = map->m_len;
-       }
        map->m_len = allocated;
 
 map_out: