diff options
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r-- | fs/block_dev.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index d9bdf2b3ade2..fc7028b685f2 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -129,6 +129,46 @@ blkdev_get_block(struct inode *inode, sector_t iblock, | |||
129 | return 0; | 129 | return 0; |
130 | } | 130 | } |
131 | 131 | ||
132 | static int | ||
133 | blkdev_get_blocks(struct inode *inode, sector_t iblock, | ||
134 | struct buffer_head *bh, int create) | ||
135 | { | ||
136 | sector_t end_block = max_block(I_BDEV(inode)); | ||
137 | unsigned long max_blocks = bh->b_size >> inode->i_blkbits; | ||
138 | |||
139 | if ((iblock + max_blocks) > end_block) { | ||
140 | max_blocks = end_block - iblock; | ||
141 | if ((long)max_blocks <= 0) { | ||
142 | if (create) | ||
143 | return -EIO; /* write fully beyond EOF */ | ||
144 | /* | ||
145 | * It is a read which is fully beyond EOF. We return | ||
146 | * a !buffer_mapped buffer | ||
147 | */ | ||
148 | max_blocks = 0; | ||
149 | } | ||
150 | } | ||
151 | |||
152 | bh->b_bdev = I_BDEV(inode); | ||
153 | bh->b_blocknr = iblock; | ||
154 | bh->b_size = max_blocks << inode->i_blkbits; | ||
155 | if (max_blocks) | ||
156 | set_buffer_mapped(bh); | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static ssize_t | ||
161 | blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | ||
162 | loff_t offset, unsigned long nr_segs) | ||
163 | { | ||
164 | struct file *file = iocb->ki_filp; | ||
165 | struct inode *inode = file->f_mapping->host; | ||
166 | |||
167 | return blockdev_direct_IO_no_locking(rw, iocb, inode, I_BDEV(inode), | ||
168 | iov, offset, nr_segs, blkdev_get_blocks, NULL); | ||
169 | } | ||
170 | |||
171 | #if 0 | ||
132 | static int blk_end_aio(struct bio *bio, unsigned int bytes_done, int error) | 172 | static int blk_end_aio(struct bio *bio, unsigned int bytes_done, int error) |
133 | { | 173 | { |
134 | struct kiocb *iocb = bio->bi_private; | 174 | struct kiocb *iocb = bio->bi_private; |
@@ -323,6 +363,7 @@ backout: | |||
323 | return PTR_ERR(page); | 363 | return PTR_ERR(page); |
324 | goto completion; | 364 | goto completion; |
325 | } | 365 | } |
366 | #endif | ||
326 | 367 | ||
327 | static int blkdev_writepage(struct page *page, struct writeback_control *wbc) | 368 | static int blkdev_writepage(struct page *page, struct writeback_control *wbc) |
328 | { | 369 | { |