summaryrefslogtreecommitdiff
blob: 8d5eebcb0e77bffdf3cb085a41dedd41441824b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
--- fs/buffer.c-original	2007-01-27 14:46:34.000000000 +1100
+++ fs/buffer.c	2007-01-27 14:51:17.000000000 +1100
@@ -1179,6 +1179,19 @@
 	} while ((size << sizebits) < PAGE_SIZE);
 
 	index = block >> sizebits;
+	/*
+	* Check for a block which wants to lie outside our maximum possible
+	* pagecache index.  (this comparison is done using sector_t types).
+	*/
+	if (unlikely(index != block >> sizebits)) {
+		char b[BDEVNAME_SIZE];
+
+		printk(KERN_ERR "%s: requested out-of-range block %llu for "
+			"device %s\n",
+			__FUNCTION__, (unsigned long long)block,
+			bdevname(bdev, b));
+		return -EIO;
+	}
 	block = index << sizebits;
 
 	/* Create a page with the proper size buffers.. */
@@ -1207,12 +1220,16 @@
 
 	for (;;) {
 		struct buffer_head * bh;
+		int ret;
 
 		bh = __find_get_block(bdev, block, size);
 		if (bh)
 			return bh;
 
-		if (!grow_buffers(bdev, block, size))
+		ret = grow_buffers(bdev, block, size);
+		if (ret < 0)
+			return NULL;
+		if (ret == 0)
 			free_more_memory();
 	}
 }