diff options
Diffstat (limited to 'fs/block_dev.c')
-rw-r--r-- | fs/block_dev.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index b5e87896f517..897ee0503932 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -146,15 +146,13 @@ blkdev_get_block(struct inode *inode, sector_t iblock, | |||
146 | } | 146 | } |
147 | 147 | ||
148 | static ssize_t | 148 | static ssize_t |
149 | blkdev_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, | 149 | blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset) |
150 | loff_t offset) | ||
151 | { | 150 | { |
152 | struct file *file = iocb->ki_filp; | 151 | struct file *file = iocb->ki_filp; |
153 | struct inode *inode = file->f_mapping->host; | 152 | struct inode *inode = file->f_mapping->host; |
154 | 153 | ||
155 | return __blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iter, | 154 | return __blockdev_direct_IO(iocb, inode, I_BDEV(inode), iter, offset, |
156 | offset, blkdev_get_block, | 155 | blkdev_get_block, NULL, NULL, 0); |
157 | NULL, NULL, 0); | ||
158 | } | 156 | } |
159 | 157 | ||
160 | int __sync_blockdev(struct block_device *bdev, int wait) | 158 | int __sync_blockdev(struct block_device *bdev, int wait) |
@@ -1597,9 +1595,22 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
1597 | ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) | 1595 | ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) |
1598 | { | 1596 | { |
1599 | struct file *file = iocb->ki_filp; | 1597 | struct file *file = iocb->ki_filp; |
1598 | struct inode *bd_inode = file->f_mapping->host; | ||
1599 | loff_t size = i_size_read(bd_inode); | ||
1600 | struct blk_plug plug; | 1600 | struct blk_plug plug; |
1601 | ssize_t ret; | 1601 | ssize_t ret; |
1602 | 1602 | ||
1603 | if (bdev_read_only(I_BDEV(bd_inode))) | ||
1604 | return -EPERM; | ||
1605 | |||
1606 | if (!iov_iter_count(from)) | ||
1607 | return 0; | ||
1608 | |||
1609 | if (iocb->ki_pos >= size) | ||
1610 | return -ENOSPC; | ||
1611 | |||
1612 | iov_iter_truncate(from, size - iocb->ki_pos); | ||
1613 | |||
1603 | blk_start_plug(&plug); | 1614 | blk_start_plug(&plug); |
1604 | ret = __generic_file_write_iter(iocb, from); | 1615 | ret = __generic_file_write_iter(iocb, from); |
1605 | if (ret > 0) { | 1616 | if (ret > 0) { |