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.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 8b18e43b82fe..d9bdf2b3ade2 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -146,7 +146,7 @@ static int blk_end_aio(struct bio *bio, unsigned int bytes_done, int error)
146 iocb->ki_nbytes = -EIO; 146 iocb->ki_nbytes = -EIO;
147 147
148 if (atomic_dec_and_test(bio_count)) { 148 if (atomic_dec_and_test(bio_count)) {
149 if (iocb->ki_nbytes < 0) 149 if ((long)iocb->ki_nbytes < 0)
150 aio_complete(iocb, iocb->ki_nbytes, 0); 150 aio_complete(iocb, iocb->ki_nbytes, 0);
151 else 151 else
152 aio_complete(iocb, iocb->ki_left, 0); 152 aio_complete(iocb, iocb->ki_left, 0);
@@ -190,6 +190,12 @@ static struct page *blk_get_page(unsigned long addr, size_t count, int rw,
190 return pvec->page[pvec->idx++]; 190 return pvec->page[pvec->idx++];
191} 191}
192 192
193/* return a page back to pvec array */
194static void blk_unget_page(struct page *page, struct pvec *pvec)
195{
196 pvec->page[--pvec->idx] = page;
197}
198
193static ssize_t 199static ssize_t
194blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, 200blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
195 loff_t pos, unsigned long nr_segs) 201 loff_t pos, unsigned long nr_segs)
@@ -278,6 +284,8 @@ same_bio:
278 count = min(count, nbytes); 284 count = min(count, nbytes);
279 goto same_bio; 285 goto same_bio;
280 } 286 }
287 } else {
288 blk_unget_page(page, &pvec);
281 } 289 }
282 290
283 /* bio is ready, submit it */ 291 /* bio is ready, submit it */