1cd82cca7SChristoph Hellwig // SPDX-License-Identifier: GPL-2.0-only 2cd82cca7SChristoph Hellwig /* 3cd82cca7SChristoph Hellwig * Copyright (C) 1991, 1992 Linus Torvalds 4cd82cca7SChristoph Hellwig * Copyright (C) 2001 Andrea Arcangeli <[email protected]> SuSE 5cd82cca7SChristoph Hellwig * Copyright (C) 2016 - 2020 Christoph Hellwig 6cd82cca7SChristoph Hellwig */ 7cd82cca7SChristoph Hellwig #include <linux/init.h> 8cd82cca7SChristoph Hellwig #include <linux/mm.h> 9cd82cca7SChristoph Hellwig #include <linux/blkdev.h> 10cd82cca7SChristoph Hellwig #include <linux/buffer_head.h> 11cd82cca7SChristoph Hellwig #include <linux/mpage.h> 12cd82cca7SChristoph Hellwig #include <linux/uio.h> 13cd82cca7SChristoph Hellwig #include <linux/namei.h> 14cd82cca7SChristoph Hellwig #include <linux/task_io_accounting_ops.h> 15cd82cca7SChristoph Hellwig #include <linux/falloc.h> 16cd82cca7SChristoph Hellwig #include <linux/suspend.h> 17f278eb3dSMing Lei #include <linux/fs.h> 18487c607dSChristoph Hellwig #include <linux/iomap.h> 198581fd40SJakub Kicinski #include <linux/module.h> 2050c52250SPavel Begunkov #include <linux/io_uring/cmd.h> 21cd82cca7SChristoph Hellwig #include "blk.h" 22cd82cca7SChristoph Hellwig 23fac7c6d5SPavel Begunkov static inline struct inode *bdev_file_inode(struct file *file) 24cd82cca7SChristoph Hellwig { 25cd82cca7SChristoph Hellwig return file->f_mapping->host; 26cd82cca7SChristoph Hellwig } 27cd82cca7SChristoph Hellwig 2816458cf3SBart Van Assche static blk_opf_t dio_bio_write_op(struct kiocb *iocb) 29cd82cca7SChristoph Hellwig { 3016458cf3SBart Van Assche blk_opf_t opf = REQ_OP_WRITE | REQ_SYNC | REQ_IDLE; 31cd82cca7SChristoph Hellwig 32cd82cca7SChristoph Hellwig /* avoid the need for a I/O completion work item */ 3391b94c5dSAl Viro if (iocb_is_dsync(iocb)) 3416458cf3SBart Van Assche opf |= REQ_FUA; 3516458cf3SBart Van Assche return opf; 36cd82cca7SChristoph Hellwig } 37cd82cca7SChristoph Hellwig 389a8dbdadSJohn Garry static bool blkdev_dio_invalid(struct block_device *bdev, struct kiocb *iocb, 39c3be7ebbSJohn Garry struct iov_iter *iter) 4037fee2e4SKeith Busch { 419a8dbdadSJohn Garry return iocb->ki_pos & (bdev_logical_block_size(bdev) - 1) || 42b1a000d3SKeith Busch !bdev_iter_is_aligned(bdev, iter); 4337fee2e4SKeith Busch } 4437fee2e4SKeith Busch 45cd82cca7SChristoph Hellwig #define DIO_INLINE_BIO_VECS 4 46cd82cca7SChristoph Hellwig 47cd82cca7SChristoph Hellwig static ssize_t __blkdev_direct_IO_simple(struct kiocb *iocb, 48de4c7befSJohn Garry struct iov_iter *iter, struct block_device *bdev, 49de4c7befSJohn Garry unsigned int nr_pages) 50cd82cca7SChristoph Hellwig { 51cd82cca7SChristoph Hellwig struct bio_vec inline_vecs[DIO_INLINE_BIO_VECS], *vecs; 52cd82cca7SChristoph Hellwig loff_t pos = iocb->ki_pos; 53cd82cca7SChristoph Hellwig bool should_dirty = false; 54cd82cca7SChristoph Hellwig struct bio bio; 55cd82cca7SChristoph Hellwig ssize_t ret; 56cd82cca7SChristoph Hellwig 57*3d8b5a22SKanchan Joshi WARN_ON_ONCE(iocb->ki_flags & IOCB_HAS_METADATA); 58cd82cca7SChristoph Hellwig if (nr_pages <= DIO_INLINE_BIO_VECS) 59cd82cca7SChristoph Hellwig vecs = inline_vecs; 60cd82cca7SChristoph Hellwig else { 61cd82cca7SChristoph Hellwig vecs = kmalloc_array(nr_pages, sizeof(struct bio_vec), 62cd82cca7SChristoph Hellwig GFP_KERNEL); 63cd82cca7SChristoph Hellwig if (!vecs) 64cd82cca7SChristoph Hellwig return -ENOMEM; 65cd82cca7SChristoph Hellwig } 66cd82cca7SChristoph Hellwig 6749add496SChristoph Hellwig if (iov_iter_rw(iter) == READ) { 6849add496SChristoph Hellwig bio_init(&bio, bdev, vecs, nr_pages, REQ_OP_READ); 69fcb14cb1SAl Viro if (user_backed_iter(iter)) 7049add496SChristoph Hellwig should_dirty = true; 7149add496SChristoph Hellwig } else { 7249add496SChristoph Hellwig bio_init(&bio, bdev, vecs, nr_pages, dio_bio_write_op(iocb)); 7349add496SChristoph Hellwig } 746549a874SPavel Begunkov bio.bi_iter.bi_sector = pos >> SECTOR_SHIFT; 7544981351SBart Van Assche bio.bi_write_hint = file_inode(iocb->ki_filp)->i_write_hint; 76cd82cca7SChristoph Hellwig bio.bi_ioprio = iocb->ki_ioprio; 77caf336f8SJohn Garry if (iocb->ki_flags & IOCB_ATOMIC) 78caf336f8SJohn Garry bio.bi_opf |= REQ_ATOMIC; 79cd82cca7SChristoph Hellwig 80cd82cca7SChristoph Hellwig ret = bio_iov_iter_get_pages(&bio, iter); 81cd82cca7SChristoph Hellwig if (unlikely(ret)) 82cd82cca7SChristoph Hellwig goto out; 83cd82cca7SChristoph Hellwig ret = bio.bi_iter.bi_size; 84cd82cca7SChristoph Hellwig 8549add496SChristoph Hellwig if (iov_iter_rw(iter) == WRITE) 86cd82cca7SChristoph Hellwig task_io_account_write(ret); 8749add496SChristoph Hellwig 88cd82cca7SChristoph Hellwig if (iocb->ki_flags & IOCB_NOWAIT) 89cd82cca7SChristoph Hellwig bio.bi_opf |= REQ_NOWAIT; 90cd82cca7SChristoph Hellwig 919650b453SMing Lei submit_bio_wait(&bio); 92cd82cca7SChristoph Hellwig 93cd82cca7SChristoph Hellwig bio_release_pages(&bio, should_dirty); 94cd82cca7SChristoph Hellwig if (unlikely(bio.bi_status)) 95cd82cca7SChristoph Hellwig ret = blk_status_to_errno(bio.bi_status); 96cd82cca7SChristoph Hellwig 97cd82cca7SChristoph Hellwig out: 98cd82cca7SChristoph Hellwig if (vecs != inline_vecs) 99cd82cca7SChristoph Hellwig kfree(vecs); 100cd82cca7SChristoph Hellwig 101cd82cca7SChristoph Hellwig bio_uninit(&bio); 102cd82cca7SChristoph Hellwig 103cd82cca7SChristoph Hellwig return ret; 104cd82cca7SChristoph Hellwig } 105cd82cca7SChristoph Hellwig 10609ce8744SJens Axboe enum { 107e71aa913SPavel Begunkov DIO_SHOULD_DIRTY = 1, 108e71aa913SPavel Begunkov DIO_IS_SYNC = 2, 10909ce8744SJens Axboe }; 11009ce8744SJens Axboe 111cd82cca7SChristoph Hellwig struct blkdev_dio { 112cd82cca7SChristoph Hellwig union { 113cd82cca7SChristoph Hellwig struct kiocb *iocb; 114cd82cca7SChristoph Hellwig struct task_struct *waiter; 115cd82cca7SChristoph Hellwig }; 116cd82cca7SChristoph Hellwig size_t size; 117cd82cca7SChristoph Hellwig atomic_t ref; 11809ce8744SJens Axboe unsigned int flags; 1196155631aSJens Axboe struct bio bio ____cacheline_aligned_in_smp; 120cd82cca7SChristoph Hellwig }; 121cd82cca7SChristoph Hellwig 122cd82cca7SChristoph Hellwig static struct bio_set blkdev_dio_pool; 123cd82cca7SChristoph Hellwig 124cd82cca7SChristoph Hellwig static void blkdev_bio_end_io(struct bio *bio) 125cd82cca7SChristoph Hellwig { 126cd82cca7SChristoph Hellwig struct blkdev_dio *dio = bio->bi_private; 12709ce8744SJens Axboe bool should_dirty = dio->flags & DIO_SHOULD_DIRTY; 128*3d8b5a22SKanchan Joshi bool is_sync = dio->flags & DIO_IS_SYNC; 129cd82cca7SChristoph Hellwig 130cd82cca7SChristoph Hellwig if (bio->bi_status && !dio->bio.bi_status) 131cd82cca7SChristoph Hellwig dio->bio.bi_status = bio->bi_status; 132cd82cca7SChristoph Hellwig 133*3d8b5a22SKanchan Joshi if (!is_sync && (dio->iocb->ki_flags & IOCB_HAS_METADATA)) 134*3d8b5a22SKanchan Joshi bio_integrity_unmap_user(bio); 135*3d8b5a22SKanchan Joshi 136e71aa913SPavel Begunkov if (atomic_dec_and_test(&dio->ref)) { 137*3d8b5a22SKanchan Joshi if (!is_sync) { 138cd82cca7SChristoph Hellwig struct kiocb *iocb = dio->iocb; 139cd82cca7SChristoph Hellwig ssize_t ret; 140cd82cca7SChristoph Hellwig 1413e08773cSChristoph Hellwig WRITE_ONCE(iocb->private, NULL); 1423e08773cSChristoph Hellwig 143cd82cca7SChristoph Hellwig if (likely(!dio->bio.bi_status)) { 144cd82cca7SChristoph Hellwig ret = dio->size; 145cd82cca7SChristoph Hellwig iocb->ki_pos += ret; 146cd82cca7SChristoph Hellwig } else { 147cd82cca7SChristoph Hellwig ret = blk_status_to_errno(dio->bio.bi_status); 148cd82cca7SChristoph Hellwig } 149cd82cca7SChristoph Hellwig 1506b19b766SJens Axboe dio->iocb->ki_complete(iocb, ret); 151cd82cca7SChristoph Hellwig bio_put(&dio->bio); 152cd82cca7SChristoph Hellwig } else { 153cd82cca7SChristoph Hellwig struct task_struct *waiter = dio->waiter; 154cd82cca7SChristoph Hellwig 155cd82cca7SChristoph Hellwig WRITE_ONCE(dio->waiter, NULL); 156cd82cca7SChristoph Hellwig blk_wake_io_task(waiter); 157cd82cca7SChristoph Hellwig } 158cd82cca7SChristoph Hellwig } 159cd82cca7SChristoph Hellwig 160cd82cca7SChristoph Hellwig if (should_dirty) { 161cd82cca7SChristoph Hellwig bio_check_pages_dirty(bio); 162cd82cca7SChristoph Hellwig } else { 163cd82cca7SChristoph Hellwig bio_release_pages(bio, false); 164cd82cca7SChristoph Hellwig bio_put(bio); 165cd82cca7SChristoph Hellwig } 166cd82cca7SChristoph Hellwig } 167cd82cca7SChristoph Hellwig 168cd82cca7SChristoph Hellwig static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, 169de4c7befSJohn Garry struct block_device *bdev, unsigned int nr_pages) 170cd82cca7SChristoph Hellwig { 171cd82cca7SChristoph Hellwig struct blk_plug plug; 172cd82cca7SChristoph Hellwig struct blkdev_dio *dio; 173cd82cca7SChristoph Hellwig struct bio *bio; 174cd82cca7SChristoph Hellwig bool is_read = (iov_iter_rw(iter) == READ), is_sync; 17516458cf3SBart Van Assche blk_opf_t opf = is_read ? REQ_OP_READ : dio_bio_write_op(iocb); 176cd82cca7SChristoph Hellwig loff_t pos = iocb->ki_pos; 177cd82cca7SChristoph Hellwig int ret = 0; 178cd82cca7SChristoph Hellwig 1790df71650SMike Snitzer if (iocb->ki_flags & IOCB_ALLOC_CACHE) 1800df71650SMike Snitzer opf |= REQ_ALLOC_CACHE; 1810df71650SMike Snitzer bio = bio_alloc_bioset(bdev, nr_pages, opf, GFP_KERNEL, 1820df71650SMike Snitzer &blkdev_dio_pool); 183cd82cca7SChristoph Hellwig dio = container_of(bio, struct blkdev_dio, bio); 184e71aa913SPavel Begunkov atomic_set(&dio->ref, 1); 185e71aa913SPavel Begunkov /* 186e71aa913SPavel Begunkov * Grab an extra reference to ensure the dio structure which is embedded 187e71aa913SPavel Begunkov * into the first bio stays around. 188e71aa913SPavel Begunkov */ 189e71aa913SPavel Begunkov bio_get(bio); 190e71aa913SPavel Begunkov 19109ce8744SJens Axboe is_sync = is_sync_kiocb(iocb); 19209ce8744SJens Axboe if (is_sync) { 19309ce8744SJens Axboe dio->flags = DIO_IS_SYNC; 194cd82cca7SChristoph Hellwig dio->waiter = current; 195cd82cca7SChristoph Hellwig } else { 19609ce8744SJens Axboe dio->flags = 0; 197cd82cca7SChristoph Hellwig dio->iocb = iocb; 198cd82cca7SChristoph Hellwig } 199cd82cca7SChristoph Hellwig 200cd82cca7SChristoph Hellwig dio->size = 0; 201fcb14cb1SAl Viro if (is_read && user_backed_iter(iter)) 20209ce8744SJens Axboe dio->flags |= DIO_SHOULD_DIRTY; 203cd82cca7SChristoph Hellwig 204cd82cca7SChristoph Hellwig blk_start_plug(&plug); 205cd82cca7SChristoph Hellwig 206cd82cca7SChristoph Hellwig for (;;) { 2076549a874SPavel Begunkov bio->bi_iter.bi_sector = pos >> SECTOR_SHIFT; 20844981351SBart Van Assche bio->bi_write_hint = file_inode(iocb->ki_filp)->i_write_hint; 209cd82cca7SChristoph Hellwig bio->bi_private = dio; 210cd82cca7SChristoph Hellwig bio->bi_end_io = blkdev_bio_end_io; 211cd82cca7SChristoph Hellwig bio->bi_ioprio = iocb->ki_ioprio; 212cd82cca7SChristoph Hellwig 213cd82cca7SChristoph Hellwig ret = bio_iov_iter_get_pages(bio, iter); 214cd82cca7SChristoph Hellwig if (unlikely(ret)) { 215cd82cca7SChristoph Hellwig bio->bi_status = BLK_STS_IOERR; 216cd82cca7SChristoph Hellwig bio_endio(bio); 217cd82cca7SChristoph Hellwig break; 218cd82cca7SChristoph Hellwig } 21967d59247SJens Axboe if (iocb->ki_flags & IOCB_NOWAIT) { 22067d59247SJens Axboe /* 22167d59247SJens Axboe * This is nonblocking IO, and we need to allocate 22267d59247SJens Axboe * another bio if we have data left to map. As we 22367d59247SJens Axboe * cannot guarantee that one of the sub bios will not 22467d59247SJens Axboe * fail getting issued FOR NOWAIT and as error results 22567d59247SJens Axboe * are coalesced across all of them, be safe and ask for 22667d59247SJens Axboe * a retry of this from blocking context. 22767d59247SJens Axboe */ 22867d59247SJens Axboe if (unlikely(iov_iter_count(iter))) { 229*3d8b5a22SKanchan Joshi ret = -EAGAIN; 230*3d8b5a22SKanchan Joshi goto fail; 23167d59247SJens Axboe } 23267d59247SJens Axboe bio->bi_opf |= REQ_NOWAIT; 23367d59247SJens Axboe } 234*3d8b5a22SKanchan Joshi if (!is_sync && (iocb->ki_flags & IOCB_HAS_METADATA)) { 235*3d8b5a22SKanchan Joshi ret = bio_integrity_map_iter(bio, iocb->private); 236*3d8b5a22SKanchan Joshi if (unlikely(ret)) 237*3d8b5a22SKanchan Joshi goto fail; 238*3d8b5a22SKanchan Joshi } 239cd82cca7SChristoph Hellwig 240cd82cca7SChristoph Hellwig if (is_read) { 24109ce8744SJens Axboe if (dio->flags & DIO_SHOULD_DIRTY) 242cd82cca7SChristoph Hellwig bio_set_pages_dirty(bio); 243cd82cca7SChristoph Hellwig } else { 244cd82cca7SChristoph Hellwig task_io_account_write(bio->bi_iter.bi_size); 245cd82cca7SChristoph Hellwig } 246cd82cca7SChristoph Hellwig dio->size += bio->bi_iter.bi_size; 247cd82cca7SChristoph Hellwig pos += bio->bi_iter.bi_size; 248cd82cca7SChristoph Hellwig 249cd82cca7SChristoph Hellwig nr_pages = bio_iov_vecs_to_alloc(iter, BIO_MAX_VECS); 250cd82cca7SChristoph Hellwig if (!nr_pages) { 2513e08773cSChristoph Hellwig submit_bio(bio); 252cd82cca7SChristoph Hellwig break; 253cd82cca7SChristoph Hellwig } 254cd82cca7SChristoph Hellwig atomic_inc(&dio->ref); 255cd82cca7SChristoph Hellwig submit_bio(bio); 25607888c66SChristoph Hellwig bio = bio_alloc(bdev, nr_pages, opf, GFP_KERNEL); 257cd82cca7SChristoph Hellwig } 258cd82cca7SChristoph Hellwig 259cd82cca7SChristoph Hellwig blk_finish_plug(&plug); 260cd82cca7SChristoph Hellwig 261cd82cca7SChristoph Hellwig if (!is_sync) 262cd82cca7SChristoph Hellwig return -EIOCBQUEUED; 263cd82cca7SChristoph Hellwig 264cd82cca7SChristoph Hellwig for (;;) { 265cd82cca7SChristoph Hellwig set_current_state(TASK_UNINTERRUPTIBLE); 266cd82cca7SChristoph Hellwig if (!READ_ONCE(dio->waiter)) 267cd82cca7SChristoph Hellwig break; 268cd82cca7SChristoph Hellwig blk_io_schedule(); 269cd82cca7SChristoph Hellwig } 270cd82cca7SChristoph Hellwig __set_current_state(TASK_RUNNING); 271cd82cca7SChristoph Hellwig 272cd82cca7SChristoph Hellwig if (!ret) 273cd82cca7SChristoph Hellwig ret = blk_status_to_errno(dio->bio.bi_status); 274cd82cca7SChristoph Hellwig if (likely(!ret)) 275cd82cca7SChristoph Hellwig ret = dio->size; 276cd82cca7SChristoph Hellwig 277cd82cca7SChristoph Hellwig bio_put(&dio->bio); 278cd82cca7SChristoph Hellwig return ret; 279*3d8b5a22SKanchan Joshi fail: 280*3d8b5a22SKanchan Joshi bio_release_pages(bio, false); 281*3d8b5a22SKanchan Joshi bio_clear_flag(bio, BIO_REFFED); 282*3d8b5a22SKanchan Joshi bio_put(bio); 283*3d8b5a22SKanchan Joshi blk_finish_plug(&plug); 284*3d8b5a22SKanchan Joshi return ret; 285cd82cca7SChristoph Hellwig } 286cd82cca7SChristoph Hellwig 28754a88eb8SPavel Begunkov static void blkdev_bio_end_io_async(struct bio *bio) 28854a88eb8SPavel Begunkov { 28954a88eb8SPavel Begunkov struct blkdev_dio *dio = container_of(bio, struct blkdev_dio, bio); 29054a88eb8SPavel Begunkov struct kiocb *iocb = dio->iocb; 29154a88eb8SPavel Begunkov ssize_t ret; 29254a88eb8SPavel Begunkov 293bb49c6faSStefano Garzarella WRITE_ONCE(iocb->private, NULL); 294bb49c6faSStefano Garzarella 29554a88eb8SPavel Begunkov if (likely(!bio->bi_status)) { 29654a88eb8SPavel Begunkov ret = dio->size; 29754a88eb8SPavel Begunkov iocb->ki_pos += ret; 29854a88eb8SPavel Begunkov } else { 29954a88eb8SPavel Begunkov ret = blk_status_to_errno(bio->bi_status); 30054a88eb8SPavel Begunkov } 30154a88eb8SPavel Begunkov 302*3d8b5a22SKanchan Joshi if (iocb->ki_flags & IOCB_HAS_METADATA) 303*3d8b5a22SKanchan Joshi bio_integrity_unmap_user(bio); 304*3d8b5a22SKanchan Joshi 305b6773cdbSLinus Torvalds iocb->ki_complete(iocb, ret); 30654a88eb8SPavel Begunkov 30754a88eb8SPavel Begunkov if (dio->flags & DIO_SHOULD_DIRTY) { 30854a88eb8SPavel Begunkov bio_check_pages_dirty(bio); 30954a88eb8SPavel Begunkov } else { 31054a88eb8SPavel Begunkov bio_release_pages(bio, false); 31154a88eb8SPavel Begunkov bio_put(bio); 31254a88eb8SPavel Begunkov } 31354a88eb8SPavel Begunkov } 31454a88eb8SPavel Begunkov 31554a88eb8SPavel Begunkov static ssize_t __blkdev_direct_IO_async(struct kiocb *iocb, 31654a88eb8SPavel Begunkov struct iov_iter *iter, 317de4c7befSJohn Garry struct block_device *bdev, 31854a88eb8SPavel Begunkov unsigned int nr_pages) 31954a88eb8SPavel Begunkov { 320b77c88c2SChristoph Hellwig bool is_read = iov_iter_rw(iter) == READ; 32116458cf3SBart Van Assche blk_opf_t opf = is_read ? REQ_OP_READ : dio_bio_write_op(iocb); 32254a88eb8SPavel Begunkov struct blkdev_dio *dio; 32354a88eb8SPavel Begunkov struct bio *bio; 32454a88eb8SPavel Begunkov loff_t pos = iocb->ki_pos; 32554a88eb8SPavel Begunkov int ret = 0; 32654a88eb8SPavel Begunkov 3270df71650SMike Snitzer if (iocb->ki_flags & IOCB_ALLOC_CACHE) 3280df71650SMike Snitzer opf |= REQ_ALLOC_CACHE; 3290df71650SMike Snitzer bio = bio_alloc_bioset(bdev, nr_pages, opf, GFP_KERNEL, 3300df71650SMike Snitzer &blkdev_dio_pool); 33154a88eb8SPavel Begunkov dio = container_of(bio, struct blkdev_dio, bio); 33254a88eb8SPavel Begunkov dio->flags = 0; 33354a88eb8SPavel Begunkov dio->iocb = iocb; 33454a88eb8SPavel Begunkov bio->bi_iter.bi_sector = pos >> SECTOR_SHIFT; 33544981351SBart Van Assche bio->bi_write_hint = file_inode(iocb->ki_filp)->i_write_hint; 33654a88eb8SPavel Begunkov bio->bi_end_io = blkdev_bio_end_io_async; 33754a88eb8SPavel Begunkov bio->bi_ioprio = iocb->ki_ioprio; 33854a88eb8SPavel Begunkov 3391bb6b810SPavel Begunkov if (iov_iter_is_bvec(iter)) { 3401bb6b810SPavel Begunkov /* 3411bb6b810SPavel Begunkov * Users don't rely on the iterator being in any particular 3421bb6b810SPavel Begunkov * state for async I/O returning -EIOCBQUEUED, hence we can 3431bb6b810SPavel Begunkov * avoid expensive iov_iter_advance(). Bypass 3441bb6b810SPavel Begunkov * bio_iov_iter_get_pages() and set the bvec directly. 3451bb6b810SPavel Begunkov */ 3461bb6b810SPavel Begunkov bio_iov_bvec_set(bio, iter); 3471bb6b810SPavel Begunkov } else { 34854a88eb8SPavel Begunkov ret = bio_iov_iter_get_pages(bio, iter); 349*3d8b5a22SKanchan Joshi if (unlikely(ret)) 350*3d8b5a22SKanchan Joshi goto out_bio_put; 3511bb6b810SPavel Begunkov } 35254a88eb8SPavel Begunkov dio->size = bio->bi_iter.bi_size; 35354a88eb8SPavel Begunkov 354b77c88c2SChristoph Hellwig if (is_read) { 355fcb14cb1SAl Viro if (user_backed_iter(iter)) { 35654a88eb8SPavel Begunkov dio->flags |= DIO_SHOULD_DIRTY; 35754a88eb8SPavel Begunkov bio_set_pages_dirty(bio); 35854a88eb8SPavel Begunkov } 35954a88eb8SPavel Begunkov } else { 36054a88eb8SPavel Begunkov task_io_account_write(bio->bi_iter.bi_size); 36154a88eb8SPavel Begunkov } 36254a88eb8SPavel Begunkov 363*3d8b5a22SKanchan Joshi if (iocb->ki_flags & IOCB_HAS_METADATA) { 364*3d8b5a22SKanchan Joshi ret = bio_integrity_map_iter(bio, iocb->private); 365*3d8b5a22SKanchan Joshi WRITE_ONCE(iocb->private, NULL); 366*3d8b5a22SKanchan Joshi if (unlikely(ret)) 367*3d8b5a22SKanchan Joshi goto out_bio_put; 368*3d8b5a22SKanchan Joshi } 369*3d8b5a22SKanchan Joshi 370caf336f8SJohn Garry if (iocb->ki_flags & IOCB_ATOMIC) 371caf336f8SJohn Garry bio->bi_opf |= REQ_ATOMIC; 372caf336f8SJohn Garry 3732bc05769SJens Axboe if (iocb->ki_flags & IOCB_NOWAIT) 3742bc05769SJens Axboe bio->bi_opf |= REQ_NOWAIT; 3752bc05769SJens Axboe 37654a88eb8SPavel Begunkov if (iocb->ki_flags & IOCB_HIPRI) { 3772bc05769SJens Axboe bio->bi_opf |= REQ_POLLED; 37854a88eb8SPavel Begunkov submit_bio(bio); 37954a88eb8SPavel Begunkov WRITE_ONCE(iocb->private, bio); 38054a88eb8SPavel Begunkov } else { 38154a88eb8SPavel Begunkov submit_bio(bio); 38254a88eb8SPavel Begunkov } 38354a88eb8SPavel Begunkov return -EIOCBQUEUED; 384*3d8b5a22SKanchan Joshi 385*3d8b5a22SKanchan Joshi out_bio_put: 386*3d8b5a22SKanchan Joshi bio_put(bio); 387*3d8b5a22SKanchan Joshi return ret; 38854a88eb8SPavel Begunkov } 38954a88eb8SPavel Begunkov 390cd82cca7SChristoph Hellwig static ssize_t blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter) 391cd82cca7SChristoph Hellwig { 392de4c7befSJohn Garry struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host); 393cd82cca7SChristoph Hellwig unsigned int nr_pages; 394cd82cca7SChristoph Hellwig 395cd82cca7SChristoph Hellwig if (!iov_iter_count(iter)) 396cd82cca7SChristoph Hellwig return 0; 397cd82cca7SChristoph Hellwig 398c3be7ebbSJohn Garry if (blkdev_dio_invalid(bdev, iocb, iter)) 399de4c7befSJohn Garry return -EINVAL; 400de4c7befSJohn Garry 401cd82cca7SChristoph Hellwig nr_pages = bio_iov_vecs_to_alloc(iter, BIO_MAX_VECS + 1); 40254a88eb8SPavel Begunkov if (likely(nr_pages <= BIO_MAX_VECS)) { 40354a88eb8SPavel Begunkov if (is_sync_kiocb(iocb)) 404de4c7befSJohn Garry return __blkdev_direct_IO_simple(iocb, iter, bdev, 405de4c7befSJohn Garry nr_pages); 406de4c7befSJohn Garry return __blkdev_direct_IO_async(iocb, iter, bdev, nr_pages); 407c3be7ebbSJohn Garry } else if (iocb->ki_flags & IOCB_ATOMIC) { 408caf336f8SJohn Garry return -EINVAL; 40954a88eb8SPavel Begunkov } 410de4c7befSJohn Garry return __blkdev_direct_IO(iocb, iter, bdev, bio_max_segs(nr_pages)); 411cd82cca7SChristoph Hellwig } 412cd82cca7SChristoph Hellwig 413487c607dSChristoph Hellwig static int blkdev_iomap_begin(struct inode *inode, loff_t offset, loff_t length, 414487c607dSChristoph Hellwig unsigned int flags, struct iomap *iomap, struct iomap *srcmap) 415487c607dSChristoph Hellwig { 416487c607dSChristoph Hellwig struct block_device *bdev = I_BDEV(inode); 417487c607dSChristoph Hellwig loff_t isize = i_size_read(inode); 418487c607dSChristoph Hellwig 4190c12028aSChristoph Hellwig if (offset >= isize) 420487c607dSChristoph Hellwig return -EIO; 421e269537eSLi Nan 422e269537eSLi Nan iomap->bdev = bdev; 423e269537eSLi Nan iomap->offset = ALIGN_DOWN(offset, bdev_logical_block_size(bdev)); 424487c607dSChristoph Hellwig iomap->type = IOMAP_MAPPED; 425487c607dSChristoph Hellwig iomap->addr = iomap->offset; 426487c607dSChristoph Hellwig iomap->length = isize - iomap->offset; 427925c86a1SChristoph Hellwig iomap->flags |= IOMAP_F_BUFFER_HEAD; /* noop for !CONFIG_BUFFER_HEAD */ 428487c607dSChristoph Hellwig return 0; 429487c607dSChristoph Hellwig } 430487c607dSChristoph Hellwig 431487c607dSChristoph Hellwig static const struct iomap_ops blkdev_iomap_ops = { 432487c607dSChristoph Hellwig .iomap_begin = blkdev_iomap_begin, 433487c607dSChristoph Hellwig }; 434487c607dSChristoph Hellwig 435925c86a1SChristoph Hellwig #ifdef CONFIG_BUFFER_HEAD 436925c86a1SChristoph Hellwig static int blkdev_get_block(struct inode *inode, sector_t iblock, 437925c86a1SChristoph Hellwig struct buffer_head *bh, int create) 438925c86a1SChristoph Hellwig { 439925c86a1SChristoph Hellwig bh->b_bdev = I_BDEV(inode); 440925c86a1SChristoph Hellwig bh->b_blocknr = iblock; 441925c86a1SChristoph Hellwig set_buffer_mapped(bh); 442925c86a1SChristoph Hellwig return 0; 443925c86a1SChristoph Hellwig } 444925c86a1SChristoph Hellwig 44517bf23a9SMatthew Wilcox (Oracle) /* 44617bf23a9SMatthew Wilcox (Oracle) * We cannot call mpage_writepages() as it does not take the buffer lock. 44717bf23a9SMatthew Wilcox (Oracle) * We must use block_write_full_folio() directly which holds the buffer 44817bf23a9SMatthew Wilcox (Oracle) * lock. The buffer lock provides the synchronisation with writeback 44917bf23a9SMatthew Wilcox (Oracle) * that filesystems rely on when they use the blockdev's mapping. 45017bf23a9SMatthew Wilcox (Oracle) */ 45117bf23a9SMatthew Wilcox (Oracle) static int blkdev_writepages(struct address_space *mapping, 45217bf23a9SMatthew Wilcox (Oracle) struct writeback_control *wbc) 453cd82cca7SChristoph Hellwig { 45417bf23a9SMatthew Wilcox (Oracle) struct blk_plug plug; 45517bf23a9SMatthew Wilcox (Oracle) int err; 45617bf23a9SMatthew Wilcox (Oracle) 45717bf23a9SMatthew Wilcox (Oracle) blk_start_plug(&plug); 45817bf23a9SMatthew Wilcox (Oracle) err = write_cache_pages(mapping, wbc, block_write_full_folio, 45917bf23a9SMatthew Wilcox (Oracle) blkdev_get_block); 46017bf23a9SMatthew Wilcox (Oracle) blk_finish_plug(&plug); 46117bf23a9SMatthew Wilcox (Oracle) 46217bf23a9SMatthew Wilcox (Oracle) return err; 463cd82cca7SChristoph Hellwig } 464cd82cca7SChristoph Hellwig 4652c69e205SMatthew Wilcox (Oracle) static int blkdev_read_folio(struct file *file, struct folio *folio) 466cd82cca7SChristoph Hellwig { 4672c69e205SMatthew Wilcox (Oracle) return block_read_full_folio(folio, blkdev_get_block); 468cd82cca7SChristoph Hellwig } 469cd82cca7SChristoph Hellwig 470cd82cca7SChristoph Hellwig static void blkdev_readahead(struct readahead_control *rac) 471cd82cca7SChristoph Hellwig { 472cd82cca7SChristoph Hellwig mpage_readahead(rac, blkdev_get_block); 473cd82cca7SChristoph Hellwig } 474cd82cca7SChristoph Hellwig 475cd82cca7SChristoph Hellwig static int blkdev_write_begin(struct file *file, struct address_space *mapping, 4761da86618SMatthew Wilcox (Oracle) loff_t pos, unsigned len, struct folio **foliop, void **fsdata) 477cd82cca7SChristoph Hellwig { 4781da86618SMatthew Wilcox (Oracle) return block_write_begin(mapping, pos, len, foliop, blkdev_get_block); 479cd82cca7SChristoph Hellwig } 480cd82cca7SChristoph Hellwig 481cd82cca7SChristoph Hellwig static int blkdev_write_end(struct file *file, struct address_space *mapping, 482a225800fSMatthew Wilcox (Oracle) loff_t pos, unsigned len, unsigned copied, struct folio *folio, 483cd82cca7SChristoph Hellwig void *fsdata) 484cd82cca7SChristoph Hellwig { 485cd82cca7SChristoph Hellwig int ret; 48697edbc02SMatthew Wilcox (Oracle) ret = block_write_end(file, mapping, pos, len, copied, folio, fsdata); 487cd82cca7SChristoph Hellwig 4881262249dSMatthew Wilcox (Oracle) folio_unlock(folio); 4891262249dSMatthew Wilcox (Oracle) folio_put(folio); 490cd82cca7SChristoph Hellwig 491cd82cca7SChristoph Hellwig return ret; 492cd82cca7SChristoph Hellwig } 493cd82cca7SChristoph Hellwig 494cd82cca7SChristoph Hellwig const struct address_space_operations def_blk_aops = { 495e621900aSMatthew Wilcox (Oracle) .dirty_folio = block_dirty_folio, 4967ba13abbSMatthew Wilcox (Oracle) .invalidate_folio = block_invalidate_folio, 4972c69e205SMatthew Wilcox (Oracle) .read_folio = blkdev_read_folio, 498cd82cca7SChristoph Hellwig .readahead = blkdev_readahead, 49917bf23a9SMatthew Wilcox (Oracle) .writepages = blkdev_writepages, 500cd82cca7SChristoph Hellwig .write_begin = blkdev_write_begin, 501cd82cca7SChristoph Hellwig .write_end = blkdev_write_end, 50267235182SMatthew Wilcox (Oracle) .migrate_folio = buffer_migrate_folio_norefs, 503cd82cca7SChristoph Hellwig .is_dirty_writeback = buffer_check_dirty_writeback, 504cd82cca7SChristoph Hellwig }; 505925c86a1SChristoph Hellwig #else /* CONFIG_BUFFER_HEAD */ 506925c86a1SChristoph Hellwig static int blkdev_read_folio(struct file *file, struct folio *folio) 507925c86a1SChristoph Hellwig { 508925c86a1SChristoph Hellwig return iomap_read_folio(folio, &blkdev_iomap_ops); 509925c86a1SChristoph Hellwig } 510925c86a1SChristoph Hellwig 511925c86a1SChristoph Hellwig static void blkdev_readahead(struct readahead_control *rac) 512925c86a1SChristoph Hellwig { 513925c86a1SChristoph Hellwig iomap_readahead(rac, &blkdev_iomap_ops); 514925c86a1SChristoph Hellwig } 515925c86a1SChristoph Hellwig 516925c86a1SChristoph Hellwig static int blkdev_map_blocks(struct iomap_writepage_ctx *wpc, 51719871b5cSChristoph Hellwig struct inode *inode, loff_t offset, unsigned int len) 518925c86a1SChristoph Hellwig { 519925c86a1SChristoph Hellwig loff_t isize = i_size_read(inode); 520925c86a1SChristoph Hellwig 521925c86a1SChristoph Hellwig if (WARN_ON_ONCE(offset >= isize)) 522925c86a1SChristoph Hellwig return -EIO; 523925c86a1SChristoph Hellwig if (offset >= wpc->iomap.offset && 524925c86a1SChristoph Hellwig offset < wpc->iomap.offset + wpc->iomap.length) 525925c86a1SChristoph Hellwig return 0; 526925c86a1SChristoph Hellwig return blkdev_iomap_begin(inode, offset, isize - offset, 527925c86a1SChristoph Hellwig IOMAP_WRITE, &wpc->iomap, NULL); 528925c86a1SChristoph Hellwig } 529925c86a1SChristoph Hellwig 530925c86a1SChristoph Hellwig static const struct iomap_writeback_ops blkdev_writeback_ops = { 531925c86a1SChristoph Hellwig .map_blocks = blkdev_map_blocks, 532925c86a1SChristoph Hellwig }; 533925c86a1SChristoph Hellwig 534925c86a1SChristoph Hellwig static int blkdev_writepages(struct address_space *mapping, 535925c86a1SChristoph Hellwig struct writeback_control *wbc) 536925c86a1SChristoph Hellwig { 537925c86a1SChristoph Hellwig struct iomap_writepage_ctx wpc = { }; 538925c86a1SChristoph Hellwig 539925c86a1SChristoph Hellwig return iomap_writepages(mapping, wbc, &wpc, &blkdev_writeback_ops); 540925c86a1SChristoph Hellwig } 541925c86a1SChristoph Hellwig 542925c86a1SChristoph Hellwig const struct address_space_operations def_blk_aops = { 543925c86a1SChristoph Hellwig .dirty_folio = filemap_dirty_folio, 544925c86a1SChristoph Hellwig .release_folio = iomap_release_folio, 545925c86a1SChristoph Hellwig .invalidate_folio = iomap_invalidate_folio, 546925c86a1SChristoph Hellwig .read_folio = blkdev_read_folio, 547925c86a1SChristoph Hellwig .readahead = blkdev_readahead, 548925c86a1SChristoph Hellwig .writepages = blkdev_writepages, 549925c86a1SChristoph Hellwig .is_partially_uptodate = iomap_is_partially_uptodate, 550af7628d6SMatthew Wilcox (Oracle) .error_remove_folio = generic_error_remove_folio, 551925c86a1SChristoph Hellwig .migrate_folio = filemap_migrate_folio, 552925c86a1SChristoph Hellwig }; 553925c86a1SChristoph Hellwig #endif /* CONFIG_BUFFER_HEAD */ 554cd82cca7SChristoph Hellwig 555cd82cca7SChristoph Hellwig /* 556cd82cca7SChristoph Hellwig * for a block special file file_inode(file)->i_size is zero 557cd82cca7SChristoph Hellwig * so we compute the size by hand (just as in block_read/write above) 558cd82cca7SChristoph Hellwig */ 559cd82cca7SChristoph Hellwig static loff_t blkdev_llseek(struct file *file, loff_t offset, int whence) 560cd82cca7SChristoph Hellwig { 561cd82cca7SChristoph Hellwig struct inode *bd_inode = bdev_file_inode(file); 562cd82cca7SChristoph Hellwig loff_t retval; 563cd82cca7SChristoph Hellwig 564cd82cca7SChristoph Hellwig inode_lock(bd_inode); 565cd82cca7SChristoph Hellwig retval = fixed_size_llseek(file, offset, whence, i_size_read(bd_inode)); 566cd82cca7SChristoph Hellwig inode_unlock(bd_inode); 567cd82cca7SChristoph Hellwig return retval; 568cd82cca7SChristoph Hellwig } 569cd82cca7SChristoph Hellwig 570cd82cca7SChristoph Hellwig static int blkdev_fsync(struct file *filp, loff_t start, loff_t end, 571cd82cca7SChristoph Hellwig int datasync) 572cd82cca7SChristoph Hellwig { 5734e762d86SChristoph Hellwig struct block_device *bdev = I_BDEV(filp->f_mapping->host); 574cd82cca7SChristoph Hellwig int error; 575cd82cca7SChristoph Hellwig 576cd82cca7SChristoph Hellwig error = file_write_and_wait_range(filp, start, end); 577cd82cca7SChristoph Hellwig if (error) 578cd82cca7SChristoph Hellwig return error; 579cd82cca7SChristoph Hellwig 580cd82cca7SChristoph Hellwig /* 581cd82cca7SChristoph Hellwig * There is no need to serialise calls to blkdev_issue_flush with 582cd82cca7SChristoph Hellwig * i_mutex and doing so causes performance issues with concurrent 583cd82cca7SChristoph Hellwig * O_SYNC writers to a block device. 584cd82cca7SChristoph Hellwig */ 585cd82cca7SChristoph Hellwig error = blkdev_issue_flush(bdev); 586cd82cca7SChristoph Hellwig if (error == -EOPNOTSUPP) 587cd82cca7SChristoph Hellwig error = 0; 588cd82cca7SChristoph Hellwig 589cd82cca7SChristoph Hellwig return error; 590cd82cca7SChristoph Hellwig } 591cd82cca7SChristoph Hellwig 592841dd789SJan Kara /** 593841dd789SJan Kara * file_to_blk_mode - get block open flags from file flags 594841dd789SJan Kara * @file: file whose open flags should be converted 595841dd789SJan Kara * 596841dd789SJan Kara * Look at file open flags and generate corresponding block open flags from 597841dd789SJan Kara * them. The function works both for file just being open (e.g. during ->open 598841dd789SJan Kara * callback) and for file that is already open. This is actually non-trivial 599841dd789SJan Kara * (see comment in the function). 600841dd789SJan Kara */ 60105bdb996SChristoph Hellwig blk_mode_t file_to_blk_mode(struct file *file) 60205bdb996SChristoph Hellwig { 60305bdb996SChristoph Hellwig blk_mode_t mode = 0; 60405bdb996SChristoph Hellwig 60505bdb996SChristoph Hellwig if (file->f_mode & FMODE_READ) 60605bdb996SChristoph Hellwig mode |= BLK_OPEN_READ; 60705bdb996SChristoph Hellwig if (file->f_mode & FMODE_WRITE) 60805bdb996SChristoph Hellwig mode |= BLK_OPEN_WRITE; 609841dd789SJan Kara /* 610ab838b3fSChristian Brauner * do_dentry_open() clears O_EXCL from f_flags, use file->private_data 611ab838b3fSChristian Brauner * to determine whether the open was exclusive for already open files. 612841dd789SJan Kara */ 613ab838b3fSChristian Brauner if (file->private_data) 614ab838b3fSChristian Brauner mode |= BLK_OPEN_EXCL; 615841dd789SJan Kara else if (file->f_flags & O_EXCL) 61605bdb996SChristoph Hellwig mode |= BLK_OPEN_EXCL; 61705bdb996SChristoph Hellwig if (file->f_flags & O_NDELAY) 61805bdb996SChristoph Hellwig mode |= BLK_OPEN_NDELAY; 61905bdb996SChristoph Hellwig 62005bdb996SChristoph Hellwig /* 62105bdb996SChristoph Hellwig * If all bits in O_ACCMODE set (aka O_RDWR | O_WRONLY), the floppy 62205bdb996SChristoph Hellwig * driver has historically allowed ioctls as if the file was opened for 62305bdb996SChristoph Hellwig * writing, but does not allow and actual reads or writes. 62405bdb996SChristoph Hellwig */ 62505bdb996SChristoph Hellwig if ((file->f_flags & O_ACCMODE) == (O_RDWR | O_WRONLY)) 62605bdb996SChristoph Hellwig mode |= BLK_OPEN_WRITE_IOCTL; 62705bdb996SChristoph Hellwig 62805bdb996SChristoph Hellwig return mode; 62905bdb996SChristoph Hellwig } 63005bdb996SChristoph Hellwig 631cd82cca7SChristoph Hellwig static int blkdev_open(struct inode *inode, struct file *filp) 632cd82cca7SChristoph Hellwig { 633a56aefcaSChristian Brauner struct block_device *bdev; 634841dd789SJan Kara blk_mode_t mode; 635a56aefcaSChristian Brauner int ret; 636cd82cca7SChristoph Hellwig 637841dd789SJan Kara mode = file_to_blk_mode(filp); 638ab838b3fSChristian Brauner /* Use the file as the holder. */ 639ab838b3fSChristian Brauner if (mode & BLK_OPEN_EXCL) 640ab838b3fSChristian Brauner filp->private_data = filp; 641ab838b3fSChristian Brauner ret = bdev_permission(inode->i_rdev, mode, filp->private_data); 642a56aefcaSChristian Brauner if (ret) 643a56aefcaSChristian Brauner return ret; 644cd82cca7SChristoph Hellwig 645a56aefcaSChristian Brauner bdev = blkdev_get_no_open(inode->i_rdev); 646a56aefcaSChristian Brauner if (!bdev) 647a56aefcaSChristian Brauner return -ENXIO; 648e9833d87SJens Axboe 649c3be7ebbSJohn Garry if (bdev_can_atomic_write(bdev)) 650caf336f8SJohn Garry filp->f_mode |= FMODE_CAN_ATOMIC_WRITE; 651caf336f8SJohn Garry 652ab838b3fSChristian Brauner ret = bdev_open(bdev, mode, filp->private_data, NULL, filp); 653a56aefcaSChristian Brauner if (ret) 654a56aefcaSChristian Brauner blkdev_put_no_open(bdev); 655a56aefcaSChristian Brauner return ret; 656cd82cca7SChristoph Hellwig } 657cd82cca7SChristoph Hellwig 6587ee34cbcSChristoph Hellwig static int blkdev_release(struct inode *inode, struct file *filp) 659cd82cca7SChristoph Hellwig { 6607c09a4edSChristian Brauner bdev_release(filp); 661cd82cca7SChristoph Hellwig return 0; 662cd82cca7SChristoph Hellwig } 663cd82cca7SChristoph Hellwig 664727cfe97SChristoph Hellwig static ssize_t 665727cfe97SChristoph Hellwig blkdev_direct_write(struct kiocb *iocb, struct iov_iter *from) 666727cfe97SChristoph Hellwig { 667727cfe97SChristoph Hellwig size_t count = iov_iter_count(from); 668727cfe97SChristoph Hellwig ssize_t written; 669727cfe97SChristoph Hellwig 670727cfe97SChristoph Hellwig written = kiocb_invalidate_pages(iocb, count); 671727cfe97SChristoph Hellwig if (written) { 672727cfe97SChristoph Hellwig if (written == -EBUSY) 673727cfe97SChristoph Hellwig return 0; 674727cfe97SChristoph Hellwig return written; 675727cfe97SChristoph Hellwig } 676727cfe97SChristoph Hellwig 677727cfe97SChristoph Hellwig written = blkdev_direct_IO(iocb, from); 678727cfe97SChristoph Hellwig if (written > 0) { 679727cfe97SChristoph Hellwig kiocb_invalidate_post_direct_write(iocb, count); 680727cfe97SChristoph Hellwig iocb->ki_pos += written; 681727cfe97SChristoph Hellwig count -= written; 682727cfe97SChristoph Hellwig } 683727cfe97SChristoph Hellwig if (written != -EIOCBQUEUED) 684727cfe97SChristoph Hellwig iov_iter_revert(from, count - iov_iter_count(from)); 685727cfe97SChristoph Hellwig return written; 686727cfe97SChristoph Hellwig } 687727cfe97SChristoph Hellwig 688487c607dSChristoph Hellwig static ssize_t blkdev_buffered_write(struct kiocb *iocb, struct iov_iter *from) 689487c607dSChristoph Hellwig { 69031754ea6SJosef Bacik return iomap_file_buffered_write(iocb, from, &blkdev_iomap_ops, NULL); 691487c607dSChristoph Hellwig } 692487c607dSChristoph Hellwig 693cd82cca7SChristoph Hellwig /* 694cd82cca7SChristoph Hellwig * Write data to the block device. Only intended for the block device itself 695cd82cca7SChristoph Hellwig * and the raw driver which basically is a fake block device. 696cd82cca7SChristoph Hellwig * 697cd82cca7SChristoph Hellwig * Does not take i_mutex for the write and thus is not for general purpose 698cd82cca7SChristoph Hellwig * use. 699cd82cca7SChristoph Hellwig */ 700cd82cca7SChristoph Hellwig static ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) 701cd82cca7SChristoph Hellwig { 702727cfe97SChristoph Hellwig struct file *file = iocb->ki_filp; 70339c3b4e7SAl Viro struct inode *bd_inode = bdev_file_inode(file); 70439c3b4e7SAl Viro struct block_device *bdev = I_BDEV(bd_inode); 7052cbd51f1SJohn Garry bool atomic = iocb->ki_flags & IOCB_ATOMIC; 706138c1a38SJens Axboe loff_t size = bdev_nr_bytes(bdev); 707cd82cca7SChristoph Hellwig size_t shorted = 0; 708cd82cca7SChristoph Hellwig ssize_t ret; 709cd82cca7SChristoph Hellwig 710fac7c6d5SPavel Begunkov if (bdev_read_only(bdev)) 711cd82cca7SChristoph Hellwig return -EPERM; 712cd82cca7SChristoph Hellwig 713cd82cca7SChristoph Hellwig if (IS_SWAPFILE(bd_inode) && !is_hibernate_resume_dev(bd_inode->i_rdev)) 714cd82cca7SChristoph Hellwig return -ETXTBSY; 715cd82cca7SChristoph Hellwig 716cd82cca7SChristoph Hellwig if (!iov_iter_count(from)) 717cd82cca7SChristoph Hellwig return 0; 718cd82cca7SChristoph Hellwig 719cd82cca7SChristoph Hellwig if (iocb->ki_pos >= size) 720cd82cca7SChristoph Hellwig return -ENOSPC; 721cd82cca7SChristoph Hellwig 722cd82cca7SChristoph Hellwig if ((iocb->ki_flags & (IOCB_NOWAIT | IOCB_DIRECT)) == IOCB_NOWAIT) 723cd82cca7SChristoph Hellwig return -EOPNOTSUPP; 724cd82cca7SChristoph Hellwig 7252cbd51f1SJohn Garry if (atomic) { 726c3be7ebbSJohn Garry ret = generic_atomic_write_valid(iocb, from); 727c3be7ebbSJohn Garry if (ret) 728c3be7ebbSJohn Garry return ret; 729c3be7ebbSJohn Garry } 730c3be7ebbSJohn Garry 731cd82cca7SChristoph Hellwig size -= iocb->ki_pos; 732cd82cca7SChristoph Hellwig if (iov_iter_count(from) > size) { 7332cbd51f1SJohn Garry if (atomic) 7342cbd51f1SJohn Garry return -EINVAL; 735cd82cca7SChristoph Hellwig shorted = iov_iter_count(from) - size; 736cd82cca7SChristoph Hellwig iov_iter_truncate(from, size); 737cd82cca7SChristoph Hellwig } 738cd82cca7SChristoph Hellwig 739727cfe97SChristoph Hellwig ret = file_update_time(file); 740727cfe97SChristoph Hellwig if (ret) 741727cfe97SChristoph Hellwig return ret; 742727cfe97SChristoph Hellwig 743727cfe97SChristoph Hellwig if (iocb->ki_flags & IOCB_DIRECT) { 744727cfe97SChristoph Hellwig ret = blkdev_direct_write(iocb, from); 745727cfe97SChristoph Hellwig if (ret >= 0 && iov_iter_count(from)) 746727cfe97SChristoph Hellwig ret = direct_write_fallback(iocb, from, ret, 747487c607dSChristoph Hellwig blkdev_buffered_write(iocb, from)); 748727cfe97SChristoph Hellwig } else { 749487c607dSChristoph Hellwig ret = blkdev_buffered_write(iocb, from); 750727cfe97SChristoph Hellwig } 751727cfe97SChristoph Hellwig 752cd82cca7SChristoph Hellwig if (ret > 0) 753cd82cca7SChristoph Hellwig ret = generic_write_sync(iocb, ret); 754cd82cca7SChristoph Hellwig iov_iter_reexpand(from, iov_iter_count(from) + shorted); 755cd82cca7SChristoph Hellwig return ret; 756cd82cca7SChristoph Hellwig } 757cd82cca7SChristoph Hellwig 758cd82cca7SChristoph Hellwig static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to) 759cd82cca7SChristoph Hellwig { 7604e762d86SChristoph Hellwig struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host); 761138c1a38SJens Axboe loff_t size = bdev_nr_bytes(bdev); 762cd82cca7SChristoph Hellwig loff_t pos = iocb->ki_pos; 763cd82cca7SChristoph Hellwig size_t shorted = 0; 764ceaa7625SJens Axboe ssize_t ret = 0; 7653e1f941dSIlya Dryomov size_t count; 766cd82cca7SChristoph Hellwig 7673e1f941dSIlya Dryomov if (unlikely(pos + iov_iter_count(to) > size)) { 768cd82cca7SChristoph Hellwig if (pos >= size) 769cd82cca7SChristoph Hellwig return 0; 770cd82cca7SChristoph Hellwig size -= pos; 7713e1f941dSIlya Dryomov shorted = iov_iter_count(to) - size; 772cd82cca7SChristoph Hellwig iov_iter_truncate(to, size); 773cd82cca7SChristoph Hellwig } 7743e1f941dSIlya Dryomov 7753e1f941dSIlya Dryomov count = iov_iter_count(to); 7763e1f941dSIlya Dryomov if (!count) 7773e1f941dSIlya Dryomov goto reexpand; /* skip atime */ 778cd82cca7SChristoph Hellwig 779ceaa7625SJens Axboe if (iocb->ki_flags & IOCB_DIRECT) { 7803c435a0fSChristoph Hellwig ret = kiocb_write_and_wait(iocb, count); 781ceaa7625SJens Axboe if (ret < 0) 7823e1f941dSIlya Dryomov goto reexpand; 783ceaa7625SJens Axboe file_accessed(iocb->ki_filp); 784ceaa7625SJens Axboe 785ceaa7625SJens Axboe ret = blkdev_direct_IO(iocb, to); 786ceaa7625SJens Axboe if (ret >= 0) { 787ceaa7625SJens Axboe iocb->ki_pos += ret; 788ceaa7625SJens Axboe count -= ret; 789ceaa7625SJens Axboe } 7903e1f941dSIlya Dryomov iov_iter_revert(to, count - iov_iter_count(to)); 791ceaa7625SJens Axboe if (ret < 0 || !count) 7923e1f941dSIlya Dryomov goto reexpand; 793ceaa7625SJens Axboe } 794ceaa7625SJens Axboe 795ceaa7625SJens Axboe ret = filemap_read(iocb, to, ret); 7966450fe1fSPavel Begunkov 7973e1f941dSIlya Dryomov reexpand: 7986450fe1fSPavel Begunkov if (unlikely(shorted)) 799cd82cca7SChristoph Hellwig iov_iter_reexpand(to, iov_iter_count(to) + shorted); 800cd82cca7SChristoph Hellwig return ret; 801cd82cca7SChristoph Hellwig } 802cd82cca7SChristoph Hellwig 803cd82cca7SChristoph Hellwig #define BLKDEV_FALLOC_FL_SUPPORTED \ 804cd82cca7SChristoph Hellwig (FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE | \ 805ad01dadaSChristoph Hellwig FALLOC_FL_ZERO_RANGE) 806cd82cca7SChristoph Hellwig 807cd82cca7SChristoph Hellwig static long blkdev_fallocate(struct file *file, int mode, loff_t start, 808cd82cca7SChristoph Hellwig loff_t len) 809cd82cca7SChristoph Hellwig { 810f278eb3dSMing Lei struct inode *inode = bdev_file_inode(file); 811f278eb3dSMing Lei struct block_device *bdev = I_BDEV(inode); 812cd82cca7SChristoph Hellwig loff_t end = start + len - 1; 813cd82cca7SChristoph Hellwig loff_t isize; 814cd82cca7SChristoph Hellwig int error; 815cd82cca7SChristoph Hellwig 816cd82cca7SChristoph Hellwig /* Fail if we don't recognize the flags. */ 817cd82cca7SChristoph Hellwig if (mode & ~BLKDEV_FALLOC_FL_SUPPORTED) 818cd82cca7SChristoph Hellwig return -EOPNOTSUPP; 819cd82cca7SChristoph Hellwig 820cd82cca7SChristoph Hellwig /* Don't go off the end of the device. */ 8212a93ad8fSChristoph Hellwig isize = bdev_nr_bytes(bdev); 822cd82cca7SChristoph Hellwig if (start >= isize) 823cd82cca7SChristoph Hellwig return -EINVAL; 824cd82cca7SChristoph Hellwig if (end >= isize) { 825cd82cca7SChristoph Hellwig if (mode & FALLOC_FL_KEEP_SIZE) { 826cd82cca7SChristoph Hellwig len = isize - start; 827cd82cca7SChristoph Hellwig end = start + len - 1; 828cd82cca7SChristoph Hellwig } else 829cd82cca7SChristoph Hellwig return -EINVAL; 830cd82cca7SChristoph Hellwig } 831cd82cca7SChristoph Hellwig 832cd82cca7SChristoph Hellwig /* 833cd82cca7SChristoph Hellwig * Don't allow IO that isn't aligned to logical block size. 834cd82cca7SChristoph Hellwig */ 835cd82cca7SChristoph Hellwig if ((start | len) & (bdev_logical_block_size(bdev) - 1)) 836cd82cca7SChristoph Hellwig return -EINVAL; 837cd82cca7SChristoph Hellwig 838f278eb3dSMing Lei filemap_invalidate_lock(inode->i_mapping); 839f278eb3dSMing Lei 8401364a3c3SSarthak Kukreti /* 8411364a3c3SSarthak Kukreti * Invalidate the page cache, including dirty pages, for valid 8421364a3c3SSarthak Kukreti * de-allocate mode calls to fallocate(). 8431364a3c3SSarthak Kukreti */ 8441364a3c3SSarthak Kukreti switch (mode) { 8451364a3c3SSarthak Kukreti case FALLOC_FL_ZERO_RANGE: 8461364a3c3SSarthak Kukreti case FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE: 84705bdb996SChristoph Hellwig error = truncate_bdev_range(bdev, file_to_blk_mode(file), start, end); 848cd82cca7SChristoph Hellwig if (error) 849f278eb3dSMing Lei goto fail; 850cd82cca7SChristoph Hellwig 8516549a874SPavel Begunkov error = blkdev_issue_zeroout(bdev, start >> SECTOR_SHIFT, 8526549a874SPavel Begunkov len >> SECTOR_SHIFT, GFP_KERNEL, 8536549a874SPavel Begunkov BLKDEV_ZERO_NOUNMAP); 854cd82cca7SChristoph Hellwig break; 855cd82cca7SChristoph Hellwig case FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE: 8561364a3c3SSarthak Kukreti error = truncate_bdev_range(bdev, file_to_blk_mode(file), start, end); 8571364a3c3SSarthak Kukreti if (error) 8581364a3c3SSarthak Kukreti goto fail; 8591364a3c3SSarthak Kukreti 8606549a874SPavel Begunkov error = blkdev_issue_zeroout(bdev, start >> SECTOR_SHIFT, 8616549a874SPavel Begunkov len >> SECTOR_SHIFT, GFP_KERNEL, 8626549a874SPavel Begunkov BLKDEV_ZERO_NOFALLBACK); 863cd82cca7SChristoph Hellwig break; 864cd82cca7SChristoph Hellwig default: 865f278eb3dSMing Lei error = -EOPNOTSUPP; 866cd82cca7SChristoph Hellwig } 867cd82cca7SChristoph Hellwig 868f278eb3dSMing Lei fail: 869f278eb3dSMing Lei filemap_invalidate_unlock(inode->i_mapping); 870f278eb3dSMing Lei return error; 871cd82cca7SChristoph Hellwig } 872cd82cca7SChristoph Hellwig 87369baa3a6SLoic Poulain static int blkdev_mmap(struct file *file, struct vm_area_struct *vma) 87469baa3a6SLoic Poulain { 87569baa3a6SLoic Poulain struct inode *bd_inode = bdev_file_inode(file); 87669baa3a6SLoic Poulain 87769baa3a6SLoic Poulain if (bdev_read_only(I_BDEV(bd_inode))) 87869baa3a6SLoic Poulain return generic_file_readonly_mmap(file, vma); 87969baa3a6SLoic Poulain 88069baa3a6SLoic Poulain return generic_file_mmap(file, vma); 88169baa3a6SLoic Poulain } 88269baa3a6SLoic Poulain 883cd82cca7SChristoph Hellwig const struct file_operations def_blk_fops = { 884cd82cca7SChristoph Hellwig .open = blkdev_open, 8857ee34cbcSChristoph Hellwig .release = blkdev_release, 886cd82cca7SChristoph Hellwig .llseek = blkdev_llseek, 887cd82cca7SChristoph Hellwig .read_iter = blkdev_read_iter, 888cd82cca7SChristoph Hellwig .write_iter = blkdev_write_iter, 8893e08773cSChristoph Hellwig .iopoll = iocb_bio_iopoll, 89069baa3a6SLoic Poulain .mmap = blkdev_mmap, 891cd82cca7SChristoph Hellwig .fsync = blkdev_fsync, 8928a709512SChristoph Hellwig .unlocked_ioctl = blkdev_ioctl, 893cd82cca7SChristoph Hellwig #ifdef CONFIG_COMPAT 894cd82cca7SChristoph Hellwig .compat_ioctl = compat_blkdev_ioctl, 895cd82cca7SChristoph Hellwig #endif 8962cb1e089SDavid Howells .splice_read = filemap_splice_read, 897cd82cca7SChristoph Hellwig .splice_write = iter_file_splice_write, 898cd82cca7SChristoph Hellwig .fallocate = blkdev_fallocate, 89950c52250SPavel Begunkov .uring_cmd = blkdev_uring_cmd, 900210a03c9SChristian Brauner .fop_flags = FOP_BUFFER_RASYNC, 901cd82cca7SChristoph Hellwig }; 902cd82cca7SChristoph Hellwig 903cd82cca7SChristoph Hellwig static __init int blkdev_init(void) 904cd82cca7SChristoph Hellwig { 905cd82cca7SChristoph Hellwig return bioset_init(&blkdev_dio_pool, 4, 906cd82cca7SChristoph Hellwig offsetof(struct blkdev_dio, bio), 907cd82cca7SChristoph Hellwig BIOSET_NEED_BVECS|BIOSET_PERCPU_CACHE); 908cd82cca7SChristoph Hellwig } 909cd82cca7SChristoph Hellwig module_init(blkdev_init); 910