Skip to contentSkip to conversation

ext4: annotate unhandled kmem_cache_alloc() error

PATCH In review Akinobu Mita 4 participants 8 messages Dec 23, 2008 – Jan 12, 2009 ext4 file system

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ext4: annotate unhandled kmem_cache_alloc() error

kmem_cache_alloc() error in ext4_mb_free_metadata is not handled. I don't know how to fix it. But I can put BUG_ON to let others know the problem.

---
 fs/ext4/mballoc.c |    1 +
 1 file changed, 1 insertion(+)
fs/ext4/mballoc.c +1 -0
Index: 2.6-rc/fs/ext4/mballoc.c
===================================================================
@@ -4417,6 +4417,7 @@ ext4_mb_free_metadata(handle_t *handle, 
 	BUG_ON(e4b->bd_buddy_page == NULL);
 
 	new_entry  = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS);
+	BUG_ON(!new_entry);
 	new_entry->start_blk = block;
 	new_entry->group  = group;
 	new_entry->count = count;
#1 lore raw
Quoted 17 lines · Akinobu Mita

kmem_cache_alloc() error in ext4_mb_free_metadata is not handled. I don't know how to fix it. But I can put BUG_ON to let others know the problem.

---
 fs/ext4/mballoc.c |    1 +
 1 file changed, 1 insertion(+)

Index: 2.6-rc/fs/ext4/mballoc.c
===================================================================

fs/ext4/mballoc.c ext4_mb_free_metadata(handle_t *handle, · line 4423

Quoted 7 lines
fs/ext4/mballoc.c +1 -0
@@ -4417,6 +4417,7 @@ ext4_mb_free_metadata(handle_t *handle, 
 	BUG_ON(e4b->bd_buddy_page == NULL);
 
 	new_entry  = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS);
+	BUG_ON(!new_entry);
 	new_entry->start_blk = block;
 	new_entry->group  = group;
 	new_entry->count = count;

BUG_ON is good for devel things, but for stable stuff it's better to let somebody know an error occured rather than panic'ing the box. The proper solution would be to do

if (!new_entry)

	return -ENOMEM;

or if there is some out: label set ret to -ENOMEM and goto out, whatever is appropriate in the context. Thanks,

Josef

#2 lore raw
Quoted 9 lines

BUG_ON is good for devel things, but for stable stuff it's better to let somebody know an error occured rather than panic'ing the box. The proper solution would be to do

if (!new_entry)

       return -ENOMEM;

or if there is some out: label set ret to -ENOMEM and goto out, whatever is appropriate in the context. Thanks,

I don't understand the code around here well.
But I think it is not that simple.

The "new_entry" is needed to free blocks. If it just returns error, it leaks something.

#3 lore raw

PATCH 1/1 ext4: fix unhandled ext4_free_data allocation failure

In ext4_mb_free_blocks() ext4_free_data allocation failure
is not handled. This error handling cannot be simple error return because ext4_mb_free_blocks() cannot fail.

This patch add __GFP_NOFAIL to gfp mask for the allocation.

---
 fs/ext4/mballoc.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
fs/ext4/mballoc.c +2 -1
Index: 2.6-git/fs/ext4/mballoc.c
===================================================================
@@ -4885,7 +4885,8 @@ do_more:
 		 * blocks being freed are metadata. these blocks shouldn't
 		 * be used until this transaction is committed
 		 */
-		new_entry  = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS);
+		new_entry  = kmem_cache_alloc(ext4_free_ext_cachep,
+						GFP_NOFS | __GFP_NOFAIL);
 		new_entry->start_blk = bit;
 		new_entry->group  = block_group;
 		new_entry->count = count;
#4 lore raw

Re: [PATCH] ext4: fix unhandled ext4_free_data allocation failure

Quoted 10 lines · Akinobu Mita

In ext4_mb_free_blocks() ext4_free_data allocation failure
is not handled. This error handling cannot be simple error return because ext4_mb_free_blocks() cannot fail.

This patch add __GFP_NOFAIL to gfp mask for the allocation.

Sorry but thats still not right, the fs should never force the box to come up with memory, it should be able to gracefully handle ENOMEM cases. This patch does this properly. Thanks,

fs/ext4/mballoc.c +4 -0
index 918aec0..e97ea09 100644
@@ -4886,6 +4886,10 @@ do_more:
 		 * be used until this transaction is committed
 		 */
 		new_entry  = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS);
+		if (!new_entry) {
+			err = -ENOMEM;
+			goto error_return;
+		}
 		new_entry->start_blk = bit;
 		new_entry->group  = block_group;
 		new_entry->count = count;
#5 lore raw

Re: [PATCH] ext4: fix unhandled ext4_free_data allocation failure

Quoted 23 lines · Josef Bacik
Quoted 10 lines · Akinobu Mita

In ext4_mb_free_blocks() ext4_free_data allocation failure
is not handled. This error handling cannot be simple error return because ext4_mb_free_blocks() cannot fail.

This patch add __GFP_NOFAIL to gfp mask for the allocation.

Sorry but thats still not right, the fs should never force the box to come up with memory, it should be able to gracefully handle ENOMEM cases. This patch does this properly. Thanks,

fs/ext4/mballoc.c +0 -0
index 918aec0..e97ea09 100644

fs/ext4/mballoc.c do_more: · line 4895

Quoted 10 lines
fs/ext4/mballoc.c +4 -0
@@ -4886,6 +4886,10 @@ do_more:
 		 * be used until this transaction is committed
 		 */
 		new_entry  = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS);
+		if (!new_entry) {
+			err = -ENOMEM;
+			goto error_return;
+		}
 		new_entry->start_blk = bit;
 		new_entry->group  = block_group;
 		new_entry->count = count;

Well, this will now force a filesystem error (then remount-ro or panic (or ignore) if the allocation fails. I'm not sure that's better...?

-Eric

maintainer
#6 lore raw

Re: [PATCH] ext4: fix unhandled ext4_free_data allocation failure

Quoted 4 lines · Eric Sandeen

Well, this will now force a filesystem error (then remount-ro or panic (or ignore) if the allocation fails. I'm not sure that's better...?

Well, our choices basically are:

1)  Force a filesystem error
2)  Sleep and retry the allocation
3)  Don't add the freed blocks to the list regions that mballoc should

be allowed to allocate from after the transaction commits. This results in the blocks getting "leaked" until the filesystem is mounted/unounted.

- Ted

maintainer
#7 lore raw

Re: [PATCH] ext4: fix unhandled ext4_free_data allocation failure

Quoted 6 lines · Theodore Tso
Quoted 4 lines · Eric Sandeen

Well, this will now force a filesystem error (then remount-ro or panic (or ignore) if the allocation fails. I'm not sure that's better...?

Quoted 8 lines

Well, our choices basically are:

1)  Force a filesystem error
2)  Sleep and retry the allocation
3)  Don't add the freed blocks to the list regions that mballoc should

be allowed to allocate from after the transaction commits. This results in the blocks getting "leaked" until the filesystem is mounted/unounted.

I just thought of another alternative:

4) Mark the buddy cache has being in need of being completely rebuilt after the transaction commits.

Someone want to try coding that up?

- Ted