vfs: fix possible deadlock in ext2, ext3, ext4 when using xattrs
[sfrench/cifs-2.6.git] / fs / ext4 / xattr.c
index b10d68fffb551d7b70b8797bfcd41b6de3bfaed4..e9054c1c7d9366ce36f1d140b125c5db8915cd15 100644 (file)
@@ -480,7 +480,7 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
                ea_bdebug(bh, "refcount now=0; freeing");
                if (ce)
                        mb_cache_entry_free(ce);
-               ext4_free_blocks(handle, inode, bh->b_blocknr, 1);
+               ext4_free_blocks(handle, inode, bh->b_blocknr, 1, 1);
                get_bh(bh);
                ext4_forget(handle, 1, inode, bh, bh->b_blocknr);
        } else {
@@ -750,12 +750,11 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
                }
        } else {
                /* Allocate a buffer where we construct the new block. */
-               s->base = kmalloc(sb->s_blocksize, GFP_KERNEL);
+               s->base = kzalloc(sb->s_blocksize, GFP_KERNEL);
                /* assert(header == s->base) */
                error = -ENOMEM;
                if (s->base == NULL)
                        goto cleanup;
-               memset(s->base, 0, sb->s_blocksize);
                header(s->base)->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC);
                header(s->base)->h_blocks = cpu_to_le32(1);
                header(s->base)->h_refcount = cpu_to_le32(1);
@@ -822,7 +821,7 @@ inserted:
                        new_bh = sb_getblk(sb, block);
                        if (!new_bh) {
 getblk_failed:
-                               ext4_free_blocks(handle, inode, block, 1);
+                               ext4_free_blocks(handle, inode, block, 1, 1);
                                error = -EIO;
                                goto cleanup;
                        }
@@ -1121,7 +1120,7 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
        int total_ino, total_blk;
        void *base, *start, *end;
        int extra_isize = 0, error = 0, tried_min_extra_isize = 0;
-       int s_min_extra_isize = EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize;
+       int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize);
 
        down_write(&EXT4_I(inode)->xattr_sem);
 retry:
@@ -1293,7 +1292,7 @@ retry:
 
                i.name = b_entry_name;
                i.value = buffer;
-               i.value_len = cpu_to_le32(size);
+               i.value_len = size;
                error = ext4_xattr_block_find(inode, &i, bs);
                if (error)
                        goto cleanup;
@@ -1387,7 +1386,7 @@ ext4_xattr_cache_insert(struct buffer_head *bh)
        struct mb_cache_entry *ce;
        int error;
 
-       ce = mb_cache_entry_alloc(ext4_xattr_cache);
+       ce = mb_cache_entry_alloc(ext4_xattr_cache, GFP_NOFS);
        if (!ce) {
                ea_bdebug(bh, "out of memory");
                return;