ext4: don't allow ext4_free_blocks() to fail due to ENOMEM
[pandora-kernel.git] / fs / ext4 / xattr.c
index 93a00d8..d5498b2 100644 (file)
@@ -487,18 +487,19 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
                ext4_free_blocks(handle, inode, bh, 0, 1,
                                 EXT4_FREE_BLOCKS_METADATA |
                                 EXT4_FREE_BLOCKS_FORGET);
+               unlock_buffer(bh);
        } else {
                le32_add_cpu(&BHDR(bh)->h_refcount, -1);
+               if (ce)
+                       mb_cache_entry_release(ce);
+               unlock_buffer(bh);
                error = ext4_handle_dirty_metadata(handle, inode, bh);
                if (IS_SYNC(inode))
                        ext4_handle_sync(handle);
-               dquot_free_block(inode, 1);
+               dquot_free_block(inode, EXT4_C2B(EXT4_SB(inode->i_sb), 1));
                ea_bdebug(bh, "refcount now=%d; releasing",
                          le32_to_cpu(BHDR(bh)->h_refcount));
-               if (ce)
-                       mb_cache_entry_release(ce);
        }
-       unlock_buffer(bh);
 out:
        ext4_std_error(inode->i_sb, error);
        return;
@@ -784,7 +785,8 @@ inserted:
                        else {
                                /* The old block is released after updating
                                   the inode. */
-                               error = dquot_alloc_block(inode, 1);
+                               error = dquot_alloc_block(inode,
+                                               EXT4_C2B(EXT4_SB(sb), 1));
                                if (error)
                                        goto cleanup;
                                error = ext4_journal_get_write_access(handle,
@@ -838,16 +840,17 @@ inserted:
 
                        new_bh = sb_getblk(sb, block);
                        if (!new_bh) {
+                               error = -ENOMEM;
 getblk_failed:
                                ext4_free_blocks(handle, inode, NULL, block, 1,
                                                 EXT4_FREE_BLOCKS_METADATA);
-                               error = -EIO;
                                goto cleanup;
                        }
                        lock_buffer(new_bh);
                        error = ext4_journal_get_create_access(handle, new_bh);
                        if (error) {
                                unlock_buffer(new_bh);
+                               error = -EIO;
                                goto getblk_failed;
                        }
                        memcpy(new_bh->b_data, s->base, new_bh->b_size);
@@ -879,7 +882,7 @@ cleanup:
        return error;
 
 cleanup_dquot:
-       dquot_free_block(inode, 1);
+       dquot_free_block(inode, EXT4_C2B(EXT4_SB(sb), 1));
        goto cleanup;
 
 bad_block: