Merge tag 'ext4_for_linus_stable2' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / fs / ext4 / extents.c
index f1956288307f39f497cc088b77bdc4363b3f0fed..6c399a8b22b3512e2da1993258a2d172843c6e9f 100644 (file)
@@ -5184,6 +5184,7 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
         * and it is decreased till we reach start.
         */
 again:
+       ret = 0;
        if (SHIFT == SHIFT_LEFT)
                iterator = &start;
        else
@@ -5227,14 +5228,21 @@ again:
                                        ext4_ext_get_actual_len(extent);
                } else {
                        extent = EXT_FIRST_EXTENT(path[depth].p_hdr);
-                       if (le32_to_cpu(extent->ee_block) > 0)
+                       if (le32_to_cpu(extent->ee_block) > start)
                                *iterator = le32_to_cpu(extent->ee_block) - 1;
-                       else
-                               /* Beginning is reached, end of the loop */
+                       else if (le32_to_cpu(extent->ee_block) == start)
                                iterator = NULL;
-                       /* Update path extent in case we need to stop */
-                       while (le32_to_cpu(extent->ee_block) < start)
+                       else {
+                               extent = EXT_LAST_EXTENT(path[depth].p_hdr);
+                               while (le32_to_cpu(extent->ee_block) >= start)
+                                       extent--;
+
+                               if (extent == EXT_LAST_EXTENT(path[depth].p_hdr))
+                                       break;
+
                                extent++;
+                               iterator = NULL;
+                       }
                        path[depth].p_ext = extent;
                }
                ret = ext4_ext_shift_path_extents(path, shift, inode,