ore: Fix NFS crash by supporting any unaligned RAID IO
[pandora-kernel.git] / fs / buffer.c
index 19d8eb7..4115eca 100644 (file)
@@ -971,6 +971,7 @@ init_page_buffers(struct page *page, struct block_device *bdev,
        struct buffer_head *head = page_buffers(page);
        struct buffer_head *bh = head;
        int uptodate = PageUptodate(page);
+       sector_t end_block = blkdev_max_block(I_BDEV(bdev->bd_inode));
 
        do {
                if (!buffer_mapped(bh)) {
@@ -979,7 +980,8 @@ init_page_buffers(struct page *page, struct block_device *bdev,
                        bh->b_blocknr = block;
                        if (uptodate)
                                set_buffer_uptodate(bh);
-                       set_buffer_mapped(bh);
+                       if (block < end_block)
+                               set_buffer_mapped(bh);
                }
                block++;
                bh = bh->b_this_page;
@@ -1085,6 +1087,9 @@ grow_buffers(struct block_device *bdev, sector_t block, int size)
 static struct buffer_head *
 __getblk_slow(struct block_device *bdev, sector_t block, int size)
 {
+       int ret;
+       struct buffer_head *bh;
+
        /* Size must be multiple of hard sectorsize */
        if (unlikely(size & (bdev_logical_block_size(bdev)-1) ||
                        (size < 512 || size > PAGE_SIZE))) {
@@ -1097,20 +1102,21 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size)
                return NULL;
        }
 
-       for (;;) {
-               struct buffer_head * bh;
-               int ret;
+retry:
+       bh = __find_get_block(bdev, block, size);
+       if (bh)
+               return bh;
 
+       ret = grow_buffers(bdev, block, size);
+       if (ret == 0) {
+               free_more_memory();
+               goto retry;
+       } else if (ret > 0) {
                bh = __find_get_block(bdev, block, size);
                if (bh)
                        return bh;
-
-               ret = grow_buffers(bdev, block, size);
-               if (ret < 0)
-                       return NULL;
-               if (ret == 0)
-                       free_more_memory();
        }
+       return NULL;
 }
 
 /*