fix ext3/4 allocation problems
PATCH 1/1 fix ext3/4 allocation problems
Hello,
Seems theres a few places where we make allocations with GFP_KERNEL while in a transaction, which can be dangerous under memory pressure as we can re-enter the fs stuff trying to free up memory. This patch just goes through and changes the GFP_KERNEL allocations that occur under a transaction to GFP_NOFS to keep this problem from happening. Thank you,
Signed-off-by Josef Bacik <[email protected]>
fs/ext3/acl.c +4 -4
@@ -37,7 +37,7 @@ ext3_acl_from_disk(const void *value, sireturn ERR_PTR (-EINVAL );if (count ==0 )return NULL ; - acl =posix_acl_alloc (count,GFP_KERNEL ); + acl =posix_acl_alloc (count,GFP_NOFS );if (!acl)return ERR_PTR (-ENOMEM );for (n=0 ; n < count; n++) {
@@ -91,7 +91,7 @@ ext3_acl_to_disk(const struct posix_acl *size =ext3_acl_size (acl->a_count); ext_acl =kmalloc (sizeof (ext3_acl_header) + acl->a_count * -sizeof (ext3_acl_entry),GFP_KERNEL ); +sizeof (ext3_acl_entry),GFP_NOFS );if (!ext_acl)return ERR_PTR (-ENOMEM ); ext_acl->a_version =cpu_to_le32 (EXT3_ACL_VERSION );
@@ -187,7 +187,7 @@ ext3_get_acl(struct inode *inode, int ty } retval =ext3_xattr_get (inode, name_index,"" ,NULL ,0 );if (retval >0 ) { - value =kmalloc (retval,GFP_KERNEL ); + value =kmalloc (retval,GFP_NOFS );if (!value)return ERR_PTR (-ENOMEM ); retval =ext3_xattr_get (inode, name_index,"" , value, retval);
@@ -335,7 +335,7 @@ ext3_init_acl(handle_t *handle, struct iif (error) goto cleanup; } - clone =posix_acl_clone (acl,GFP_KERNEL ); + clone =posix_acl_clone (acl,GFP_NOFS ); error = -ENOMEM ;if (!clone) goto cleanup;
fs/ext3/resize.c +2 -2
@@ -485,7 +485,7 @@ static int add_new_gdb(handle_t *handle, goto exit_dindj; n_group_desc =kmalloc ((gdb_num +1 ) *sizeof (struct buffer_head *), -GFP_KERNEL ); +GFP_NOFS );if (!n_group_desc) { err = -ENOMEM ; ext3_warning (sb, __FUNCTION__,
@@ -568,7 +568,7 @@ static int reserve_backup_gdb(handle_t *int res, i;int err; - primary =kmalloc (reserved_gdb *sizeof (*primary),GFP_KERNEL ); + primary =kmalloc (reserved_gdb *sizeof (*primary),GFP_NOFS );if (!primary)return -ENOMEM ;
fs/ext3/xattr.c +2 -2
@@ -728,7 +728,7 @@ ext3_xattr_block_set(handle_t *handle, s ce =NULL ; }ea_bdebug (bs->bh,"cloning" ); - s->base =kmalloc (bs->bh->b_size,GFP_KERNEL ); + s->base =kmalloc (bs->bh->b_size,GFP_NOFS ); error = -ENOMEM ;if (s->base ==NULL ) goto cleanup;
@@ -740,7 +740,7 @@ ext3_xattr_block_set(handle_t *handle, s } }else {/* Allocate a buffer where we construct the new block. */ - s->base =kzalloc (sb->s_blocksize,GFP_KERNEL ); + s->base =kzalloc (sb->s_blocksize,GFP_NOFS );/* assert(header == s->base) */ error = -ENOMEM ;if (s->base ==NULL )
fs/ext4/acl.c +4 -4
@@ -37,7 +37,7 @@ ext4_acl_from_disk(const void *value, sireturn ERR_PTR (-EINVAL );if (count ==0 )return NULL ; - acl =posix_acl_alloc (count,GFP_KERNEL ); + acl =posix_acl_alloc (count,GFP_NOFS );if (!acl)return ERR_PTR (-ENOMEM );for (n=0 ; n < count; n++) {
@@ -91,7 +91,7 @@ ext4_acl_to_disk(const struct posix_acl *size =ext4_acl_size (acl->a_count); ext_acl =kmalloc (sizeof (ext4_acl_header) + acl->a_count * -sizeof (ext4_acl_entry),GFP_KERNEL ); +sizeof (ext4_acl_entry),GFP_NOFS );if (!ext_acl)return ERR_PTR (-ENOMEM ); ext_acl->a_version =cpu_to_le32 (EXT4_ACL_VERSION );
@@ -187,7 +187,7 @@ ext4_get_acl(struct inode *inode, int ty } retval =ext4_xattr_get (inode, name_index,"" ,NULL ,0 );if (retval >0 ) { - value =kmalloc (retval,GFP_KERNEL ); + value =kmalloc (retval,GFP_NOFS );if (!value)return ERR_PTR (-ENOMEM ); retval =ext4_xattr_get (inode, name_index,"" , value, retval);
@@ -335,7 +335,7 @@ ext4_init_acl(handle_t *handle, struct iif (error) goto cleanup; } - clone =posix_acl_clone (acl,GFP_KERNEL ); + clone =posix_acl_clone (acl,GFP_NOFS ); error = -ENOMEM ;if (!clone) goto cleanup;
fs/ext4/extents.c +1 -1
@@ -2009,7 +2009,7 @@ int ext4_ext_remove_space(struct inode ** We start scanning from right side, freeing all the blocks * after i_size and walking into the tree depth-wise. */ - path =kzalloc (sizeof (struct ext4_ext_path ) * (depth +1 ),GFP_KERNEL ); + path =kzalloc (sizeof (struct ext4_ext_path ) * (depth +1 ),GFP_NOFS );if (path ==NULL ) {ext4_journal_stop (handle);return -ENOMEM ;
fs/ext4/resize.c +2 -2
@@ -469,7 +469,7 @@ static int add_new_gdb(handle_t *handle, goto exit_dindj; n_group_desc =kmalloc ((gdb_num +1 ) *sizeof (struct buffer_head *), -GFP_KERNEL ); +GFP_NOFS );if (!n_group_desc) { err = -ENOMEM ; ext4_warning (sb, __func__,
@@ -552,7 +552,7 @@ static int reserve_backup_gdb(handle_t *int res, i;int err; - primary =kmalloc (reserved_gdb *sizeof (*primary),GFP_KERNEL ); + primary =kmalloc (reserved_gdb *sizeof (*primary),GFP_NOFS );if (!primary)return -ENOMEM ;
fs/ext4/xattr.c +2 -2
@@ -739,7 +739,7 @@ ext4_xattr_block_set(handle_t *handle, s ce =NULL ; }ea_bdebug (bs->bh,"cloning" ); - s->base =kmalloc (bs->bh->b_size,GFP_KERNEL ); + s->base =kmalloc (bs->bh->b_size,GFP_NOFS ); error = -ENOMEM ;if (s->base ==NULL ) goto cleanup;
@@ -751,7 +751,7 @@ ext4_xattr_block_set(handle_t *handle, s } }else {/* Allocate a buffer where we construct the new block. */ - s->base =kzalloc (sb->s_blocksize,GFP_KERNEL ); + s->base =kzalloc (sb->s_blocksize,GFP_NOFS );/* assert(header == s->base) */ error = -ENOMEM ;if (s->base ==NULL )