Merge branch 'for-linus' of git://git.o-hand.com/linux-rpurdie-leds
[pandora-kernel.git] / fs / ext4 / extents.c
index ffcaa11..377309c 100644 (file)
@@ -107,11 +107,8 @@ static int ext4_ext_truncate_extend_restart(handle_t *handle,
        if (err <= 0)
                return err;
        err = ext4_truncate_restart_trans(handle, inode, needed);
-       /*
-        * We have dropped i_data_sem so someone might have cached again
-        * an extent we are going to truncate.
-        */
-       ext4_ext_invalidate_cache(inode);
+       if (err == 0)
+               err = -EAGAIN;
 
        return err;
 }
@@ -185,10 +182,10 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode,
        if (flex_size >= EXT4_FLEX_SIZE_DIR_ALLOC_SCHEME) {
                /*
                 * If there are at least EXT4_FLEX_SIZE_DIR_ALLOC_SCHEME
-                * block groups per flexgroup, reserve the first block 
-                * group for directories and special files.  Regular 
+                * block groups per flexgroup, reserve the first block
+                * group for directories and special files.  Regular
                 * files will start at the second block group.  This
-                * tends to speed up directory access and improves 
+                * tends to speed up directory access and improves
                 * fsck times.
                 */
                block_group &= ~(flex_size-1);
@@ -2037,7 +2034,7 @@ ext4_ext_in_cache(struct inode *inode, ext4_lblk_t block,
        struct ext4_ext_cache *cex;
        int ret = EXT4_EXT_CACHE_NO;
 
-       /* 
+       /*
         * We borrow i_block_reservation_lock to protect i_cached_extent
         */
        spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
@@ -2359,7 +2356,7 @@ static int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start)
        int depth = ext_depth(inode);
        struct ext4_ext_path *path;
        handle_t *handle;
-       int i = 0, err = 0;
+       int i, err;
 
        ext_debug("truncate since %u\n", start);
 
@@ -2368,23 +2365,26 @@ static int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start)
        if (IS_ERR(handle))
                return PTR_ERR(handle);
 
+again:
        ext4_ext_invalidate_cache(inode);
 
        /*
         * We start scanning from right side, freeing all the blocks
         * after i_size and walking into the tree depth-wise.
         */
+       depth = ext_depth(inode);
        path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1), GFP_NOFS);
        if (path == NULL) {
                ext4_journal_stop(handle);
                return -ENOMEM;
        }
+       path[0].p_depth = depth;
        path[0].p_hdr = ext_inode_hdr(inode);
        if (ext4_ext_check(inode, path[0].p_hdr, depth)) {
                err = -EIO;
                goto out;
        }
-       path[0].p_depth = depth;
+       i = err = 0;
 
        while (i >= 0 && err == 0) {
                if (i == depth) {
@@ -2478,6 +2478,8 @@ static int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start)
 out:
        ext4_ext_drop_refs(path);
        kfree(path);
+       if (err == -EAGAIN)
+               goto again;
        ext4_journal_stop(handle);
 
        return err;