2011-07-12 21:40:50

by Andreas Dilger

[permalink] [raw]
Subject: [PATCH] ext4: fall back to vmalloc() for large allocations

For very large ext4 filesystems (128TB and larger) kmalloc() of
some per-group structures can fail at mount time due to memory
fragmentation. If kmalloc() fails, fall back to vmalloc() for
the s_group_info and s_group_desc arrays.

Signed-off-by: Yu Jian <[email protected]>
Signed-off-by: Andreas Dilger <[email protected]>
---
fs/ext4/mballoc.c | 49 +++++++++++++++++++++++++++++++++----------------
fs/ext4/super.c | 29 +++++++++++++++++++++++------
2 files changed, 56 insertions(+), 22 deletions(-)

diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 6ed859d..72c5796 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2325,25 +2325,37 @@ static int ext4_mb_init_backend(struct super_block *sb)
while (array_size < sizeof(*sbi->s_group_info) *
num_meta_group_infos_max)
array_size = array_size << 1;
- /* An 8TB filesystem with 64-bit pointers requires a 4096 byte
- * kmalloc. A 128kb malloc should suffice for a 256TB filesystem.
- * So a two level scheme suffices for now. */
+ /* A 16TB filesystem with 64-bit pointers requires an 8192 byte
+ * kmalloc(). Filesystems larger than 2^32 blocks (16TB normally)
+ * have group descriptors at least twice as large (64 bytes or
+ * more vs. 32 bytes for traditional ext3 filesystems), so a 128TB
+ * filesystem needs a 128kB allocation, which may need vmalloc(). */
sbi->s_group_info = kzalloc(array_size, GFP_KERNEL);
if (sbi->s_group_info == NULL) {
- printk(KERN_ERR "EXT4-fs: can't allocate buddy meta group\n");
- return -ENOMEM;
+ sbi->s_group_info = vmalloc(array_size);
+ if (sbi->s_group_info != NULL) {
+ memset(sbi->s_group_info, 0, array_size);
+ } else {
+ ext4_msg(sb, KERN_ERR, "no memory for groupinfo (%u)\n",
+ array_size);
+ return -ENOMEM;
+ }
}
sbi->s_buddy_cache = new_inode(sb);
if (sbi->s_buddy_cache == NULL) {
- printk(KERN_ERR "EXT4-fs: can't get new inode\n");
+ ext4_msg(sb, KERN_ERR, "can't get new inode\n");
goto err_freesgi;
}
- sbi->s_buddy_cache->i_ino = get_next_ino();
+ /* To avoid potentially colliding with an valid on-disk inode number,
+ * use EXT4_BAD_INO for the buddy cache inode number. This inode is
+ * not in the inode hash, so it should never be found by iget(), but
+ * this will avoid confusion if it ever shows up during debugging. */
+ sbi->s_buddy_cache->i_ino = EXT4_BAD_INO;
EXT4_I(sbi->s_buddy_cache)->i_disksize = 0;
for (i = 0; i < ngroups; i++) {
desc = ext4_get_group_desc(sb, i, NULL);
if (desc == NULL) {
- printk(KERN_ERR
+ ext4_msg(sb, KERN_ERR,
"EXT4-fs: can't read descriptor %u\n", i);
goto err_freebuddy;
}
@@ -2362,7 +2374,10 @@ err_freebuddy:
kfree(sbi->s_group_info[i]);
iput(sbi->s_buddy_cache);
err_freesgi:
- kfree(sbi->s_group_info);
+ if (is_vmalloc_addr(sbi->s_group_info))
+ vfree(sbi->s_group_info);
+ else
+ kfree(sbi->s_group_info);
return -ENOMEM;
}

@@ -2457,12 +2472,6 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
i++;
} while (i <= sb->s_blocksize_bits + 1);

- /* init file for buddy data */
- ret = ext4_mb_init_backend(sb);
- if (ret != 0) {
- goto out;
- }
-
spin_lock_init(&sbi->s_md_lock);
spin_lock_init(&sbi->s_bal_lock);

@@ -2487,6 +2496,11 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
spin_lock_init(&lg->lg_prealloc_lock);
}

+ /* init file for buddy data */
+ ret = ext4_mb_init_backend(sb);
+ if (ret != 0)
+ goto out;
+
if (sbi->s_proc)
proc_create_data("mb_groups", S_IRUGO, sbi->s_proc,
&ext4_mb_seq_groups_fops, sb);
@@ -2544,7 +2558,10 @@ int ext4_mb_release(struct super_block *sb)
EXT4_DESC_PER_BLOCK_BITS(sb);
for (i = 0; i < num_meta_group_infos; i++)
kfree(sbi->s_group_info[i]);
- kfree(sbi->s_group_info);
+ if (is_vmalloc_addr(sbi->s_group_info))
+ vfree(sbi->s_group_info);
+ else
+ kfree(sbi->s_group_info);
}
kfree(sbi->s_mb_offsets);
kfree(sbi->s_mb_maxs);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 9ea71aa..556084b 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -789,7 +789,12 @@ static void ext4_put_super(struct super_block *sb)

for (i = 0; i < sbi->s_gdb_count; i++)
brelse(sbi->s_group_desc[i]);
- kfree(sbi->s_group_desc);
+
+ if (is_vmalloc_addr(sbi->s_group_desc))
+ vfree(sbi->s_group_desc);
+ else
+ kfree(sbi->s_group_desc);
+
if (is_vmalloc_addr(sbi->s_flex_groups))
vfree(sbi->s_flex_groups);
else
@@ -3059,6 +3064,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
int ret = -ENOMEM;
int blocksize;
unsigned int db_count;
+ size_t size;
unsigned int i;
int needs_recovery, has_huge_files;
__u64 blocks_count;
@@ -3408,11 +3414,18 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
(EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb)));
db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) /
EXT4_DESC_PER_BLOCK(sb);
- sbi->s_group_desc = kmalloc(db_count * sizeof(struct buffer_head *),
- GFP_KERNEL);
+ size = (size_t)db_count * sizeof(struct buffer_head *);
+ sbi->s_group_desc = kzalloc(size, GFP_KERNEL);
if (sbi->s_group_desc == NULL) {
- ext4_msg(sb, KERN_ERR, "not enough memory");
- goto failed_mount;
+ sbi->s_group_desc = vmalloc(size);
+ if (sbi->s_group_desc != NULL) {
+ memset(sbi->s_group_desc, 0, size);
+ } else {
+ ext4_msg(sb, KERN_ERR, "no memory for %u groups (%u)\n",
+ sbi->s_groups_count, (unsigned int)size);
+ ret = -ENOMEM;
+ goto failed_mount;
+ }
}

#ifdef CONFIG_PROC_FS
@@ -3756,7 +3769,11 @@ failed_mount3:
failed_mount2:
for (i = 0; i < db_count; i++)
brelse(sbi->s_group_desc[i]);
- kfree(sbi->s_group_desc);
+
+ if (is_vmalloc_addr(sbi->s_group_desc))
+ vfree(sbi->s_group_desc);
+ else
+ kfree(sbi->s_group_desc);
failed_mount:
if (sbi->s_proc) {
remove_proc_entry(sb->s_id, ext4_proc_root);
--
1.7.3.4



2011-07-18 01:25:58

by Theodore Ts'o

[permalink] [raw]
Subject: Re: [PATCH] ext4: fall back to vmalloc() for large allocations

On Tue, Jul 12, 2011 at 03:40:46PM -0600, Andreas Dilger wrote:
> For very large ext4 filesystems (128TB and larger) kmalloc() of
> some per-group structures can fail at mount time due to memory
> fragmentation. If kmalloc() fails, fall back to vmalloc() for
> the s_group_info and s_group_desc arrays.
>
> Signed-off-by: Yu Jian <[email protected]>
> Signed-off-by: Andreas Dilger <[email protected]>

Andras, was this patch authored by Yu Jian or by you?

> sbi->s_buddy_cache = new_inode(sb);
> if (sbi->s_buddy_cache == NULL) {
> - printk(KERN_ERR "EXT4-fs: can't get new inode\n");
> + ext4_msg(sb, KERN_ERR, "can't get new inode\n");
> goto err_freesgi;
> }

Using ext4_msg instead of printk is good, but that really should be a
separate patch.


> - sbi->s_buddy_cache->i_ino = get_next_ino();
> + /* To avoid potentially colliding with an valid on-disk inode number,
> + * use EXT4_BAD_INO for the buddy cache inode number. This inode is
> + * not in the inode hash, so it should never be found by iget(), but
> + * this will avoid confusion if it ever shows up during debugging. */
> + sbi->s_buddy_cache->i_ino = EXT4_BAD_INO;

This should be a separate patch.

> @@ -2457,12 +2472,6 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
> i++;
> } while (i <= sb->s_blocksize_bits + 1);
>
> - /* init file for buddy data */
> - ret = ext4_mb_init_backend(sb);
> - if (ret != 0) {
> - goto out;
> - }
> -
> spin_lock_init(&sbi->s_md_lock);
> spin_lock_init(&sbi->s_bal_lock);
>
> @@ -2487,6 +2496,11 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
> spin_lock_init(&lg->lg_prealloc_lock);
> }
>
> + /* init file for buddy data */
> + ret = ext4_mb_init_backend(sb);
> + if (ret != 0)
> + goto out;
> +
> if (sbi->s_proc)
> proc_create_data("mb_groups", S_IRUGO, sbi->s_proc,
> &ext4_mb_seq_groups_fops, sb);

Why are you moving ext4_mb_init_backend()? This should be a separate
patch, with an explanation of what is going on....

- Ted

2011-07-18 05:12:37

by Andreas Dilger

[permalink] [raw]
Subject: Re: [PATCH] ext4: fall back to vmalloc() for large allocations

On 2011-07-17, at 7:25 PM, Ted Ts'o wrote:
> On Tue, Jul 12, 2011 at 03:40:46PM -0600, Andreas Dilger wrote:
>> For very large ext4 filesystems (128TB and larger) kmalloc() of
>> some per-group structures can fail at mount time due to memory
>> fragmentation. If kmalloc() fails, fall back to vmalloc() for
>> the s_group_info and s_group_desc arrays.
>>
>> Signed-off-by: Yu Jian <[email protected]>
>> Signed-off-by: Andreas Dilger <[email protected]>
>
> Andreas, was this patch authored by Yu Jian or by you?

Yu Jian wrote it with help from me, and I made some modifications afterward,
so I put both of our names down.

>> sbi->s_buddy_cache = new_inode(sb);
>> if (sbi->s_buddy_cache == NULL) {
>> - printk(KERN_ERR "EXT4-fs: can't get new inode\n");
>> + ext4_msg(sb, KERN_ERR, "can't get new inode\n");
>> goto err_freesgi;
>> }
>
> Using ext4_msg instead of printk is good, but that really should be a
> separate patch.

>
>> - sbi->s_buddy_cache->i_ino = get_next_ino();
>> + /* To avoid potentially colliding with an valid on-disk inode number,
>> + * use EXT4_BAD_INO for the buddy cache inode number. This inode is
>> + * not in the inode hash, so it should never be found by iget(), but
>> + * this will avoid confusion if it ever shows up during debugging. */
>> + sbi->s_buddy_cache->i_ino = EXT4_BAD_INO;
>
> This should be a separate patch.

Sure.

>> @@ -2457,12 +2472,6 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
>> i++;
>> } while (i <= sb->s_blocksize_bits + 1);
>>
>> - /* init file for buddy data */
>> - ret = ext4_mb_init_backend(sb);
>> - if (ret != 0) {
>> - goto out;
>> - }
>> -
>> spin_lock_init(&sbi->s_md_lock);
>> spin_lock_init(&sbi->s_bal_lock);
>>
>> @@ -2487,6 +2496,11 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
>> spin_lock_init(&lg->lg_prealloc_lock);
>> }
>>
>> + /* init file for buddy data */
>> + ret = ext4_mb_init_backend(sb);
>> + if (ret != 0)
>> + goto out;
>> +
>> if (sbi->s_proc)
>> proc_create_data("mb_groups", S_IRUGO, sbi->s_proc,
>> &ext4_mb_seq_groups_fops, sb);
>
> Why are you moving ext4_mb_init_backend()? This should be a separate
> patch, with an explanation of what is going on....

In ext4_mb_init(), if the s_locality_group allocation fails it will
currently cause the allocations made in ext4_mb_init_backend() to
be leaked. Moving the ext4_mb_init_backend() allocation after the
s_locality_group allocation avoids that problem.

Cheers, Andreas
--
Andreas Dilger
Principal Engineer
Whamcloud, Inc.




2011-07-18 11:36:25

by Theodore Ts'o

[permalink] [raw]
Subject: Re: [PATCH] ext4: fall back to vmalloc() for large allocations

On Sun, Jul 17, 2011 at 11:12:34PM -0600, Andreas Dilger wrote:
>
> Yu Jian wrote it with help from me, and I made some modifications afterward,
> so I put both of our names down.

OK, I just wanted to know who I should credit as the author in Git.
If you think it should be Yu Jian, could you put in a From: Yu Jian
line? If you think you made sufficient modifications that you think
it's mainly your code, that's fine. I just wasn't sure which would
have been more correct, and whether you might have just forgotten an
explicit From: header or not. Just want to give credit where credit
is due! :-)

I'm going to mark this patch as "revisions requested" in patchworkand
want for you to send out a broken out patch series.

Many thanks!!

- Ted

2011-08-01 13:13:21

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH 2/5] ext4: use ext4_kvzalloc()/ext4_kvmalloc() for s_group_desc and s_group_info

Signed-off-by: "Theodore Ts'o" <[email protected]>
---
fs/ext4/mballoc.c | 6 +++---
fs/ext4/resize.c | 13 +++++++------
fs/ext4/super.c | 9 +++++----
3 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index fa716c9..d5021e8 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2331,7 +2331,7 @@ static int ext4_mb_init_backend(struct super_block *sb)
/* An 8TB filesystem with 64-bit pointers requires a 4096 byte
* kmalloc. A 128kb malloc should suffice for a 256TB filesystem.
* So a two level scheme suffices for now. */
- sbi->s_group_info = kzalloc(array_size, GFP_KERNEL);
+ sbi->s_group_info = ext4_kvzalloc(array_size, GFP_KERNEL);
if (sbi->s_group_info == NULL) {
printk(KERN_ERR "EXT4-fs: can't allocate buddy meta group\n");
return -ENOMEM;
@@ -2365,7 +2365,7 @@ err_freebuddy:
kfree(sbi->s_group_info[i]);
iput(sbi->s_buddy_cache);
err_freesgi:
- kfree(sbi->s_group_info);
+ ext4_kvfree(sbi->s_group_info);
return -ENOMEM;
}

@@ -2559,7 +2559,7 @@ int ext4_mb_release(struct super_block *sb)
EXT4_DESC_PER_BLOCK_BITS(sb);
for (i = 0; i < num_meta_group_infos; i++)
kfree(sbi->s_group_info[i]);
- kfree(sbi->s_group_info);
+ ext4_kvfree(sbi->s_group_info);
}
kfree(sbi->s_mb_offsets);
kfree(sbi->s_mb_maxs);
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 71085df..707d3f1 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -467,12 +467,13 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
if (unlikely(err))
goto exit_dindj;

- n_group_desc = kmalloc((gdb_num + 1) * sizeof(struct buffer_head *),
- GFP_NOFS);
+ n_group_desc = ext4_kvmalloc((gdb_num + 1) *
+ sizeof(struct buffer_head *),
+ GFP_NOFS);
if (!n_group_desc) {
err = -ENOMEM;
- ext4_warning(sb,
- "not enough memory for %lu groups", gdb_num + 1);
+ ext4_warning(sb, "not enough memory for %lu groups",
+ gdb_num + 1);
goto exit_inode;
}

@@ -507,7 +508,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
n_group_desc[gdb_num] = gdb_bh;
EXT4_SB(sb)->s_group_desc = n_group_desc;
EXT4_SB(sb)->s_gdb_count++;
- kfree(o_group_desc);
+ ext4_kvfree(o_group_desc);

le16_add_cpu(&es->s_reserved_gdt_blocks, -1);
err = ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh);
@@ -517,7 +518,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
return err;

exit_inode:
- kfree(n_group_desc);
+ ext4_kvfree(n_group_desc);
/* ext4_handle_release_buffer(handle, iloc.bh); */
brelse(iloc.bh);
exit_dindj:
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 658f586..e2d88ba 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -819,7 +819,7 @@ static void ext4_put_super(struct super_block *sb)

for (i = 0; i < sbi->s_gdb_count; i++)
brelse(sbi->s_group_desc[i]);
- kfree(sbi->s_group_desc);
+ ext4_kvfree(sbi->s_group_desc);
ext4_kvfree(sbi->s_flex_groups);
percpu_counter_destroy(&sbi->s_freeblocks_counter);
percpu_counter_destroy(&sbi->s_freeinodes_counter);
@@ -3439,8 +3439,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
(EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb)));
db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) /
EXT4_DESC_PER_BLOCK(sb);
- sbi->s_group_desc = kmalloc(db_count * sizeof(struct buffer_head *),
- GFP_KERNEL);
+ sbi->s_group_desc = ext4_kvmalloc(db_count *
+ sizeof(struct buffer_head *),
+ GFP_KERNEL);
if (sbi->s_group_desc == NULL) {
ext4_msg(sb, KERN_ERR, "not enough memory");
goto failed_mount;
@@ -3783,7 +3784,7 @@ failed_mount3:
failed_mount2:
for (i = 0; i < db_count; i++)
brelse(sbi->s_group_desc[i]);
- kfree(sbi->s_group_desc);
+ ext4_kvfree(sbi->s_group_desc);
failed_mount:
if (sbi->s_proc) {
remove_proc_entry(sb->s_id, ext4_proc_root);
--
1.7.4.1.22.gec8e1.dirty


2011-08-01 13:13:21

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH 4/5] ext4: use EXT4_BAD_INO for buddy cache to avoid colliding with valid inode #

From: Yu Jian <[email protected]>

Signed-off-by: Yu Jian <[email protected]>
Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
fs/ext4/mballoc.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 262fa47..8beccd8 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2342,7 +2342,11 @@ static int ext4_mb_init_backend(struct super_block *sb)
ext4_msg(sb, KERN_ERR, "can't get new inode");
goto err_freesgi;
}
- sbi->s_buddy_cache->i_ino = get_next_ino();
+ /* To avoid potentially colliding with an valid on-disk inode number,
+ * use EXT4_BAD_INO for the buddy cache inode number. This inode is
+ * not in the inode hash, so it should never be found by iget(), but
+ * this will avoid confusion if it ever shows up during debugging. */
+ sbi->s_buddy_cache->i_ino = EXT4_BAD_INO;
EXT4_I(sbi->s_buddy_cache)->i_disksize = 0;
for (i = 0; i < ngroups; i++) {
desc = ext4_get_group_desc(sb, i, NULL);
--
1.7.4.1.22.gec8e1.dirty


2011-08-01 13:13:26

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH 0/5] Break up "fall back to vmalloc() for large allocations"

This patch series breaks up Andreas and Yu Jian's patch "fall back to
vmalloc() for large allocations" into 5 patches, with the following
changes:

1) I created new helper functions, ext4_kvmalloc(), ext4_kzalloc, and
ext4_kvfree() to simplify the code.

2) Fixed the patch so that online resize would work correctly if
s_group_info and s_group_desc were allocated using vmalloc().
(Yeah, there are other reasons why online resize won't work for
such large allocations, but let's not add to the problems; also,
there's always the possibility that kmalloc might fail for even
for a small allocation.)

3) Fixed many more places in mballoc.c where ext4_msg() would be better
than just printk().

I was waiting for Andreas and/or Yu Jian to resubmit, but since they
didn't, and I wanted these fixes, I decided to break up the patch
myself.

- Ted

Theodore Ts'o (3):
ext4: introduce ext4_kvmalloc(), ext4_kzalloc(), and ext4_kvfree()
ext4: use ext4_kvzalloc()/ext4_kvmalloc() for s_group_desc and
s_group_info
ext4: use ext4_msg() instead of printk in mballoc

Yu Jian (2):
ext4: use EXT4_BAD_INO for buddy cache to avoid colliding with valid
inode #
ext4: prevent memory leaks from ext4_mb_init_backend() on error path

fs/ext4/ext4.h | 3 ++
fs/ext4/mballoc.c | 103 +++++++++++++++++++++++++++++------------------------
fs/ext4/resize.c | 13 ++++---
fs/ext4/super.c | 63 +++++++++++++++++++++-----------
4 files changed, 107 insertions(+), 75 deletions(-)

--
1.7.4.1.22.gec8e1.dirty


2011-08-01 13:13:26

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH 1/5] ext4: introduce ext4_kvmalloc(), ext4_kzalloc(), and ext4_kvfree()

Introduce new helper functions which try kmalloc, and then fall back
to vmalloc if necessary, and use them for allocating and deallocating
s_flex_groups.

Signed-off-by: "Theodore Ts'o" <[email protected]>
---
fs/ext4/ext4.h | 3 +++
fs/ext4/super.c | 54 ++++++++++++++++++++++++++++++++++++------------------
2 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index ba2009b..db9fead 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1874,6 +1874,9 @@ extern int ext4_group_extend(struct super_block *sb,
ext4_fsblk_t n_blocks_count);

/* super.c */
+extern void *ext4_kvmalloc(size_t size, gfp_t flags);
+extern void *ext4_kvzalloc(size_t size, gfp_t flags);
+extern void ext4_kvfree(void *ptr);
extern void __ext4_error(struct super_block *, const char *, unsigned int,
const char *, ...)
__attribute__ ((format (printf, 4, 5)));
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index cfe9f39..658f586 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -110,6 +110,35 @@ static struct file_system_type ext3_fs_type = {
#define IS_EXT3_SB(sb) (0)
#endif

+void *ext4_kvmalloc(size_t size, gfp_t flags)
+{
+ void *ret;
+
+ ret = kmalloc(size, flags);
+ if (!ret)
+ ret = __vmalloc(size, flags, PAGE_KERNEL);
+ return ret;
+}
+
+void *ext4_kvzalloc(size_t size, gfp_t flags)
+{
+ void *ret;
+
+ ret = kmalloc(size, flags);
+ if (!ret)
+ ret = __vmalloc(size, flags | __GFP_ZERO, PAGE_KERNEL);
+ return ret;
+}
+
+void ext4_kvfree(void *ptr)
+{
+ if (is_vmalloc_addr(ptr))
+ vfree(ptr);
+ else
+ kfree(ptr);
+
+}
+
ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
struct ext4_group_desc *bg)
{
@@ -791,10 +820,7 @@ static void ext4_put_super(struct super_block *sb)
for (i = 0; i < sbi->s_gdb_count; i++)
brelse(sbi->s_group_desc[i]);
kfree(sbi->s_group_desc);
- if (is_vmalloc_addr(sbi->s_flex_groups))
- vfree(sbi->s_flex_groups);
- else
- kfree(sbi->s_flex_groups);
+ ext4_kvfree(sbi->s_flex_groups);
percpu_counter_destroy(&sbi->s_freeblocks_counter);
percpu_counter_destroy(&sbi->s_freeinodes_counter);
percpu_counter_destroy(&sbi->s_dirs_counter);
@@ -1977,15 +2003,11 @@ static int ext4_fill_flex_info(struct super_block *sb)
((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) <<
EXT4_DESC_PER_BLOCK_BITS(sb))) / groups_per_flex;
size = flex_group_count * sizeof(struct flex_groups);
- sbi->s_flex_groups = kzalloc(size, GFP_KERNEL);
+ sbi->s_flex_groups = ext4_kvzalloc(size, GFP_KERNEL);
if (sbi->s_flex_groups == NULL) {
- sbi->s_flex_groups = vzalloc(size);
- if (sbi->s_flex_groups == NULL) {
- ext4_msg(sb, KERN_ERR,
- "not enough memory for %u flex groups",
- flex_group_count);
- goto failed;
- }
+ ext4_msg(sb, KERN_ERR, "not enough memory for %u flex groups",
+ flex_group_count);
+ goto failed;
}

for (i = 0; i < sbi->s_groups_count; i++) {
@@ -3750,12 +3772,8 @@ failed_mount_wq:
}
failed_mount3:
del_timer(&sbi->s_err_report);
- if (sbi->s_flex_groups) {
- if (is_vmalloc_addr(sbi->s_flex_groups))
- vfree(sbi->s_flex_groups);
- else
- kfree(sbi->s_flex_groups);
- }
+ if (sbi->s_flex_groups)
+ ext4_kvfree(sbi->s_flex_groups);
percpu_counter_destroy(&sbi->s_freeblocks_counter);
percpu_counter_destroy(&sbi->s_freeinodes_counter);
percpu_counter_destroy(&sbi->s_dirs_counter);
--
1.7.4.1.22.gec8e1.dirty


2011-08-01 13:13:26

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH 5/5] ext4: prevent memory leaks from ext4_mb_init_backend() on error path

From: Yu Jian <[email protected]>

In ext4_mb_init(), if the s_locality_group allocation fails it will
currently cause the allocations made in ext4_mb_init_backend() to
be leaked. Moving the ext4_mb_init_backend() allocation after the
s_locality_group allocation avoids that problem.

Signed-off-by: Yu Jian <[email protected]>
Signed-off-by: Andreas Dilger <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>
---
fs/ext4/mballoc.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 8beccd8..c6c71af 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2465,12 +2465,6 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
i++;
} while (i <= sb->s_blocksize_bits + 1);

- /* init file for buddy data */
- ret = ext4_mb_init_backend(sb);
- if (ret != 0) {
- goto out;
- }

2011-08-01 13:13:26

by Theodore Ts'o

[permalink] [raw]
Subject: [PATCH 3/5] ext4: use ext4_msg() instead of printk in mballoc

Signed-off-by: "Theodore Ts'o" <[email protected]>
---
fs/ext4/mballoc.c | 79 ++++++++++++++++++++++++++++-------------------------
1 files changed, 42 insertions(+), 37 deletions(-)

diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index d5021e8..262fa47 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -493,10 +493,11 @@ static void mb_cmp_bitmaps(struct ext4_buddy *e4b, void *bitmap)
b2 = (unsigned char *) bitmap;
for (i = 0; i < e4b->bd_sb->s_blocksize; i++) {
if (b1[i] != b2[i]) {
- printk(KERN_ERR "corruption in group %u "
- "at byte %u(%u): %x in copy != %x "
- "on disk/prealloc\n",
- e4b->bd_group, i, i * 8, b1[i], b2[i]);
+ ext4_msg(e4b->bd_sb, KERN_ERR,
+ "corruption in group %u "
+ "at byte %u(%u): %x in copy != %x "
+ "on disk/prealloc",
+ e4b->bd_group, i, i * 8, b1[i], b2[i]);
BUG();
}
}
@@ -2224,8 +2225,8 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
EXT4_DESC_PER_BLOCK_BITS(sb);
meta_group_info = kmalloc(metalen, GFP_KERNEL);
if (meta_group_info == NULL) {
- printk(KERN_ERR "EXT4-fs: can't allocate mem for a "
- "buddy group\n");
+ ext4_msg(sb, KERN_ERR, "EXT4-fs: can't allocate mem "
+ "for a buddy group");
goto exit_meta_group_info;
}
sbi->s_group_info[group >> EXT4_DESC_PER_BLOCK_BITS(sb)] =
@@ -2238,7 +2239,7 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,

meta_group_info[i] = kmem_cache_alloc(cachep, GFP_KERNEL);
if (meta_group_info[i] == NULL) {
- printk(KERN_ERR "EXT4-fs: can't allocate buddy mem\n");
+ ext4_msg(sb, KERN_ERR, "EXT4-fs: can't allocate buddy mem");
goto exit_group_info;
}
memset(meta_group_info[i], 0, kmem_cache_size(cachep));
@@ -2333,12 +2334,12 @@ static int ext4_mb_init_backend(struct super_block *sb)
* So a two level scheme suffices for now. */
sbi->s_group_info = ext4_kvzalloc(array_size, GFP_KERNEL);
if (sbi->s_group_info == NULL) {
- printk(KERN_ERR "EXT4-fs: can't allocate buddy meta group\n");
+ ext4_msg(sb, KERN_ERR, "can't allocate buddy meta group");
return -ENOMEM;
}
sbi->s_buddy_cache = new_inode(sb);
if (sbi->s_buddy_cache == NULL) {
- printk(KERN_ERR "EXT4-fs: can't get new inode\n");
+ ext4_msg(sb, KERN_ERR, "can't get new inode");
goto err_freesgi;
}
sbi->s_buddy_cache->i_ino = get_next_ino();
@@ -2346,8 +2347,7 @@ static int ext4_mb_init_backend(struct super_block *sb)
for (i = 0; i < ngroups; i++) {
desc = ext4_get_group_desc(sb, i, NULL);
if (desc == NULL) {
- printk(KERN_ERR
- "EXT4-fs: can't read descriptor %u\n", i);
+ ext4_msg(sb, KERN_ERR, "can't read descriptor %u", i);
goto err_freebuddy;
}
if (ext4_mb_add_groupinfo(sb, i, desc) != 0)
@@ -2411,7 +2411,8 @@ static int ext4_groupinfo_create_slab(size_t size)

mutex_unlock(&ext4_grpinfo_slab_create_mutex);
if (!cachep) {
- printk(KERN_EMERG "EXT4: no memory for groupinfo slab cache\n");
+ printk(KERN_EMERG,
+ "EXT4-fs: no memory for groupinfo slab cache\n");
return -ENOMEM;
}

@@ -2566,25 +2567,25 @@ int ext4_mb_release(struct super_block *sb)
if (sbi->s_buddy_cache)
iput(sbi->s_buddy_cache);
if (sbi->s_mb_stats) {
- printk(KERN_INFO
- "EXT4-fs: mballoc: %u blocks %u reqs (%u success)\n",
+ ext4_msg(sb, KERN_INFO,
+ "mballoc: %u blocks %u reqs (%u success)",
atomic_read(&sbi->s_bal_allocated),
atomic_read(&sbi->s_bal_reqs),
atomic_read(&sbi->s_bal_success));
- printk(KERN_INFO
- "EXT4-fs: mballoc: %u extents scanned, %u goal hits, "
- "%u 2^N hits, %u breaks, %u lost\n",
+ ext4_msg(sb, KERN_INFO,
+ "mballoc: %u extents scanned, %u goal hits, "
+ "%u 2^N hits, %u breaks, %u lost",
atomic_read(&sbi->s_bal_ex_scanned),
atomic_read(&sbi->s_bal_goals),
atomic_read(&sbi->s_bal_2orders),
atomic_read(&sbi->s_bal_breaks),
atomic_read(&sbi->s_mb_lost_chunks));
- printk(KERN_INFO
- "EXT4-fs: mballoc: %lu generated and it took %Lu\n",
+ ext4_msg(sb, KERN_INFO,
+ "mballoc: %lu generated and it took %Lu",
sbi->s_mb_buddies_generated,
sbi->s_mb_generation_time);
- printk(KERN_INFO
- "EXT4-fs: mballoc: %u preallocated, %u discarded\n",
+ ext4_msg(sb, KERN_INFO,
+ "mballoc: %u preallocated, %u discarded",
atomic_read(&sbi->s_mb_preallocated),
atomic_read(&sbi->s_mb_discarded));
}
@@ -3024,9 +3025,10 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,

if (start + size <= ac->ac_o_ex.fe_logical &&
start > ac->ac_o_ex.fe_logical) {
- printk(KERN_ERR "start %lu, size %lu, fe_logical %lu\n",
- (unsigned long) start, (unsigned long) size,
- (unsigned long) ac->ac_o_ex.fe_logical);
+ ext4_msg(ac->ac_sb, KERN_ERR,
+ "start %lu, size %lu, fe_logical %lu",
+ (unsigned long) start, (unsigned long) size,
+ (unsigned long) ac->ac_o_ex.fe_logical);
}
BUG_ON(start + size <= ac->ac_o_ex.fe_logical &&
start > ac->ac_o_ex.fe_logical);
@@ -3607,10 +3609,11 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
bit = next + 1;
}
if (free != pa->pa_free) {
- printk(KERN_CRIT "pa %p: logic %lu, phys. %lu, len %lu\n",
- pa, (unsigned long) pa->pa_lstart,
- (unsigned long) pa->pa_pstart,
- (unsigned long) pa->pa_len);
+ ext4_msg(e4b->bd_sb, KERN_CRIT,
+ "pa %p: logic %lu, phys. %lu, len %lu",
+ pa, (unsigned long) pa->pa_lstart,
+ (unsigned long) pa->pa_pstart,
+ (unsigned long) pa->pa_len);
ext4_grp_locked_error(sb, group, 0, 0, "free %u, pa_free %u",
free, pa->pa_free);
/*
@@ -3798,7 +3801,8 @@ repeat:
* use preallocation while we're discarding it */
spin_unlock(&pa->pa_lock);
spin_unlock(&ei->i_prealloc_lock);
- printk(KERN_ERR "uh-oh! used pa while discarding\n");
+ ext4_msg(sb, KERN_ERR,
+ "uh-oh! used pa while discarding");
WARN_ON(1);
schedule_timeout_uninterruptible(HZ);
goto repeat;
@@ -3875,12 +3879,13 @@ static void ext4_mb_show_ac(struct ext4_allocation_context *ac)
(EXT4_SB(sb)->s_mount_flags & EXT4_MF_FS_ABORTED))
return;

- printk(KERN_ERR "EXT4-fs: Can't allocate:"
- " Allocation context details:\n");
- printk(KERN_ERR "EXT4-fs: status %d flags %d\n",
+ ext4_msg(ac->ac_sb, KERN_ERR, "EXT4-fs: Can't allocate:"
+ " Allocation context details:");
+ ext4_msg(ac->ac_sb, KERN_ERR, "EXT4-fs: status %d flags %d",
ac->ac_status, ac->ac_flags);
- printk(KERN_ERR "EXT4-fs: orig %lu/%lu/%lu@%lu, goal %lu/%lu/%lu@%lu, "
- "best %lu/%lu/%lu@%lu cr %d\n",
+ ext4_msg(ac->ac_sb, KERN_ERR, "EXT4-fs: orig %lu/%lu/%lu@%lu, "
+ "goal %lu/%lu/%lu@%lu, "
+ "best %lu/%lu/%lu@%lu cr %d",
(unsigned long)ac->ac_o_ex.fe_group,
(unsigned long)ac->ac_o_ex.fe_start,
(unsigned long)ac->ac_o_ex.fe_len,
@@ -3894,9 +3899,9 @@ static void ext4_mb_show_ac(struct ext4_allocation_context *ac)
(unsigned long)ac->ac_b_ex.fe_len,
(unsigned long)ac->ac_b_ex.fe_logical,
(int)ac->ac_criteria);
- printk(KERN_ERR "EXT4-fs: %lu scanned, %d found\n", ac->ac_ex_scanned,
- ac->ac_found);
- printk(KERN_ERR "EXT4-fs: groups: \n");
+ ext4_msg(ac->ac_sb, KERN_ERR, "EXT4-fs: %lu scanned, %d found",
+ ac->ac_ex_scanned, ac->ac_found);
+ ext4_msg(ac->ac_sb, KERN_ERR, "EXT4-fs: groups: ");
ngroups = ext4_get_groups_count(sb);
for (i = 0; i < ngroups; i++) {
struct ext4_group_info *grp = ext4_get_group_info(sb, i);
--
1.7.4.1.22.gec8e1.dirty


2011-08-02 03:11:36

by Andreas Dilger

[permalink] [raw]
Subject: Re: [PATCH 3/5] ext4: use ext4_msg() instead of printk in mballoc

On 2011-08-01, at 7:13 AM, Theodore Ts'o <[email protected]> wrote:
> Signed-off-by: "Theodore Ts'o" <[email protected]>
> ---
> fs/ext4/mballoc.c | 79 ++++++++++++++++++++++++++++-------------------------
> 1 files changed, 42 insertions(+), 37 deletions(-)

Hi Ted, thanks for updating this patch set. One minor issue below.

> diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
> index d5021e8..262fa47 100644
> --- a/fs/ext4/mballoc.c
> +++ b/fs/ext4/mballoc.c
> @@ -493,10 +493,11 @@ static void mb_cmp_bitmaps(struct ext4_buddy *e4b, void *bitmap)
> b2 = (unsigned char *) bitmap;
> for (i = 0; i < e4b->bd_sb->s_blocksize; i++) {
> if (b1[i] != b2[i]) {
> - printk(KERN_ERR "corruption in group %u "
> - "at byte %u(%u): %x in copy != %x "
> - "on disk/prealloc\n",
> - e4b->bd_group, i, i * 8, b1[i], b2[i]);
> + ext4_msg(e4b->bd_sb, KERN_ERR,
> + "corruption in group %u "
> + "at byte %u(%u): %x in copy != %x "
> + "on disk/prealloc",
> + e4b->bd_group, i, i * 8, b1[i], b2[i]);
> BUG();
> }
> }
> @@ -2224,8 +2225,8 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
> EXT4_DESC_PER_BLOCK_BITS(sb);
> meta_group_info = kmalloc(metalen, GFP_KERNEL);
> if (meta_group_info == NULL) {
> - printk(KERN_ERR "EXT4-fs: can't allocate mem for a "
> - "buddy group\n");
> + ext4_msg(sb, KERN_ERR, "EXT4-fs: can't allocate mem "
> + "for a buddy group");

I don't think ext4_msg() format strings should still have "Ext4-fs:" at the beginning. Isn't that the whole point of using ext4_msg()?

> goto exit_meta_group_info;
> }
> sbi->s_group_info[group >> EXT4_DESC_PER_BLOCK_BITS(sb)] =
> @@ -2238,7 +2239,7 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
>
> meta_group_info[i] = kmem_cache_alloc(cachep, GFP_KERNEL);
> if (meta_group_info[i] == NULL) {
> - printk(KERN_ERR "EXT4-fs: can't allocate buddy mem\n");
> + ext4_msg(sb, KERN_ERR, "EXT4-fs: can't allocate buddy mem");

Ditto.

> goto exit_group_info;
> }
> memset(meta_group_info[i], 0, kmem_cache_size(cachep));
> @@ -2333,12 +2334,12 @@ static int ext4_mb_init_backend(struct super_block *sb)
> * So a two level scheme suffices for now. */
> sbi->s_group_info = ext4_kvzalloc(array_size, GFP_KERNEL);
> if (sbi->s_group_info == NULL) {
> - printk(KERN_ERR "EXT4-fs: can't allocate buddy meta group\n");
> + ext4_msg(sb, KERN_ERR, "can't allocate buddy meta group");
> return -ENOMEM;
> }
> sbi->s_buddy_cache = new_inode(sb);
> if (sbi->s_buddy_cache == NULL) {
> - printk(KERN_ERR "EXT4-fs: can't get new inode\n");
> + ext4_msg(sb, KERN_ERR, "can't get new inode");
> goto err_freesgi;
> }
> sbi->s_buddy_cache->i_ino = get_next_ino();
> @@ -2346,8 +2347,7 @@ static int ext4_mb_init_backend(struct super_block *sb)
> for (i = 0; i < ngroups; i++) {
> desc = ext4_get_group_desc(sb, i, NULL);
> if (desc == NULL) {
> - printk(KERN_ERR
> - "EXT4-fs: can't read descriptor %u\n", i);
> + ext4_msg(sb, KERN_ERR, "can't read descriptor %u", i);
> goto err_freebuddy;
> }
> if (ext4_mb_add_groupinfo(sb, i, desc) != 0)
> @@ -2411,7 +2411,8 @@ static int ext4_groupinfo_create_slab(size_t size)
>
> mutex_unlock(&ext4_grpinfo_slab_create_mutex);
> if (!cachep) {
> - printk(KERN_EMERG "EXT4: no memory for groupinfo slab cache\n");
> + printk(KERN_EMERG,
> + "EXT4-fs: no memory for groupinfo slab cache\n");

This one didn't actually get changed to ext4_msg().

> return -ENOMEM;
> }
>
> @@ -2566,25 +2567,25 @@ int ext4_mb_release(struct super_block *sb)
> if (sbi->s_buddy_cache)
> iput(sbi->s_buddy_cache);
> if (sbi->s_mb_stats) {
> - printk(KERN_INFO
> - "EXT4-fs: mballoc: %u blocks %u reqs (%u success)\n",
> + ext4_msg(sb, KERN_INFO,
> + "mballoc: %u blocks %u reqs (%u success)",
> atomic_read(&sbi->s_bal_allocated),
> atomic_read(&sbi->s_bal_reqs),
> atomic_read(&sbi->s_bal_success));
> - printk(KERN_INFO
> - "EXT4-fs: mballoc: %u extents scanned, %u goal hits, "
> - "%u 2^N hits, %u breaks, %u lost\n",
> + ext4_msg(sb, KERN_INFO,
> + "mballoc: %u extents scanned, %u goal hits, "
> + "%u 2^N hits, %u breaks, %u lost",
> atomic_read(&sbi->s_bal_ex_scanned),
> atomic_read(&sbi->s_bal_goals),
> atomic_read(&sbi->s_bal_2orders),
> atomic_read(&sbi->s_bal_breaks),
> atomic_read(&sbi->s_mb_lost_chunks));
> - printk(KERN_INFO
> - "EXT4-fs: mballoc: %lu generated and it took %Lu\n",
> + ext4_msg(sb, KERN_INFO,
> + "mballoc: %lu generated and it took %Lu",
> sbi->s_mb_buddies_generated,
> sbi->s_mb_generation_time);
> - printk(KERN_INFO
> - "EXT4-fs: mballoc: %u preallocated, %u discarded\n",
> + ext4_msg(sb, KERN_INFO,
> + "mballoc: %u preallocated, %u discarded",
> atomic_read(&sbi->s_mb_preallocated),
> atomic_read(&sbi->s_mb_discarded));
> }
> @@ -3024,9 +3025,10 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
>
> if (start + size <= ac->ac_o_ex.fe_logical &&
> start > ac->ac_o_ex.fe_logical) {
> - printk(KERN_ERR "start %lu, size %lu, fe_logical %lu\n",
> - (unsigned long) start, (unsigned long) size,
> - (unsigned long) ac->ac_o_ex.fe_logical);
> + ext4_msg(ac->ac_sb, KERN_ERR,
> + "start %lu, size %lu, fe_logical %lu",
> + (unsigned long) start, (unsigned long) size,
> + (unsigned long) ac->ac_o_ex.fe_logical);
> }
> BUG_ON(start + size <= ac->ac_o_ex.fe_logical &&
> start > ac->ac_o_ex.fe_logical);
> @@ -3607,10 +3609,11 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
> bit = next + 1;
> }
> if (free != pa->pa_free) {
> - printk(KERN_CRIT "pa %p: logic %lu, phys. %lu, len %lu\n",
> - pa, (unsigned long) pa->pa_lstart,
> - (unsigned long) pa->pa_pstart,
> - (unsigned long) pa->pa_len);
> + ext4_msg(e4b->bd_sb, KERN_CRIT,
> + "pa %p: logic %lu, phys. %lu, len %lu",
> + pa, (unsigned long) pa->pa_lstart,
> + (unsigned long) pa->pa_pstart,
> + (unsigned long) pa->pa_len);
> ext4_grp_locked_error(sb, group, 0, 0, "free %u, pa_free %u",
> free, pa->pa_free);
> /*
> @@ -3798,7 +3801,8 @@ repeat:
> * use preallocation while we're discarding it */
> spin_unlock(&pa->pa_lock);
> spin_unlock(&ei->i_prealloc_lock);
> - printk(KERN_ERR "uh-oh! used pa while discarding\n");
> + ext4_msg(sb, KERN_ERR,
> + "uh-oh! used pa while discarding");
> WARN_ON(1);
> schedule_timeout_uninterruptible(HZ);
> goto repeat;
> @@ -3875,12 +3879,13 @@ static void ext4_mb_show_ac(struct ext4_allocation_context *ac)
> (EXT4_SB(sb)->s_mount_flags & EXT4_MF_FS_ABORTED))
> return;
>
> - printk(KERN_ERR "EXT4-fs: Can't allocate:"
> - " Allocation context details:\n");
> - printk(KERN_ERR "EXT4-fs: status %d flags %d\n",
> + ext4_msg(ac->ac_sb, KERN_ERR, "EXT4-fs: Can't allocate:"

Ditto.

> + " Allocation context details:");
> + ext4_msg(ac->ac_sb, KERN_ERR, "EXT4-fs: status %d flags %d",
> ac->ac_status, ac->ac_flags);
> - printk(KERN_ERR "EXT4-fs: orig %lu/%lu/%lu@%lu, goal %lu/%lu/%lu@%lu, "
> - "best %lu/%lu/%lu@%lu cr %d\n",
> + ext4_msg(ac->ac_sb, KERN_ERR, "EXT4-fs: orig %lu/%lu/%lu@%lu, "

Here too.

> + "goal %lu/%lu/%lu@%lu, "
> + "best %lu/%lu/%lu@%lu cr %d",
> (unsigned long)ac->ac_o_ex.fe_group,
> (unsigned long)ac->ac_o_ex.fe_start,
> (unsigned long)ac->ac_o_ex.fe_len,
> @@ -3894,9 +3899,9 @@ static void ext4_mb_show_ac(struct ext4_allocation_context *ac)
> (unsigned long)ac->ac_b_ex.fe_len,
> (unsigned long)ac->ac_b_ex.fe_logical,
> (int)ac->ac_criteria);
> - printk(KERN_ERR "EXT4-fs: %lu scanned, %d found\n", ac->ac_ex_scanned,
> - ac->ac_found);
> - printk(KERN_ERR "EXT4-fs: groups: \n");
> + ext4_msg(ac->ac_sb, KERN_ERR, "EXT4-fs: %lu scanned, %d found",

...

> + ac->ac_ex_scanned, ac->ac_found);
> + ext4_msg(ac->ac_sb, KERN_ERR, "EXT4-fs: groups: ");
> ngroups = ext4_get_groups_count(sb);
> for (i = 0; i < ngroups; i++) {
> struct ext4_group_info *grp = ext4_get_group_info(sb, i);
> --
> 1.7.4.1.22.gec8e1.dirty
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

2011-08-02 06:07:15

by Mathias Krause

[permalink] [raw]
Subject: [PATCH] ext4: use kzalloc in ext4_kzalloc()

Commit 9933fc0i (ext4: introduce ext4_kvmalloc(), ext4_kzalloc(), and
ext4_kvfree()) intruduced wrappers around k*alloc/vmalloc but introduced
a typo for ext4_kzalloc() by not using kzalloc() but kmalloc().

Signed-off-by: Mathias Krause <[email protected]>
---
fs/ext4/super.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index e2d88ba..4687fea 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -124,7 +124,7 @@ void *ext4_kvzalloc(size_t size, gfp_t flags)
{
void *ret;

- ret = kmalloc(size, flags);
+ ret = kzalloc(size, flags);
if (!ret)
ret = __vmalloc(size, flags | __GFP_ZERO, PAGE_KERNEL);
return ret;
--
1.5.6.5

2011-08-03 18:57:59

by Theodore Ts'o

[permalink] [raw]
Subject: Re: [PATCH] ext4: use kzalloc in ext4_kzalloc()

On Tue, Aug 02, 2011 at 08:07:15AM +0200, Mathias Krause wrote:
> Commit 9933fc0i (ext4: introduce ext4_kvmalloc(), ext4_kzalloc(), and
> ext4_kvfree()) intruduced wrappers around k*alloc/vmalloc but introduced
> a typo for ext4_kzalloc() by not using kzalloc() but kmalloc().
>
> Signed-off-by: Mathias Krause <[email protected]>

Oops. Thanks for catching this. I'll make sure this gets pushed to
Linus ASAP.

- Ted