patch-2.1.52 linux/fs/buffer.c

Next file: linux/fs/dcache.c
Previous file: linux/fs/binfmt_misc.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.51/linux/fs/buffer.c linux/fs/buffer.c
@@ -823,12 +823,8 @@
 struct buffer_head * getblk(kdev_t dev, int block, int size)
 {
 	struct buffer_head * bh;
-	int isize = BUFSIZE_INDEX(size);
+	int isize;
 
-	/* If there are too many dirty buffers, we wake up the update process
-	 * now so as to ensure that there are still clean buffers available
-	 * for user processes to use (and dirty).
-	 */
 repeat:
 	bh = get_hash_table(dev, block, size);
 	if (bh) {
@@ -841,17 +837,15 @@
 		return bh;
 	}
 
-	while(!free_list[isize])
-		refill_freelist(size);
-	
-	if (find_buffer(dev,block,size))
-		 goto repeat;
-
+	isize = BUFSIZE_INDEX(size);
+get_free:
 	bh = free_list[isize];
+	if (!bh)
+		goto refill;
 	remove_from_free_list(bh);
 
 	/* OK, FINALLY we know that this buffer is the only one of its kind,
-	 * and that it's unused (b_count=0), unlocked (buffer_locked=0), and clean.
+	 * and that it's unused (b_count=0), unlocked, and clean.
 	 */
 	bh->b_count=1;
 	bh->b_list	= BUF_CLEAN;
@@ -862,6 +856,16 @@
 	bh->b_blocknr=block;
 	insert_into_queues(bh);
 	return bh;
+
+	/*
+	 * If we block while refilling the free list, somebody may
+	 * create the buffer first ... search the hashes again.
+	 */
+refill:
+	refill_freelist(size);
+	if (!find_buffer(dev,block,size))
+		goto get_free;
+	goto repeat;
 }
 
 void set_writetime(struct buffer_head * buf, int flag)

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov