diff -ruN linux-2.4.32/fs/buffer.c linux-2.4.32-fix/fs/buffer.c
--- linux-2.4.32/fs/buffer.c	2005-11-16 20:12:54.000000000 +0100
+++ linux-2.4.32-fix/fs/buffer.c	2008-04-28 10:41:48.000000000 +0200
@@ -2564,11 +2564,12 @@
 	return NULL;
 }
 
-static void hash_page_buffers(struct page *page, kdev_t dev, int block, int size)
+static void hash_page_buffers(struct page *page, kdev_t dev, int block, int size, int max)
 {
 	struct buffer_head *head = page->buffers;
 	struct buffer_head *bh = head;
 	unsigned int uptodate;
+	int i = 0;
 
 	uptodate = 1 << BH_Mapped;
 	if (Page_Uptodate(page))
@@ -2579,15 +2580,30 @@
 		if (!(bh->b_state & (1 << BH_Mapped))) {
 			init_buffer(bh, NULL, NULL);
 			bh->b_dev = dev;
-			bh->b_blocknr = block;
-			bh->b_state = uptodate;
+			if ((max != 0) && (block >= max)) {
+				/**
+				 * Do not map buffer_head if the block nb is bigger than max.
+				 * Instead, clear the buffer and set bh state as up-to-date.
+				 * This is what is done in block_read_full_page().
+				 */
+				bh->b_blocknr = 0;
+				memset(kmap(page) + i*size, 0, size);
+				flush_dcache_page(page);
+				kunmap(page);
+				set_bit(BH_Uptodate, &bh->b_state);
+			}
+			else {
+				bh->b_blocknr = block;
+				bh->b_state = uptodate;
+			}
 		}
 
 		/* Insert the buffer into the hash lists if necessary */
-		if (!bh->b_pprev)
+		if ((buffer_mapped(bh)) && (!bh->b_pprev))
 			__insert_into_hash_list(bh);
 
 		block++;
+		i++;
 		bh = bh->b_this_page;
 	} while (bh != head);
 	write_unlock(&hash_table_lock);
@@ -2603,6 +2619,7 @@
 	struct block_device *bdev;
 	unsigned long index;
 	int sizebits;
+	unsigned long max = 0;
 
 	/* Size must be multiple of hard sectorsize */
 	if (size & (get_hardsect_size(dev)-1))
@@ -2619,6 +2636,19 @@
 	index = block >> sizebits;
 	block = index << sizebits;
 
+	/* stolen from max_block() [fs/block_dev.c] */
+	if (blk_size[MAJOR(dev)]) {
+		unsigned int blocks = blk_size[MAJOR(dev)][MINOR(dev)];
+		if (blocks) {
+			unsigned int _size = block_size(dev);
+			unsigned int _sizebits = blksize_bits(_size);
+			blocks += (_size-1) >> BLOCK_SIZE_BITS;
+			max = blocks << (BLOCK_SIZE_BITS - _sizebits);
+			if (_sizebits > BLOCK_SIZE_BITS)
+				max = blocks >> (_sizebits - BLOCK_SIZE_BITS);
+		}
+	}
+
 	bdev = bdget(kdev_t_to_nr(dev));
 	if (!bdev) {
 		printk("No block device for %s\n", kdevname(dev));
@@ -2634,7 +2664,7 @@
 		return 0;
 
 	/* Hash in the buffers on the hash list */
-	hash_page_buffers(page, dev, block, size);
+	hash_page_buffers(page, dev, block, size, max);
 	UnlockPage(page);
 	page_cache_release(page);
 
