aboutsummaryrefslogtreecommitdiffstats
path: root/fs/block_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r--fs/block_dev.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 8b18e43b82fe..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
132static int
133blkdev_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
160static ssize_t
161blkdev_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
132static int blk_end_aio(struct bio *bio, unsigned int bytes_done, int error) 172static 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;
@@ -146,7 +186,7 @@ static int blk_end_aio(struct bio *bio, unsigned int bytes_done, int error)
146 iocb->ki_nbytes = -EIO; 186 iocb->ki_nbytes = -EIO;
147 187
148 if (atomic_dec_and_test(bio_count)) { 188 if (atomic_dec_and_test(bio_count)) {
149 if (iocb->ki_nbytes < 0) 189 if ((long)iocb->ki_nbytes < 0)
150 aio_complete(iocb, iocb->ki_nbytes, 0); 190 aio_complete(iocb, iocb->ki_nbytes, 0);
151 else 191 else
152 aio_complete(iocb, iocb->ki_left, 0); 192 aio_complete(iocb, iocb->ki_left, 0);
@@ -190,6 +230,12 @@ static struct page *blk_get_page(unsigned long addr, size_t count, int rw,
190 return pvec->page[pvec->idx++]; 230 return pvec->page[pvec->idx++];
191} 231}
192 232
233/* return a page back to pvec array */
234static void blk_unget_page(struct page *page, struct pvec *pvec)
235{
236 pvec->page[--pvec->idx] = page;
237}
238
193static ssize_t 239static ssize_t
194blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, 240blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
195 loff_t pos, unsigned long nr_segs) 241 loff_t pos, unsigned long nr_segs)
@@ -278,6 +324,8 @@ same_bio:
278 count = min(count, nbytes); 324 count = min(count, nbytes);
279 goto same_bio; 325 goto same_bio;
280 } 326 }
327 } else {
328 blk_unget_page(page, &pvec);
281 } 329 }
282 330
283 /* bio is ready, submit it */ 331 /* bio is ready, submit it */
@@ -315,6 +363,7 @@ backout:
315 return PTR_ERR(page); 363 return PTR_ERR(page);
316 goto completion; 364 goto completion;
317} 365}
366#endif
318 367
319static int blkdev_writepage(struct page *page, struct writeback_control *wbc) 368static int blkdev_writepage(struct page *page, struct writeback_control *wbc)
320{ 369{