

- 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[]);

_
