- alloc_buffer_head() should take the allocation mode as an arg, and not assume. - Use __GFP_REPEAT in JBD's call to alloc_buffer_head(). fs/buffer.c | 8 ++++---- fs/jbd/journal.c | 10 ++-------- include/linux/buffer_head.h | 2 +- 3 files changed, 7 insertions(+), 13 deletions(-) diff -puN fs/buffer.c~alloc_buffer_head-take-gfp fs/buffer.c --- 25/fs/buffer.c~alloc_buffer_head-take-gfp 2003-04-10 21:56:54.000000000 -0700 +++ 25-akpm/fs/buffer.c 2003-04-10 21:57:41.000000000 -0700 @@ -919,7 +919,7 @@ try_again: head = NULL; offset = PAGE_SIZE; while ((offset -= size) >= 0) { - bh = alloc_buffer_head(); + bh = alloc_buffer_head(GFP_NOFS); if (!bh) goto no_grow; @@ -2270,7 +2270,7 @@ int nobh_prepare_write(struct page *page if (buffer_uptodate(&map_bh)) continue; /* reiserfs does this */ if (block_start < from || block_end > to) { - struct buffer_head *bh = alloc_buffer_head(); + struct buffer_head *bh = alloc_buffer_head(GFP_NOFS); if (!bh) { ret = -ENOMEM; @@ -2829,9 +2829,9 @@ static void recalc_bh_state(void) buffer_heads_over_limit = (tot > max_buffer_heads); } -struct buffer_head *alloc_buffer_head(void) +struct buffer_head *alloc_buffer_head(int gfp_flags) { - struct buffer_head *ret = kmem_cache_alloc(bh_cachep, GFP_NOFS); + struct buffer_head *ret = kmem_cache_alloc(bh_cachep, gfp_flags); if (ret) { preempt_disable(); __get_cpu_var(bh_accounting).nr++; diff -puN fs/jbd/journal.c~alloc_buffer_head-take-gfp fs/jbd/journal.c --- 25/fs/jbd/journal.c~alloc_buffer_head-take-gfp 2003-04-10 21:56:54.000000000 -0700 +++ 25-akpm/fs/jbd/journal.c 2003-04-10 21:58:07.000000000 -0700 @@ -457,14 +457,8 @@ int journal_write_metadata_buffer(transa /* * Right, time to make up the new buffer_head. */ - do { - new_bh = alloc_buffer_head(); - if (!new_bh) { - printk (KERN_NOTICE "%s: ENOMEM at alloc_buffer_head, " - "trying again.\n", __FUNCTION__); - yield(); - } - } while (!new_bh); + new_bh = alloc_buffer_head(GFP_NOFS|__GFP_REPEAT); + /* keep subsequent assertions sane */ new_bh->b_state = 0; init_buffer(new_bh, NULL, NULL); diff -puN include/linux/buffer_head.h~alloc_buffer_head-take-gfp include/linux/buffer_head.h --- 25/include/linux/buffer_head.h~alloc_buffer_head-take-gfp 2003-04-10 21:56:54.000000000 -0700 +++ 25-akpm/include/linux/buffer_head.h 2003-04-10 21:58:15.000000000 -0700 @@ -172,7 +172,7 @@ struct buffer_head * __getblk(struct blo void __brelse(struct buffer_head *); void __bforget(struct buffer_head *); struct buffer_head *__bread(struct block_device *, sector_t block, int size); -struct buffer_head *alloc_buffer_head(void); +struct buffer_head *alloc_buffer_head(int gfp_flags); void free_buffer_head(struct buffer_head * bh); void FASTCALL(unlock_buffer(struct buffer_head *bh)); void ll_rw_block(int, int, struct buffer_head * bh[]); _