]> err.no Git - linux-2.6/blobdiff - fs/ext4/extents.c
Merge branch 'for-linus' of git://neil.brown.name/md
[linux-2.6] / fs / ext4 / extents.c
index 42c4c0c892ed9b442617207b00acbdc7be99249f..612c3d2c38240ff59a643bcbf405c2229443a848 100644 (file)
@@ -99,7 +99,7 @@ static int ext4_ext_journal_restart(handle_t *handle, int needed)
        if (handle->h_buffer_credits > needed)
                return 0;
        err = ext4_journal_extend(handle, needed);
-       if (err)
+       if (err <= 0)
                return err;
        return ext4_journal_restart(handle, needed);
 }
@@ -1441,7 +1441,7 @@ unsigned int ext4_ext_check_overlap(struct inode *inode,
 
        /*
         * get the next allocated block if the extent in the path
-        * is before the requested block(s) 
+        * is before the requested block(s)
         */
        if (b2 < b1) {
                b2 = ext4_ext_next_allocated_block(path);
@@ -1910,9 +1910,13 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
                        BUG_ON(b != ex_ee_block + ex_ee_len - 1);
                }
 
-               /* at present, extent can't cross block group: */
-               /* leaf + bitmap + group desc + sb + inode */
-               credits = 5;
+               /*
+                * 3 for leaf, sb, and inode plus 2 (bmap and group
+                * descriptor) for each block group; assume two block
+                * groups plus ex_ee_len/blocks_per_block_group for
+                * the worst case
+                */
+               credits = 7 + 2*(ex_ee_len/EXT4_BLOCKS_PER_GROUP(inode->i_sb));
                if (ex == EXT_FIRST_EXTENT(eh)) {
                        correct_index = 1;
                        credits += (ext_depth(inode)) + 1;
@@ -2323,7 +2327,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
                unsigned int newdepth;
                /* If extent has less than EXT4_EXT_ZERO_LEN zerout directly */
                if (allocated <= EXT4_EXT_ZERO_LEN) {
-                       /* Mark first half uninitialized.
+                       /*
+                        * iblock == ee_block is handled by the zerouout
+                        * at the beginning.
+                        * Mark first half uninitialized.
                         * Mark second half initialized and zero out the
                         * initialized extent
                         */
@@ -2346,7 +2353,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
                                ex->ee_len   = orig_ex.ee_len;
                                ext4_ext_store_pblock(ex, ext_pblock(&orig_ex));
                                ext4_ext_dirty(handle, inode, path + depth);
-                               /* zeroed the full extent */
+                               /* blocks available from iblock */
                                return allocated;
 
                        } else if (err)
@@ -2374,6 +2381,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
                                        err = PTR_ERR(path);
                                        return err;
                                }
+                               /* get the second half extent details */
                                ex = path[depth].p_ext;
                                err = ext4_ext_get_access(handle, inode,
                                                                path + depth);
@@ -2403,6 +2411,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
                        ext4_ext_store_pblock(ex, ext_pblock(&orig_ex));
                        ext4_ext_dirty(handle, inode, path + depth);
                        /* zeroed the full extent */
+                       /* blocks available from iblock */
                        return allocated;
 
                } else if (err)
@@ -2418,23 +2427,22 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
                 */
                orig_ex.ee_len = cpu_to_le16(ee_len -
                                                ext4_ext_get_actual_len(ex3));
-               if (newdepth != depth) {
-                       depth = newdepth;
-                       ext4_ext_drop_refs(path);
-                       path = ext4_ext_find_extent(inode, iblock, path);
-                       if (IS_ERR(path)) {
-                               err = PTR_ERR(path);
-                               goto out;
-                       }
-                       eh = path[depth].p_hdr;
-                       ex = path[depth].p_ext;
-                       if (ex2 != &newex)
-                               ex2 = ex;
-
-                       err = ext4_ext_get_access(handle, inode, path + depth);
-                       if (err)
-                               goto out;
+               depth = newdepth;
+               ext4_ext_drop_refs(path);
+               path = ext4_ext_find_extent(inode, iblock, path);
+               if (IS_ERR(path)) {
+                       err = PTR_ERR(path);
+                       goto out;
                }
+               eh = path[depth].p_hdr;
+               ex = path[depth].p_ext;
+               if (ex2 != &newex)
+                       ex2 = ex;
+
+               err = ext4_ext_get_access(handle, inode, path + depth);
+               if (err)
+                       goto out;
+
                allocated = max_blocks;
 
                /* If extent has less than EXT4_EXT_ZERO_LEN and we are trying
@@ -2452,6 +2460,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
                        ext4_ext_store_pblock(ex, ext_pblock(&orig_ex));
                        ext4_ext_dirty(handle, inode, path + depth);
                        /* zero out the first half */
+                       /* blocks available from iblock */
                        return allocated;
                }
        }