diff options
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r-- | fs/block_dev.c | 103 |
1 files changed, 81 insertions, 22 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index 552a8d13bc32..6d7274619bf9 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -165,14 +165,15 @@ blkdev_get_block(struct inode *inode, sector_t iblock, | |||
165 | } | 165 | } |
166 | 166 | ||
167 | static ssize_t | 167 | static ssize_t |
168 | blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | 168 | blkdev_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, |
169 | loff_t offset, unsigned long nr_segs) | 169 | loff_t offset) |
170 | { | 170 | { |
171 | struct file *file = iocb->ki_filp; | 171 | struct file *file = iocb->ki_filp; |
172 | struct inode *inode = file->f_mapping->host; | 172 | struct inode *inode = file->f_mapping->host; |
173 | 173 | ||
174 | return __blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iov, offset, | 174 | return __blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iter, |
175 | nr_segs, blkdev_get_block, NULL, NULL, 0); | 175 | offset, blkdev_get_block, |
176 | NULL, NULL, 0); | ||
176 | } | 177 | } |
177 | 178 | ||
178 | int __sync_blockdev(struct block_device *bdev, int wait) | 179 | int __sync_blockdev(struct block_device *bdev, int wait) |
@@ -363,6 +364,69 @@ int blkdev_fsync(struct file *filp, loff_t start, loff_t end, int datasync) | |||
363 | } | 364 | } |
364 | EXPORT_SYMBOL(blkdev_fsync); | 365 | EXPORT_SYMBOL(blkdev_fsync); |
365 | 366 | ||
367 | /** | ||
368 | * bdev_read_page() - Start reading a page from a block device | ||
369 | * @bdev: The device to read the page from | ||
370 | * @sector: The offset on the device to read the page to (need not be aligned) | ||
371 | * @page: The page to read | ||
372 | * | ||
373 | * On entry, the page should be locked. It will be unlocked when the page | ||
374 | * has been read. If the block driver implements rw_page synchronously, | ||
375 | * that will be true on exit from this function, but it need not be. | ||
376 | * | ||
377 | * Errors returned by this function are usually "soft", eg out of memory, or | ||
378 | * queue full; callers should try a different route to read this page rather | ||
379 | * than propagate an error back up the stack. | ||
380 | * | ||
381 | * Return: negative errno if an error occurs, 0 if submission was successful. | ||
382 | */ | ||
383 | int bdev_read_page(struct block_device *bdev, sector_t sector, | ||
384 | struct page *page) | ||
385 | { | ||
386 | const struct block_device_operations *ops = bdev->bd_disk->fops; | ||
387 | if (!ops->rw_page) | ||
388 | return -EOPNOTSUPP; | ||
389 | return ops->rw_page(bdev, sector + get_start_sect(bdev), page, READ); | ||
390 | } | ||
391 | EXPORT_SYMBOL_GPL(bdev_read_page); | ||
392 | |||
393 | /** | ||
394 | * bdev_write_page() - Start writing a page to a block device | ||
395 | * @bdev: The device to write the page to | ||
396 | * @sector: The offset on the device to write the page to (need not be aligned) | ||
397 | * @page: The page to write | ||
398 | * @wbc: The writeback_control for the write | ||
399 | * | ||
400 | * On entry, the page should be locked and not currently under writeback. | ||
401 | * On exit, if the write started successfully, the page will be unlocked and | ||
402 | * under writeback. If the write failed already (eg the driver failed to | ||
403 | * queue the page to the device), the page will still be locked. If the | ||
404 | * caller is a ->writepage implementation, it will need to unlock the page. | ||
405 | * | ||
406 | * Errors returned by this function are usually "soft", eg out of memory, or | ||
407 | * queue full; callers should try a different route to write this page rather | ||
408 | * than propagate an error back up the stack. | ||
409 | * | ||
410 | * Return: negative errno if an error occurs, 0 if submission was successful. | ||
411 | */ | ||
412 | int bdev_write_page(struct block_device *bdev, sector_t sector, | ||
413 | struct page *page, struct writeback_control *wbc) | ||
414 | { | ||
415 | int result; | ||
416 | int rw = (wbc->sync_mode == WB_SYNC_ALL) ? WRITE_SYNC : WRITE; | ||
417 | const struct block_device_operations *ops = bdev->bd_disk->fops; | ||
418 | if (!ops->rw_page) | ||
419 | return -EOPNOTSUPP; | ||
420 | set_page_writeback(page); | ||
421 | result = ops->rw_page(bdev, sector + get_start_sect(bdev), page, rw); | ||
422 | if (result) | ||
423 | end_page_writeback(page); | ||
424 | else | ||
425 | unlock_page(page); | ||
426 | return result; | ||
427 | } | ||
428 | EXPORT_SYMBOL_GPL(bdev_write_page); | ||
429 | |||
366 | /* | 430 | /* |
367 | * pseudo-fs | 431 | * pseudo-fs |
368 | */ | 432 | */ |
@@ -1508,43 +1572,38 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
1508 | * Does not take i_mutex for the write and thus is not for general purpose | 1572 | * Does not take i_mutex for the write and thus is not for general purpose |
1509 | * use. | 1573 | * use. |
1510 | */ | 1574 | */ |
1511 | ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, | 1575 | ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) |
1512 | unsigned long nr_segs, loff_t pos) | ||
1513 | { | 1576 | { |
1514 | struct file *file = iocb->ki_filp; | 1577 | struct file *file = iocb->ki_filp; |
1515 | struct blk_plug plug; | 1578 | struct blk_plug plug; |
1516 | ssize_t ret; | 1579 | ssize_t ret; |
1517 | 1580 | ||
1518 | BUG_ON(iocb->ki_pos != pos); | ||
1519 | |||
1520 | blk_start_plug(&plug); | 1581 | blk_start_plug(&plug); |
1521 | ret = __generic_file_aio_write(iocb, iov, nr_segs); | 1582 | ret = __generic_file_write_iter(iocb, from); |
1522 | if (ret > 0) { | 1583 | if (ret > 0) { |
1523 | ssize_t err; | 1584 | ssize_t err; |
1524 | 1585 | err = generic_write_sync(file, iocb->ki_pos - ret, ret); | |
1525 | err = generic_write_sync(file, pos, ret); | ||
1526 | if (err < 0) | 1586 | if (err < 0) |
1527 | ret = err; | 1587 | ret = err; |
1528 | } | 1588 | } |
1529 | blk_finish_plug(&plug); | 1589 | blk_finish_plug(&plug); |
1530 | return ret; | 1590 | return ret; |
1531 | } | 1591 | } |
1532 | EXPORT_SYMBOL_GPL(blkdev_aio_write); | 1592 | EXPORT_SYMBOL_GPL(blkdev_write_iter); |
1533 | 1593 | ||
1534 | static ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov, | 1594 | static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to) |
1535 | unsigned long nr_segs, loff_t pos) | ||
1536 | { | 1595 | { |
1537 | struct file *file = iocb->ki_filp; | 1596 | struct file *file = iocb->ki_filp; |
1538 | struct inode *bd_inode = file->f_mapping->host; | 1597 | struct inode *bd_inode = file->f_mapping->host; |
1539 | loff_t size = i_size_read(bd_inode); | 1598 | loff_t size = i_size_read(bd_inode); |
1599 | loff_t pos = iocb->ki_pos; | ||
1540 | 1600 | ||
1541 | if (pos >= size) | 1601 | if (pos >= size) |
1542 | return 0; | 1602 | return 0; |
1543 | 1603 | ||
1544 | size -= pos; | 1604 | size -= pos; |
1545 | if (size < iocb->ki_nbytes) | 1605 | iov_iter_truncate(to, size); |
1546 | nr_segs = iov_shorten((struct iovec *)iov, nr_segs, size); | 1606 | return generic_file_read_iter(iocb, to); |
1547 | return generic_file_aio_read(iocb, iov, nr_segs, pos); | ||
1548 | } | 1607 | } |
1549 | 1608 | ||
1550 | /* | 1609 | /* |
@@ -1576,10 +1635,10 @@ const struct file_operations def_blk_fops = { | |||
1576 | .open = blkdev_open, | 1635 | .open = blkdev_open, |
1577 | .release = blkdev_close, | 1636 | .release = blkdev_close, |
1578 | .llseek = block_llseek, | 1637 | .llseek = block_llseek, |
1579 | .read = do_sync_read, | 1638 | .read = new_sync_read, |
1580 | .write = do_sync_write, | 1639 | .write = new_sync_write, |
1581 | .aio_read = blkdev_aio_read, | 1640 | .read_iter = blkdev_read_iter, |
1582 | .aio_write = blkdev_aio_write, | 1641 | .write_iter = blkdev_write_iter, |
1583 | .mmap = generic_file_mmap, | 1642 | .mmap = generic_file_mmap, |
1584 | .fsync = blkdev_fsync, | 1643 | .fsync = blkdev_fsync, |
1585 | .unlocked_ioctl = block_ioctl, | 1644 | .unlocked_ioctl = block_ioctl, |
@@ -1587,7 +1646,7 @@ const struct file_operations def_blk_fops = { | |||
1587 | .compat_ioctl = compat_blkdev_ioctl, | 1646 | .compat_ioctl = compat_blkdev_ioctl, |
1588 | #endif | 1647 | #endif |
1589 | .splice_read = generic_file_splice_read, | 1648 | .splice_read = generic_file_splice_read, |
1590 | .splice_write = generic_file_splice_write, | 1649 | .splice_write = iter_file_splice_write, |
1591 | }; | 1650 | }; |
1592 | 1651 | ||
1593 | int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg) | 1652 | int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg) |