aboutsummaryrefslogtreecommitdiffstats
path: root/fs/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/buffer.c')
-rw-r--r--fs/buffer.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index eeb8ac1aa856..f65ef8821c73 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1042,8 +1042,21 @@ grow_buffers(struct block_device *bdev, sector_t block, int size)
1042 } while ((size << sizebits) < PAGE_SIZE); 1042 } while ((size << sizebits) < PAGE_SIZE);
1043 1043
1044 index = block >> sizebits; 1044 index = block >> sizebits;
1045 block = index << sizebits;
1046 1045
1046 /*
1047 * Check for a block which wants to lie outside our maximum possible
1048 * pagecache index. (this comparison is done using sector_t types).
1049 */
1050 if (unlikely(index != block >> sizebits)) {
1051 char b[BDEVNAME_SIZE];
1052
1053 printk(KERN_ERR "%s: requested out-of-range block %llu for "
1054 "device %s\n",
1055 __FUNCTION__, (unsigned long long)block,
1056 bdevname(bdev, b));
1057 return -EIO;
1058 }
1059 block = index << sizebits;
1047 /* Create a page with the proper size buffers.. */ 1060 /* Create a page with the proper size buffers.. */
1048 page = grow_dev_page(bdev, block, index, size); 1061 page = grow_dev_page(bdev, block, index, size);
1049 if (!page) 1062 if (!page)
@@ -1070,12 +1083,16 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size)
1070 1083
1071 for (;;) { 1084 for (;;) {
1072 struct buffer_head * bh; 1085 struct buffer_head * bh;
1086 int ret;
1073 1087
1074 bh = __find_get_block(bdev, block, size); 1088 bh = __find_get_block(bdev, block, size);
1075 if (bh) 1089 if (bh)
1076 return bh; 1090 return bh;
1077 1091
1078 if (!grow_buffers(bdev, block, size)) 1092 ret = grow_buffers(bdev, block, size);
1093 if (ret < 0)
1094 return NULL;
1095 if (ret == 0)
1079 free_more_memory(); 1096 free_more_memory();
1080 } 1097 }
1081} 1098}
@@ -1837,6 +1854,7 @@ static int __block_prepare_write(struct inode *inode, struct page *page,
1837 clear_buffer_new(bh); 1854 clear_buffer_new(bh);
1838 kaddr = kmap_atomic(page, KM_USER0); 1855 kaddr = kmap_atomic(page, KM_USER0);
1839 memset(kaddr+block_start, 0, bh->b_size); 1856 memset(kaddr+block_start, 0, bh->b_size);
1857 flush_dcache_page(page);
1840 kunmap_atomic(kaddr, KM_USER0); 1858 kunmap_atomic(kaddr, KM_USER0);
1841 set_buffer_uptodate(bh); 1859 set_buffer_uptodate(bh);
1842 mark_buffer_dirty(bh); 1860 mark_buffer_dirty(bh);
@@ -2343,6 +2361,7 @@ failed:
2343 */ 2361 */
2344 kaddr = kmap_atomic(page, KM_USER0); 2362 kaddr = kmap_atomic(page, KM_USER0);
2345 memset(kaddr, 0, PAGE_CACHE_SIZE); 2363 memset(kaddr, 0, PAGE_CACHE_SIZE);
2364 flush_dcache_page(page);
2346 kunmap_atomic(kaddr, KM_USER0); 2365 kunmap_atomic(kaddr, KM_USER0);
2347 SetPageUptodate(page); 2366 SetPageUptodate(page);
2348 set_page_dirty(page); 2367 set_page_dirty(page);