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> 18*487c607dSChristoph Hellwig #include <linux/iomap.h> 198581fd40SJakub Kicinski #include <linux/module.h> 20cd82cca7SChristoph Hellwig #include "blk.h" 21cd82cca7SChristoph Hellwig 22fac7c6d5SPavel Begunkov static inline struct inode *bdev_file_inode(struct file *file) 23cd82cca7SChristoph Hellwig { 24cd82cca7SChristoph Hellwig return file->f_mapping->host; 25cd82cca7SChristoph Hellwig } 26cd82cca7SChristoph Hellwig 27cd82cca7SChristoph Hellwig static int blkdev_get_block(struct inode *inode, sector_t iblock, 28cd82cca7SChristoph Hellwig struct buffer_head *bh, int create) 29cd82cca7SChristoph Hellwig { 30cd82cca7SChristoph Hellwig bh->b_bdev = I_BDEV(inode); 31cd82cca7SChristoph Hellwig bh->b_blocknr = iblock; 32cd82cca7SChristoph Hellwig set_buffer_mapped(bh); 33cd82cca7SChristoph Hellwig return 0; 34cd82cca7SChristoph Hellwig } 35cd82cca7SChristoph Hellwig 3616458cf3SBart Van Assche static blk_opf_t dio_bio_write_op(struct kiocb *iocb) 37cd82cca7SChristoph Hellwig { 3816458cf3SBart Van Assche blk_opf_t opf = REQ_OP_WRITE | REQ_SYNC | REQ_IDLE; 39cd82cca7SChristoph Hellwig 40cd82cca7SChristoph Hellwig /* avoid the need for a I/O completion work item */ 4191b94c5dSAl Viro if (iocb_is_dsync(iocb)) 4216458cf3SBart Van Assche opf |= REQ_FUA; 4316458cf3SBart Van Assche return opf; 44cd82cca7SChristoph Hellwig } 45cd82cca7SChristoph Hellwig 4637fee2e4SKeith Busch static bool blkdev_dio_unaligned(struct block_device *bdev, loff_t pos, 4737fee2e4SKeith Busch struct iov_iter *iter) 4837fee2e4SKeith Busch { 49b1a000d3SKeith Busch return pos & (bdev_logical_block_size(bdev) - 1) || 50b1a000d3SKeith Busch !bdev_iter_is_aligned(bdev, iter); 5137fee2e4SKeith Busch } 5237fee2e4SKeith Busch 53cd82cca7SChristoph Hellwig #define DIO_INLINE_BIO_VECS 4 54cd82cca7SChristoph Hellwig 55cd82cca7SChristoph Hellwig static ssize_t __blkdev_direct_IO_simple(struct kiocb *iocb, 56cd82cca7SChristoph Hellwig struct iov_iter *iter, unsigned int nr_pages) 57cd82cca7SChristoph Hellwig { 584e762d86SChristoph Hellwig struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host); 59cd82cca7SChristoph Hellwig struct bio_vec inline_vecs[DIO_INLINE_BIO_VECS], *vecs; 60cd82cca7SChristoph Hellwig loff_t pos = iocb->ki_pos; 61cd82cca7SChristoph Hellwig bool should_dirty = false; 62cd82cca7SChristoph Hellwig struct bio bio; 63cd82cca7SChristoph Hellwig ssize_t ret; 64cd82cca7SChristoph Hellwig 6537fee2e4SKeith Busch if (blkdev_dio_unaligned(bdev, pos, iter)) 66cd82cca7SChristoph Hellwig return -EINVAL; 67cd82cca7SChristoph Hellwig 68cd82cca7SChristoph Hellwig if (nr_pages <= DIO_INLINE_BIO_VECS) 69cd82cca7SChristoph Hellwig vecs = inline_vecs; 70cd82cca7SChristoph Hellwig else { 71cd82cca7SChristoph Hellwig vecs = kmalloc_array(nr_pages, sizeof(struct bio_vec), 72cd82cca7SChristoph Hellwig GFP_KERNEL); 73cd82cca7SChristoph Hellwig if (!vecs) 74cd82cca7SChristoph Hellwig return -ENOMEM; 75cd82cca7SChristoph Hellwig } 76cd82cca7SChristoph Hellwig 7749add496SChristoph Hellwig if (iov_iter_rw(iter) == READ) { 7849add496SChristoph Hellwig bio_init(&bio, bdev, vecs, nr_pages, REQ_OP_READ); 79fcb14cb1SAl Viro if (user_backed_iter(iter)) 8049add496SChristoph Hellwig should_dirty = true; 8149add496SChristoph Hellwig } else { 8249add496SChristoph Hellwig bio_init(&bio, bdev, vecs, nr_pages, dio_bio_write_op(iocb)); 8349add496SChristoph Hellwig } 846549a874SPavel Begunkov bio.bi_iter.bi_sector = pos >> SECTOR_SHIFT; 85cd82cca7SChristoph Hellwig bio.bi_ioprio = iocb->ki_ioprio; 86cd82cca7SChristoph Hellwig 87cd82cca7SChristoph Hellwig ret = bio_iov_iter_get_pages(&bio, iter); 88cd82cca7SChristoph Hellwig if (unlikely(ret)) 89cd82cca7SChristoph Hellwig goto out; 90cd82cca7SChristoph Hellwig ret = bio.bi_iter.bi_size; 91cd82cca7SChristoph Hellwig 9249add496SChristoph Hellwig if (iov_iter_rw(iter) == WRITE) 93cd82cca7SChristoph Hellwig task_io_account_write(ret); 9449add496SChristoph Hellwig 95cd82cca7SChristoph Hellwig if (iocb->ki_flags & IOCB_NOWAIT) 96cd82cca7SChristoph Hellwig bio.bi_opf |= REQ_NOWAIT; 97cd82cca7SChristoph Hellwig 989650b453SMing Lei submit_bio_wait(&bio); 99cd82cca7SChristoph Hellwig 100cd82cca7SChristoph Hellwig bio_release_pages(&bio, should_dirty); 101cd82cca7SChristoph Hellwig if (unlikely(bio.bi_status)) 102cd82cca7SChristoph Hellwig ret = blk_status_to_errno(bio.bi_status); 103cd82cca7SChristoph Hellwig 104cd82cca7SChristoph Hellwig out: 105cd82cca7SChristoph Hellwig if (vecs != inline_vecs) 106cd82cca7SChristoph Hellwig kfree(vecs); 107cd82cca7SChristoph Hellwig 108cd82cca7SChristoph Hellwig bio_uninit(&bio); 109cd82cca7SChristoph Hellwig 110cd82cca7SChristoph Hellwig return ret; 111cd82cca7SChristoph Hellwig } 112cd82cca7SChristoph Hellwig 11309ce8744SJens Axboe enum { 114e71aa913SPavel Begunkov DIO_SHOULD_DIRTY = 1, 115e71aa913SPavel Begunkov DIO_IS_SYNC = 2, 11609ce8744SJens Axboe }; 11709ce8744SJens Axboe 118cd82cca7SChristoph Hellwig struct blkdev_dio { 119cd82cca7SChristoph Hellwig union { 120cd82cca7SChristoph Hellwig struct kiocb *iocb; 121cd82cca7SChristoph Hellwig struct task_struct *waiter; 122cd82cca7SChristoph Hellwig }; 123cd82cca7SChristoph Hellwig size_t size; 124cd82cca7SChristoph Hellwig atomic_t ref; 12509ce8744SJens Axboe unsigned int flags; 1266155631aSJens Axboe struct bio bio ____cacheline_aligned_in_smp; 127cd82cca7SChristoph Hellwig }; 128cd82cca7SChristoph Hellwig 129cd82cca7SChristoph Hellwig static struct bio_set blkdev_dio_pool; 130cd82cca7SChristoph Hellwig 131cd82cca7SChristoph Hellwig static void blkdev_bio_end_io(struct bio *bio) 132cd82cca7SChristoph Hellwig { 133cd82cca7SChristoph Hellwig struct blkdev_dio *dio = bio->bi_private; 13409ce8744SJens Axboe bool should_dirty = dio->flags & DIO_SHOULD_DIRTY; 135cd82cca7SChristoph Hellwig 136cd82cca7SChristoph Hellwig if (bio->bi_status && !dio->bio.bi_status) 137cd82cca7SChristoph Hellwig dio->bio.bi_status = bio->bi_status; 138cd82cca7SChristoph Hellwig 139e71aa913SPavel Begunkov if (atomic_dec_and_test(&dio->ref)) { 14009ce8744SJens Axboe if (!(dio->flags & DIO_IS_SYNC)) { 141cd82cca7SChristoph Hellwig struct kiocb *iocb = dio->iocb; 142cd82cca7SChristoph Hellwig ssize_t ret; 143cd82cca7SChristoph Hellwig 1443e08773cSChristoph Hellwig WRITE_ONCE(iocb->private, NULL); 1453e08773cSChristoph Hellwig 146cd82cca7SChristoph Hellwig if (likely(!dio->bio.bi_status)) { 147cd82cca7SChristoph Hellwig ret = dio->size; 148cd82cca7SChristoph Hellwig iocb->ki_pos += ret; 149cd82cca7SChristoph Hellwig } else { 150cd82cca7SChristoph Hellwig ret = blk_status_to_errno(dio->bio.bi_status); 151cd82cca7SChristoph Hellwig } 152cd82cca7SChristoph Hellwig 1536b19b766SJens Axboe dio->iocb->ki_complete(iocb, ret); 154cd82cca7SChristoph Hellwig bio_put(&dio->bio); 155cd82cca7SChristoph Hellwig } else { 156cd82cca7SChristoph Hellwig struct task_struct *waiter = dio->waiter; 157cd82cca7SChristoph Hellwig 158cd82cca7SChristoph Hellwig WRITE_ONCE(dio->waiter, NULL); 159cd82cca7SChristoph Hellwig blk_wake_io_task(waiter); 160cd82cca7SChristoph Hellwig } 161cd82cca7SChristoph Hellwig } 162cd82cca7SChristoph Hellwig 163cd82cca7SChristoph Hellwig if (should_dirty) { 164cd82cca7SChristoph Hellwig bio_check_pages_dirty(bio); 165cd82cca7SChristoph Hellwig } else { 166cd82cca7SChristoph Hellwig bio_release_pages(bio, false); 167cd82cca7SChristoph Hellwig bio_put(bio); 168cd82cca7SChristoph Hellwig } 169cd82cca7SChristoph Hellwig } 170cd82cca7SChristoph Hellwig 171cd82cca7SChristoph Hellwig static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, 172cd82cca7SChristoph Hellwig unsigned int nr_pages) 173cd82cca7SChristoph Hellwig { 1744e762d86SChristoph Hellwig struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host); 175cd82cca7SChristoph Hellwig struct blk_plug plug; 176cd82cca7SChristoph Hellwig struct blkdev_dio *dio; 177cd82cca7SChristoph Hellwig struct bio *bio; 178cd82cca7SChristoph Hellwig bool is_read = (iov_iter_rw(iter) == READ), is_sync; 17916458cf3SBart Van Assche blk_opf_t opf = is_read ? REQ_OP_READ : dio_bio_write_op(iocb); 180cd82cca7SChristoph Hellwig loff_t pos = iocb->ki_pos; 181cd82cca7SChristoph Hellwig int ret = 0; 182cd82cca7SChristoph Hellwig 18337fee2e4SKeith Busch if (blkdev_dio_unaligned(bdev, pos, iter)) 184cd82cca7SChristoph Hellwig return -EINVAL; 185cd82cca7SChristoph Hellwig 1860df71650SMike Snitzer if (iocb->ki_flags & IOCB_ALLOC_CACHE) 1870df71650SMike Snitzer opf |= REQ_ALLOC_CACHE; 1880df71650SMike Snitzer bio = bio_alloc_bioset(bdev, nr_pages, opf, GFP_KERNEL, 1890df71650SMike Snitzer &blkdev_dio_pool); 190cd82cca7SChristoph Hellwig dio = container_of(bio, struct blkdev_dio, bio); 191e71aa913SPavel Begunkov atomic_set(&dio->ref, 1); 192e71aa913SPavel Begunkov /* 193e71aa913SPavel Begunkov * Grab an extra reference to ensure the dio structure which is embedded 194e71aa913SPavel Begunkov * into the first bio stays around. 195e71aa913SPavel Begunkov */ 196e71aa913SPavel Begunkov bio_get(bio); 197e71aa913SPavel Begunkov 19809ce8744SJens Axboe is_sync = is_sync_kiocb(iocb); 19909ce8744SJens Axboe if (is_sync) { 20009ce8744SJens Axboe dio->flags = DIO_IS_SYNC; 201cd82cca7SChristoph Hellwig dio->waiter = current; 202cd82cca7SChristoph Hellwig } else { 20309ce8744SJens Axboe dio->flags = 0; 204cd82cca7SChristoph Hellwig dio->iocb = iocb; 205cd82cca7SChristoph Hellwig } 206cd82cca7SChristoph Hellwig 207cd82cca7SChristoph Hellwig dio->size = 0; 208fcb14cb1SAl Viro if (is_read && user_backed_iter(iter)) 20909ce8744SJens Axboe dio->flags |= DIO_SHOULD_DIRTY; 210cd82cca7SChristoph Hellwig 211cd82cca7SChristoph Hellwig blk_start_plug(&plug); 212cd82cca7SChristoph Hellwig 213cd82cca7SChristoph Hellwig for (;;) { 2146549a874SPavel Begunkov bio->bi_iter.bi_sector = pos >> SECTOR_SHIFT; 215cd82cca7SChristoph Hellwig bio->bi_private = dio; 216cd82cca7SChristoph Hellwig bio->bi_end_io = blkdev_bio_end_io; 217cd82cca7SChristoph Hellwig bio->bi_ioprio = iocb->ki_ioprio; 218cd82cca7SChristoph Hellwig 219cd82cca7SChristoph Hellwig ret = bio_iov_iter_get_pages(bio, iter); 220cd82cca7SChristoph Hellwig if (unlikely(ret)) { 221cd82cca7SChristoph Hellwig bio->bi_status = BLK_STS_IOERR; 222cd82cca7SChristoph Hellwig bio_endio(bio); 223cd82cca7SChristoph Hellwig break; 224cd82cca7SChristoph Hellwig } 22567d59247SJens Axboe if (iocb->ki_flags & IOCB_NOWAIT) { 22667d59247SJens Axboe /* 22767d59247SJens Axboe * This is nonblocking IO, and we need to allocate 22867d59247SJens Axboe * another bio if we have data left to map. As we 22967d59247SJens Axboe * cannot guarantee that one of the sub bios will not 23067d59247SJens Axboe * fail getting issued FOR NOWAIT and as error results 23167d59247SJens Axboe * are coalesced across all of them, be safe and ask for 23267d59247SJens Axboe * a retry of this from blocking context. 23367d59247SJens Axboe */ 23467d59247SJens Axboe if (unlikely(iov_iter_count(iter))) { 23567d59247SJens Axboe bio_release_pages(bio, false); 23667d59247SJens Axboe bio_clear_flag(bio, BIO_REFFED); 23767d59247SJens Axboe bio_put(bio); 23867d59247SJens Axboe blk_finish_plug(&plug); 23967d59247SJens Axboe return -EAGAIN; 24067d59247SJens Axboe } 24167d59247SJens Axboe bio->bi_opf |= REQ_NOWAIT; 24267d59247SJens Axboe } 243cd82cca7SChristoph Hellwig 244cd82cca7SChristoph Hellwig if (is_read) { 24509ce8744SJens Axboe if (dio->flags & DIO_SHOULD_DIRTY) 246cd82cca7SChristoph Hellwig bio_set_pages_dirty(bio); 247cd82cca7SChristoph Hellwig } else { 248cd82cca7SChristoph Hellwig task_io_account_write(bio->bi_iter.bi_size); 249cd82cca7SChristoph Hellwig } 250cd82cca7SChristoph Hellwig dio->size += bio->bi_iter.bi_size; 251cd82cca7SChristoph Hellwig pos += bio->bi_iter.bi_size; 252cd82cca7SChristoph Hellwig 253cd82cca7SChristoph Hellwig nr_pages = bio_iov_vecs_to_alloc(iter, BIO_MAX_VECS); 254cd82cca7SChristoph Hellwig if (!nr_pages) { 2553e08773cSChristoph Hellwig submit_bio(bio); 256cd82cca7SChristoph Hellwig break; 257cd82cca7SChristoph Hellwig } 258cd82cca7SChristoph Hellwig atomic_inc(&dio->ref); 259cd82cca7SChristoph Hellwig submit_bio(bio); 26007888c66SChristoph Hellwig bio = bio_alloc(bdev, nr_pages, opf, GFP_KERNEL); 261cd82cca7SChristoph Hellwig } 262cd82cca7SChristoph Hellwig 263cd82cca7SChristoph Hellwig blk_finish_plug(&plug); 264cd82cca7SChristoph Hellwig 265cd82cca7SChristoph Hellwig if (!is_sync) 266cd82cca7SChristoph Hellwig return -EIOCBQUEUED; 267cd82cca7SChristoph Hellwig 268cd82cca7SChristoph Hellwig for (;;) { 269cd82cca7SChristoph Hellwig set_current_state(TASK_UNINTERRUPTIBLE); 270cd82cca7SChristoph Hellwig if (!READ_ONCE(dio->waiter)) 271cd82cca7SChristoph Hellwig break; 272cd82cca7SChristoph Hellwig blk_io_schedule(); 273cd82cca7SChristoph Hellwig } 274cd82cca7SChristoph Hellwig __set_current_state(TASK_RUNNING); 275cd82cca7SChristoph Hellwig 276cd82cca7SChristoph Hellwig if (!ret) 277cd82cca7SChristoph Hellwig ret = blk_status_to_errno(dio->bio.bi_status); 278cd82cca7SChristoph Hellwig if (likely(!ret)) 279cd82cca7SChristoph Hellwig ret = dio->size; 280cd82cca7SChristoph Hellwig 281cd82cca7SChristoph Hellwig bio_put(&dio->bio); 282cd82cca7SChristoph Hellwig return ret; 283cd82cca7SChristoph Hellwig } 284cd82cca7SChristoph Hellwig 28554a88eb8SPavel Begunkov static void blkdev_bio_end_io_async(struct bio *bio) 28654a88eb8SPavel Begunkov { 28754a88eb8SPavel Begunkov struct blkdev_dio *dio = container_of(bio, struct blkdev_dio, bio); 28854a88eb8SPavel Begunkov struct kiocb *iocb = dio->iocb; 28954a88eb8SPavel Begunkov ssize_t ret; 29054a88eb8SPavel Begunkov 291bb49c6faSStefano Garzarella WRITE_ONCE(iocb->private, NULL); 292bb49c6faSStefano Garzarella 29354a88eb8SPavel Begunkov if (likely(!bio->bi_status)) { 29454a88eb8SPavel Begunkov ret = dio->size; 29554a88eb8SPavel Begunkov iocb->ki_pos += ret; 29654a88eb8SPavel Begunkov } else { 29754a88eb8SPavel Begunkov ret = blk_status_to_errno(bio->bi_status); 29854a88eb8SPavel Begunkov } 29954a88eb8SPavel Begunkov 300b6773cdbSLinus Torvalds iocb->ki_complete(iocb, ret); 30154a88eb8SPavel Begunkov 30254a88eb8SPavel Begunkov if (dio->flags & DIO_SHOULD_DIRTY) { 30354a88eb8SPavel Begunkov bio_check_pages_dirty(bio); 30454a88eb8SPavel Begunkov } else { 30554a88eb8SPavel Begunkov bio_release_pages(bio, false); 30654a88eb8SPavel Begunkov bio_put(bio); 30754a88eb8SPavel Begunkov } 30854a88eb8SPavel Begunkov } 30954a88eb8SPavel Begunkov 31054a88eb8SPavel Begunkov static ssize_t __blkdev_direct_IO_async(struct kiocb *iocb, 31154a88eb8SPavel Begunkov struct iov_iter *iter, 31254a88eb8SPavel Begunkov unsigned int nr_pages) 31354a88eb8SPavel Begunkov { 3144e762d86SChristoph Hellwig struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host); 315b77c88c2SChristoph Hellwig bool is_read = iov_iter_rw(iter) == READ; 31616458cf3SBart Van Assche blk_opf_t opf = is_read ? REQ_OP_READ : dio_bio_write_op(iocb); 31754a88eb8SPavel Begunkov struct blkdev_dio *dio; 31854a88eb8SPavel Begunkov struct bio *bio; 31954a88eb8SPavel Begunkov loff_t pos = iocb->ki_pos; 32054a88eb8SPavel Begunkov int ret = 0; 32154a88eb8SPavel Begunkov 32237fee2e4SKeith Busch if (blkdev_dio_unaligned(bdev, pos, iter)) 32354a88eb8SPavel Begunkov return -EINVAL; 32454a88eb8SPavel Begunkov 3250df71650SMike Snitzer if (iocb->ki_flags & IOCB_ALLOC_CACHE) 3260df71650SMike Snitzer opf |= REQ_ALLOC_CACHE; 3270df71650SMike Snitzer bio = bio_alloc_bioset(bdev, nr_pages, opf, GFP_KERNEL, 3280df71650SMike Snitzer &blkdev_dio_pool); 32954a88eb8SPavel Begunkov dio = container_of(bio, struct blkdev_dio, bio); 33054a88eb8SPavel Begunkov dio->flags = 0; 33154a88eb8SPavel Begunkov dio->iocb = iocb; 33254a88eb8SPavel Begunkov bio->bi_iter.bi_sector = pos >> SECTOR_SHIFT; 33354a88eb8SPavel Begunkov bio->bi_end_io = blkdev_bio_end_io_async; 33454a88eb8SPavel Begunkov bio->bi_ioprio = iocb->ki_ioprio; 33554a88eb8SPavel Begunkov 3361bb6b810SPavel Begunkov if (iov_iter_is_bvec(iter)) { 3371bb6b810SPavel Begunkov /* 3381bb6b810SPavel Begunkov * Users don't rely on the iterator being in any particular 3391bb6b810SPavel Begunkov * state for async I/O returning -EIOCBQUEUED, hence we can 3401bb6b810SPavel Begunkov * avoid expensive iov_iter_advance(). Bypass 3411bb6b810SPavel Begunkov * bio_iov_iter_get_pages() and set the bvec directly. 3421bb6b810SPavel Begunkov */ 3431bb6b810SPavel Begunkov bio_iov_bvec_set(bio, iter); 3441bb6b810SPavel Begunkov } else { 34554a88eb8SPavel Begunkov ret = bio_iov_iter_get_pages(bio, iter); 34654a88eb8SPavel Begunkov if (unlikely(ret)) { 34775feae73SPavel Begunkov bio_put(bio); 34854a88eb8SPavel Begunkov return ret; 34954a88eb8SPavel Begunkov } 3501bb6b810SPavel Begunkov } 35154a88eb8SPavel Begunkov dio->size = bio->bi_iter.bi_size; 35254a88eb8SPavel Begunkov 353b77c88c2SChristoph Hellwig if (is_read) { 354fcb14cb1SAl Viro if (user_backed_iter(iter)) { 35554a88eb8SPavel Begunkov dio->flags |= DIO_SHOULD_DIRTY; 35654a88eb8SPavel Begunkov bio_set_pages_dirty(bio); 35754a88eb8SPavel Begunkov } 35854a88eb8SPavel Begunkov } else { 35954a88eb8SPavel Begunkov task_io_account_write(bio->bi_iter.bi_size); 36054a88eb8SPavel Begunkov } 36154a88eb8SPavel Begunkov 36254a88eb8SPavel Begunkov if (iocb->ki_flags & IOCB_HIPRI) { 363842e39b0SPavel Begunkov bio->bi_opf |= REQ_POLLED | REQ_NOWAIT; 36454a88eb8SPavel Begunkov submit_bio(bio); 36554a88eb8SPavel Begunkov WRITE_ONCE(iocb->private, bio); 36654a88eb8SPavel Begunkov } else { 367842e39b0SPavel Begunkov if (iocb->ki_flags & IOCB_NOWAIT) 368842e39b0SPavel Begunkov bio->bi_opf |= REQ_NOWAIT; 36954a88eb8SPavel Begunkov submit_bio(bio); 37054a88eb8SPavel Begunkov } 37154a88eb8SPavel Begunkov return -EIOCBQUEUED; 37254a88eb8SPavel Begunkov } 37354a88eb8SPavel Begunkov 374cd82cca7SChristoph Hellwig static ssize_t blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter) 375cd82cca7SChristoph Hellwig { 376cd82cca7SChristoph Hellwig unsigned int nr_pages; 377cd82cca7SChristoph Hellwig 378cd82cca7SChristoph Hellwig if (!iov_iter_count(iter)) 379cd82cca7SChristoph Hellwig return 0; 380cd82cca7SChristoph Hellwig 381cd82cca7SChristoph Hellwig nr_pages = bio_iov_vecs_to_alloc(iter, BIO_MAX_VECS + 1); 38254a88eb8SPavel Begunkov if (likely(nr_pages <= BIO_MAX_VECS)) { 38354a88eb8SPavel Begunkov if (is_sync_kiocb(iocb)) 384cd82cca7SChristoph Hellwig return __blkdev_direct_IO_simple(iocb, iter, nr_pages); 38554a88eb8SPavel Begunkov return __blkdev_direct_IO_async(iocb, iter, nr_pages); 38654a88eb8SPavel Begunkov } 387cd82cca7SChristoph Hellwig return __blkdev_direct_IO(iocb, iter, bio_max_segs(nr_pages)); 388cd82cca7SChristoph Hellwig } 389cd82cca7SChristoph Hellwig 390*487c607dSChristoph Hellwig static int blkdev_iomap_begin(struct inode *inode, loff_t offset, loff_t length, 391*487c607dSChristoph Hellwig unsigned int flags, struct iomap *iomap, struct iomap *srcmap) 392*487c607dSChristoph Hellwig { 393*487c607dSChristoph Hellwig struct block_device *bdev = I_BDEV(inode); 394*487c607dSChristoph Hellwig loff_t isize = i_size_read(inode); 395*487c607dSChristoph Hellwig 396*487c607dSChristoph Hellwig iomap->bdev = bdev; 397*487c607dSChristoph Hellwig iomap->offset = ALIGN_DOWN(offset, bdev_logical_block_size(bdev)); 398*487c607dSChristoph Hellwig if (iomap->offset >= isize) 399*487c607dSChristoph Hellwig return -EIO; 400*487c607dSChristoph Hellwig iomap->type = IOMAP_MAPPED; 401*487c607dSChristoph Hellwig iomap->addr = iomap->offset; 402*487c607dSChristoph Hellwig iomap->length = isize - iomap->offset; 403*487c607dSChristoph Hellwig iomap->flags |= IOMAP_F_BUFFER_HEAD; 404*487c607dSChristoph Hellwig return 0; 405*487c607dSChristoph Hellwig } 406*487c607dSChristoph Hellwig 407*487c607dSChristoph Hellwig static const struct iomap_ops blkdev_iomap_ops = { 408*487c607dSChristoph Hellwig .iomap_begin = blkdev_iomap_begin, 409*487c607dSChristoph Hellwig }; 410*487c607dSChristoph Hellwig 411cd82cca7SChristoph Hellwig static int blkdev_writepage(struct page *page, struct writeback_control *wbc) 412cd82cca7SChristoph Hellwig { 413cd82cca7SChristoph Hellwig return block_write_full_page(page, blkdev_get_block, wbc); 414cd82cca7SChristoph Hellwig } 415cd82cca7SChristoph Hellwig 4162c69e205SMatthew Wilcox (Oracle) static int blkdev_read_folio(struct file *file, struct folio *folio) 417cd82cca7SChristoph Hellwig { 4182c69e205SMatthew Wilcox (Oracle) return block_read_full_folio(folio, blkdev_get_block); 419cd82cca7SChristoph Hellwig } 420cd82cca7SChristoph Hellwig 421cd82cca7SChristoph Hellwig static void blkdev_readahead(struct readahead_control *rac) 422cd82cca7SChristoph Hellwig { 423cd82cca7SChristoph Hellwig mpage_readahead(rac, blkdev_get_block); 424cd82cca7SChristoph Hellwig } 425cd82cca7SChristoph Hellwig 426cd82cca7SChristoph Hellwig static int blkdev_write_begin(struct file *file, struct address_space *mapping, 4279d6b0cd7SMatthew Wilcox (Oracle) loff_t pos, unsigned len, struct page **pagep, void **fsdata) 428cd82cca7SChristoph Hellwig { 429b3992d1eSMatthew Wilcox (Oracle) return block_write_begin(mapping, pos, len, pagep, blkdev_get_block); 430cd82cca7SChristoph Hellwig } 431cd82cca7SChristoph Hellwig 432cd82cca7SChristoph Hellwig static int blkdev_write_end(struct file *file, struct address_space *mapping, 433cd82cca7SChristoph Hellwig loff_t pos, unsigned len, unsigned copied, struct page *page, 434cd82cca7SChristoph Hellwig void *fsdata) 435cd82cca7SChristoph Hellwig { 436cd82cca7SChristoph Hellwig int ret; 437cd82cca7SChristoph Hellwig ret = block_write_end(file, mapping, pos, len, copied, page, fsdata); 438cd82cca7SChristoph Hellwig 439cd82cca7SChristoph Hellwig unlock_page(page); 440cd82cca7SChristoph Hellwig put_page(page); 441cd82cca7SChristoph Hellwig 442cd82cca7SChristoph Hellwig return ret; 443cd82cca7SChristoph Hellwig } 444cd82cca7SChristoph Hellwig 445cd82cca7SChristoph Hellwig const struct address_space_operations def_blk_aops = { 446e621900aSMatthew Wilcox (Oracle) .dirty_folio = block_dirty_folio, 4477ba13abbSMatthew Wilcox (Oracle) .invalidate_folio = block_invalidate_folio, 4482c69e205SMatthew Wilcox (Oracle) .read_folio = blkdev_read_folio, 449cd82cca7SChristoph Hellwig .readahead = blkdev_readahead, 450cd82cca7SChristoph Hellwig .writepage = blkdev_writepage, 451cd82cca7SChristoph Hellwig .write_begin = blkdev_write_begin, 452cd82cca7SChristoph Hellwig .write_end = blkdev_write_end, 45367235182SMatthew Wilcox (Oracle) .migrate_folio = buffer_migrate_folio_norefs, 454cd82cca7SChristoph Hellwig .is_dirty_writeback = buffer_check_dirty_writeback, 455cd82cca7SChristoph Hellwig }; 456cd82cca7SChristoph Hellwig 457cd82cca7SChristoph Hellwig /* 458cd82cca7SChristoph Hellwig * for a block special file file_inode(file)->i_size is zero 459cd82cca7SChristoph Hellwig * so we compute the size by hand (just as in block_read/write above) 460cd82cca7SChristoph Hellwig */ 461cd82cca7SChristoph Hellwig static loff_t blkdev_llseek(struct file *file, loff_t offset, int whence) 462cd82cca7SChristoph Hellwig { 463cd82cca7SChristoph Hellwig struct inode *bd_inode = bdev_file_inode(file); 464cd82cca7SChristoph Hellwig loff_t retval; 465cd82cca7SChristoph Hellwig 466cd82cca7SChristoph Hellwig inode_lock(bd_inode); 467cd82cca7SChristoph Hellwig retval = fixed_size_llseek(file, offset, whence, i_size_read(bd_inode)); 468cd82cca7SChristoph Hellwig inode_unlock(bd_inode); 469cd82cca7SChristoph Hellwig return retval; 470cd82cca7SChristoph Hellwig } 471cd82cca7SChristoph Hellwig 472cd82cca7SChristoph Hellwig static int blkdev_fsync(struct file *filp, loff_t start, loff_t end, 473cd82cca7SChristoph Hellwig int datasync) 474cd82cca7SChristoph Hellwig { 4754e762d86SChristoph Hellwig struct block_device *bdev = I_BDEV(filp->f_mapping->host); 476cd82cca7SChristoph Hellwig int error; 477cd82cca7SChristoph Hellwig 478cd82cca7SChristoph Hellwig error = file_write_and_wait_range(filp, start, end); 479cd82cca7SChristoph Hellwig if (error) 480cd82cca7SChristoph Hellwig return error; 481cd82cca7SChristoph Hellwig 482cd82cca7SChristoph Hellwig /* 483cd82cca7SChristoph Hellwig * There is no need to serialise calls to blkdev_issue_flush with 484cd82cca7SChristoph Hellwig * i_mutex and doing so causes performance issues with concurrent 485cd82cca7SChristoph Hellwig * O_SYNC writers to a block device. 486cd82cca7SChristoph Hellwig */ 487cd82cca7SChristoph Hellwig error = blkdev_issue_flush(bdev); 488cd82cca7SChristoph Hellwig if (error == -EOPNOTSUPP) 489cd82cca7SChristoph Hellwig error = 0; 490cd82cca7SChristoph Hellwig 491cd82cca7SChristoph Hellwig return error; 492cd82cca7SChristoph Hellwig } 493cd82cca7SChristoph Hellwig 49405bdb996SChristoph Hellwig blk_mode_t file_to_blk_mode(struct file *file) 49505bdb996SChristoph Hellwig { 49605bdb996SChristoph Hellwig blk_mode_t mode = 0; 49705bdb996SChristoph Hellwig 49805bdb996SChristoph Hellwig if (file->f_mode & FMODE_READ) 49905bdb996SChristoph Hellwig mode |= BLK_OPEN_READ; 50005bdb996SChristoph Hellwig if (file->f_mode & FMODE_WRITE) 50105bdb996SChristoph Hellwig mode |= BLK_OPEN_WRITE; 502ee3249a8SChristoph Hellwig if (file->private_data) 50305bdb996SChristoph Hellwig mode |= BLK_OPEN_EXCL; 50405bdb996SChristoph Hellwig if (file->f_flags & O_NDELAY) 50505bdb996SChristoph Hellwig mode |= BLK_OPEN_NDELAY; 50605bdb996SChristoph Hellwig 50705bdb996SChristoph Hellwig /* 50805bdb996SChristoph Hellwig * If all bits in O_ACCMODE set (aka O_RDWR | O_WRONLY), the floppy 50905bdb996SChristoph Hellwig * driver has historically allowed ioctls as if the file was opened for 51005bdb996SChristoph Hellwig * writing, but does not allow and actual reads or writes. 51105bdb996SChristoph Hellwig */ 51205bdb996SChristoph Hellwig if ((file->f_flags & O_ACCMODE) == (O_RDWR | O_WRONLY)) 51305bdb996SChristoph Hellwig mode |= BLK_OPEN_WRITE_IOCTL; 51405bdb996SChristoph Hellwig 51505bdb996SChristoph Hellwig return mode; 51605bdb996SChristoph Hellwig } 51705bdb996SChristoph Hellwig 518cd82cca7SChristoph Hellwig static int blkdev_open(struct inode *inode, struct file *filp) 519cd82cca7SChristoph Hellwig { 520cd82cca7SChristoph Hellwig struct block_device *bdev; 521cd82cca7SChristoph Hellwig 522cd82cca7SChristoph Hellwig /* 523cd82cca7SChristoph Hellwig * Preserve backwards compatibility and allow large file access 524cd82cca7SChristoph Hellwig * even if userspace doesn't ask for it explicitly. Some mkfs 525cd82cca7SChristoph Hellwig * binary needs it. We might want to drop this workaround 526cd82cca7SChristoph Hellwig * during an unstable branch. 527cd82cca7SChristoph Hellwig */ 528cd82cca7SChristoph Hellwig filp->f_flags |= O_LARGEFILE; 529a05f7bd9SChristoph Hellwig filp->f_mode |= FMODE_BUF_RASYNC | FMODE_CAN_ODIRECT; 530cd82cca7SChristoph Hellwig 531ee3249a8SChristoph Hellwig /* 532ee3249a8SChristoph Hellwig * Use the file private data to store the holder for exclusive openes. 533ee3249a8SChristoph Hellwig * file_to_blk_mode relies on it being present to set BLK_OPEN_EXCL. 534ee3249a8SChristoph Hellwig */ 535cd82cca7SChristoph Hellwig if (filp->f_flags & O_EXCL) 536ee3249a8SChristoph Hellwig filp->private_data = filp; 537cd82cca7SChristoph Hellwig 53805bdb996SChristoph Hellwig bdev = blkdev_get_by_dev(inode->i_rdev, file_to_blk_mode(filp), 539ee3249a8SChristoph Hellwig filp->private_data, NULL); 540cd82cca7SChristoph Hellwig if (IS_ERR(bdev)) 541cd82cca7SChristoph Hellwig return PTR_ERR(bdev); 542fac7c6d5SPavel Begunkov 543e9833d87SJens Axboe if (bdev_nowait(bdev)) 544e9833d87SJens Axboe filp->f_mode |= FMODE_NOWAIT; 545e9833d87SJens Axboe 546cd82cca7SChristoph Hellwig filp->f_mapping = bdev->bd_inode->i_mapping; 547cd82cca7SChristoph Hellwig filp->f_wb_err = filemap_sample_wb_err(filp->f_mapping); 548cd82cca7SChristoph Hellwig return 0; 549cd82cca7SChristoph Hellwig } 550cd82cca7SChristoph Hellwig 5517ee34cbcSChristoph Hellwig static int blkdev_release(struct inode *inode, struct file *filp) 552cd82cca7SChristoph Hellwig { 553ee3249a8SChristoph Hellwig blkdev_put(I_BDEV(filp->f_mapping->host), filp->private_data); 554cd82cca7SChristoph Hellwig return 0; 555cd82cca7SChristoph Hellwig } 556cd82cca7SChristoph Hellwig 557727cfe97SChristoph Hellwig static ssize_t 558727cfe97SChristoph Hellwig blkdev_direct_write(struct kiocb *iocb, struct iov_iter *from) 559727cfe97SChristoph Hellwig { 560727cfe97SChristoph Hellwig size_t count = iov_iter_count(from); 561727cfe97SChristoph Hellwig ssize_t written; 562727cfe97SChristoph Hellwig 563727cfe97SChristoph Hellwig written = kiocb_invalidate_pages(iocb, count); 564727cfe97SChristoph Hellwig if (written) { 565727cfe97SChristoph Hellwig if (written == -EBUSY) 566727cfe97SChristoph Hellwig return 0; 567727cfe97SChristoph Hellwig return written; 568727cfe97SChristoph Hellwig } 569727cfe97SChristoph Hellwig 570727cfe97SChristoph Hellwig written = blkdev_direct_IO(iocb, from); 571727cfe97SChristoph Hellwig if (written > 0) { 572727cfe97SChristoph Hellwig kiocb_invalidate_post_direct_write(iocb, count); 573727cfe97SChristoph Hellwig iocb->ki_pos += written; 574727cfe97SChristoph Hellwig count -= written; 575727cfe97SChristoph Hellwig } 576727cfe97SChristoph Hellwig if (written != -EIOCBQUEUED) 577727cfe97SChristoph Hellwig iov_iter_revert(from, count - iov_iter_count(from)); 578727cfe97SChristoph Hellwig return written; 579727cfe97SChristoph Hellwig } 580727cfe97SChristoph Hellwig 581*487c607dSChristoph Hellwig static ssize_t blkdev_buffered_write(struct kiocb *iocb, struct iov_iter *from) 582*487c607dSChristoph Hellwig { 583*487c607dSChristoph Hellwig return iomap_file_buffered_write(iocb, from, &blkdev_iomap_ops); 584*487c607dSChristoph Hellwig } 585*487c607dSChristoph Hellwig 586cd82cca7SChristoph Hellwig /* 587cd82cca7SChristoph Hellwig * Write data to the block device. Only intended for the block device itself 588cd82cca7SChristoph Hellwig * and the raw driver which basically is a fake block device. 589cd82cca7SChristoph Hellwig * 590cd82cca7SChristoph Hellwig * Does not take i_mutex for the write and thus is not for general purpose 591cd82cca7SChristoph Hellwig * use. 592cd82cca7SChristoph Hellwig */ 593cd82cca7SChristoph Hellwig static ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) 594cd82cca7SChristoph Hellwig { 595727cfe97SChristoph Hellwig struct file *file = iocb->ki_filp; 596727cfe97SChristoph Hellwig struct block_device *bdev = I_BDEV(file->f_mapping->host); 597fac7c6d5SPavel Begunkov struct inode *bd_inode = bdev->bd_inode; 598138c1a38SJens Axboe loff_t size = bdev_nr_bytes(bdev); 599cd82cca7SChristoph Hellwig size_t shorted = 0; 600cd82cca7SChristoph Hellwig ssize_t ret; 601cd82cca7SChristoph Hellwig 602fac7c6d5SPavel Begunkov if (bdev_read_only(bdev)) 603cd82cca7SChristoph Hellwig return -EPERM; 604cd82cca7SChristoph Hellwig 605cd82cca7SChristoph Hellwig if (IS_SWAPFILE(bd_inode) && !is_hibernate_resume_dev(bd_inode->i_rdev)) 606cd82cca7SChristoph Hellwig return -ETXTBSY; 607cd82cca7SChristoph Hellwig 608cd82cca7SChristoph Hellwig if (!iov_iter_count(from)) 609cd82cca7SChristoph Hellwig return 0; 610cd82cca7SChristoph Hellwig 611cd82cca7SChristoph Hellwig if (iocb->ki_pos >= size) 612cd82cca7SChristoph Hellwig return -ENOSPC; 613cd82cca7SChristoph Hellwig 614cd82cca7SChristoph Hellwig if ((iocb->ki_flags & (IOCB_NOWAIT | IOCB_DIRECT)) == IOCB_NOWAIT) 615cd82cca7SChristoph Hellwig return -EOPNOTSUPP; 616cd82cca7SChristoph Hellwig 617cd82cca7SChristoph Hellwig size -= iocb->ki_pos; 618cd82cca7SChristoph Hellwig if (iov_iter_count(from) > size) { 619cd82cca7SChristoph Hellwig shorted = iov_iter_count(from) - size; 620cd82cca7SChristoph Hellwig iov_iter_truncate(from, size); 621cd82cca7SChristoph Hellwig } 622cd82cca7SChristoph Hellwig 623727cfe97SChristoph Hellwig ret = file_remove_privs(file); 624727cfe97SChristoph Hellwig if (ret) 625727cfe97SChristoph Hellwig return ret; 626727cfe97SChristoph Hellwig 627727cfe97SChristoph Hellwig ret = file_update_time(file); 628727cfe97SChristoph Hellwig if (ret) 629727cfe97SChristoph Hellwig return ret; 630727cfe97SChristoph Hellwig 631727cfe97SChristoph Hellwig if (iocb->ki_flags & IOCB_DIRECT) { 632727cfe97SChristoph Hellwig ret = blkdev_direct_write(iocb, from); 633727cfe97SChristoph Hellwig if (ret >= 0 && iov_iter_count(from)) 634727cfe97SChristoph Hellwig ret = direct_write_fallback(iocb, from, ret, 635*487c607dSChristoph Hellwig blkdev_buffered_write(iocb, from)); 636727cfe97SChristoph Hellwig } else { 637*487c607dSChristoph Hellwig ret = blkdev_buffered_write(iocb, from); 638727cfe97SChristoph Hellwig } 639727cfe97SChristoph Hellwig 640cd82cca7SChristoph Hellwig if (ret > 0) 641cd82cca7SChristoph Hellwig ret = generic_write_sync(iocb, ret); 642cd82cca7SChristoph Hellwig iov_iter_reexpand(from, iov_iter_count(from) + shorted); 643cd82cca7SChristoph Hellwig return ret; 644cd82cca7SChristoph Hellwig } 645cd82cca7SChristoph Hellwig 646cd82cca7SChristoph Hellwig static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to) 647cd82cca7SChristoph Hellwig { 6484e762d86SChristoph Hellwig struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host); 649138c1a38SJens Axboe loff_t size = bdev_nr_bytes(bdev); 650cd82cca7SChristoph Hellwig loff_t pos = iocb->ki_pos; 651cd82cca7SChristoph Hellwig size_t shorted = 0; 652ceaa7625SJens Axboe ssize_t ret = 0; 6533e1f941dSIlya Dryomov size_t count; 654cd82cca7SChristoph Hellwig 6553e1f941dSIlya Dryomov if (unlikely(pos + iov_iter_count(to) > size)) { 656cd82cca7SChristoph Hellwig if (pos >= size) 657cd82cca7SChristoph Hellwig return 0; 658cd82cca7SChristoph Hellwig size -= pos; 6593e1f941dSIlya Dryomov shorted = iov_iter_count(to) - size; 660cd82cca7SChristoph Hellwig iov_iter_truncate(to, size); 661cd82cca7SChristoph Hellwig } 6623e1f941dSIlya Dryomov 6633e1f941dSIlya Dryomov count = iov_iter_count(to); 6643e1f941dSIlya Dryomov if (!count) 6653e1f941dSIlya Dryomov goto reexpand; /* skip atime */ 666cd82cca7SChristoph Hellwig 667ceaa7625SJens Axboe if (iocb->ki_flags & IOCB_DIRECT) { 6683c435a0fSChristoph Hellwig ret = kiocb_write_and_wait(iocb, count); 669ceaa7625SJens Axboe if (ret < 0) 6703e1f941dSIlya Dryomov goto reexpand; 671ceaa7625SJens Axboe file_accessed(iocb->ki_filp); 672ceaa7625SJens Axboe 673ceaa7625SJens Axboe ret = blkdev_direct_IO(iocb, to); 674ceaa7625SJens Axboe if (ret >= 0) { 675ceaa7625SJens Axboe iocb->ki_pos += ret; 676ceaa7625SJens Axboe count -= ret; 677ceaa7625SJens Axboe } 6783e1f941dSIlya Dryomov iov_iter_revert(to, count - iov_iter_count(to)); 679ceaa7625SJens Axboe if (ret < 0 || !count) 6803e1f941dSIlya Dryomov goto reexpand; 681ceaa7625SJens Axboe } 682ceaa7625SJens Axboe 683ceaa7625SJens Axboe ret = filemap_read(iocb, to, ret); 6846450fe1fSPavel Begunkov 6853e1f941dSIlya Dryomov reexpand: 6866450fe1fSPavel Begunkov if (unlikely(shorted)) 687cd82cca7SChristoph Hellwig iov_iter_reexpand(to, iov_iter_count(to) + shorted); 688cd82cca7SChristoph Hellwig return ret; 689cd82cca7SChristoph Hellwig } 690cd82cca7SChristoph Hellwig 691cd82cca7SChristoph Hellwig #define BLKDEV_FALLOC_FL_SUPPORTED \ 692cd82cca7SChristoph Hellwig (FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE | \ 693cd82cca7SChristoph Hellwig FALLOC_FL_ZERO_RANGE | FALLOC_FL_NO_HIDE_STALE) 694cd82cca7SChristoph Hellwig 695cd82cca7SChristoph Hellwig static long blkdev_fallocate(struct file *file, int mode, loff_t start, 696cd82cca7SChristoph Hellwig loff_t len) 697cd82cca7SChristoph Hellwig { 698f278eb3dSMing Lei struct inode *inode = bdev_file_inode(file); 699f278eb3dSMing Lei struct block_device *bdev = I_BDEV(inode); 700cd82cca7SChristoph Hellwig loff_t end = start + len - 1; 701cd82cca7SChristoph Hellwig loff_t isize; 702cd82cca7SChristoph Hellwig int error; 703cd82cca7SChristoph Hellwig 704cd82cca7SChristoph Hellwig /* Fail if we don't recognize the flags. */ 705cd82cca7SChristoph Hellwig if (mode & ~BLKDEV_FALLOC_FL_SUPPORTED) 706cd82cca7SChristoph Hellwig return -EOPNOTSUPP; 707cd82cca7SChristoph Hellwig 708cd82cca7SChristoph Hellwig /* Don't go off the end of the device. */ 7092a93ad8fSChristoph Hellwig isize = bdev_nr_bytes(bdev); 710cd82cca7SChristoph Hellwig if (start >= isize) 711cd82cca7SChristoph Hellwig return -EINVAL; 712cd82cca7SChristoph Hellwig if (end >= isize) { 713cd82cca7SChristoph Hellwig if (mode & FALLOC_FL_KEEP_SIZE) { 714cd82cca7SChristoph Hellwig len = isize - start; 715cd82cca7SChristoph Hellwig end = start + len - 1; 716cd82cca7SChristoph Hellwig } else 717cd82cca7SChristoph Hellwig return -EINVAL; 718cd82cca7SChristoph Hellwig } 719cd82cca7SChristoph Hellwig 720cd82cca7SChristoph Hellwig /* 721cd82cca7SChristoph Hellwig * Don't allow IO that isn't aligned to logical block size. 722cd82cca7SChristoph Hellwig */ 723cd82cca7SChristoph Hellwig if ((start | len) & (bdev_logical_block_size(bdev) - 1)) 724cd82cca7SChristoph Hellwig return -EINVAL; 725cd82cca7SChristoph Hellwig 726f278eb3dSMing Lei filemap_invalidate_lock(inode->i_mapping); 727f278eb3dSMing Lei 728cd82cca7SChristoph Hellwig /* Invalidate the page cache, including dirty pages. */ 72905bdb996SChristoph Hellwig error = truncate_bdev_range(bdev, file_to_blk_mode(file), start, end); 730cd82cca7SChristoph Hellwig if (error) 731f278eb3dSMing Lei goto fail; 732cd82cca7SChristoph Hellwig 733cd82cca7SChristoph Hellwig switch (mode) { 734cd82cca7SChristoph Hellwig case FALLOC_FL_ZERO_RANGE: 735cd82cca7SChristoph Hellwig case FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE: 7366549a874SPavel Begunkov error = blkdev_issue_zeroout(bdev, start >> SECTOR_SHIFT, 7376549a874SPavel Begunkov len >> SECTOR_SHIFT, GFP_KERNEL, 7386549a874SPavel Begunkov BLKDEV_ZERO_NOUNMAP); 739cd82cca7SChristoph Hellwig break; 740cd82cca7SChristoph Hellwig case FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE: 7416549a874SPavel Begunkov error = blkdev_issue_zeroout(bdev, start >> SECTOR_SHIFT, 7426549a874SPavel Begunkov len >> SECTOR_SHIFT, GFP_KERNEL, 7436549a874SPavel Begunkov BLKDEV_ZERO_NOFALLBACK); 744cd82cca7SChristoph Hellwig break; 745cd82cca7SChristoph Hellwig case FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE | FALLOC_FL_NO_HIDE_STALE: 7466549a874SPavel Begunkov error = blkdev_issue_discard(bdev, start >> SECTOR_SHIFT, 74744abff2cSChristoph Hellwig len >> SECTOR_SHIFT, GFP_KERNEL); 748cd82cca7SChristoph Hellwig break; 749cd82cca7SChristoph Hellwig default: 750f278eb3dSMing Lei error = -EOPNOTSUPP; 751cd82cca7SChristoph Hellwig } 752cd82cca7SChristoph Hellwig 753f278eb3dSMing Lei fail: 754f278eb3dSMing Lei filemap_invalidate_unlock(inode->i_mapping); 755f278eb3dSMing Lei return error; 756cd82cca7SChristoph Hellwig } 757cd82cca7SChristoph Hellwig 75869baa3a6SLoic Poulain static int blkdev_mmap(struct file *file, struct vm_area_struct *vma) 75969baa3a6SLoic Poulain { 76069baa3a6SLoic Poulain struct inode *bd_inode = bdev_file_inode(file); 76169baa3a6SLoic Poulain 76269baa3a6SLoic Poulain if (bdev_read_only(I_BDEV(bd_inode))) 76369baa3a6SLoic Poulain return generic_file_readonly_mmap(file, vma); 76469baa3a6SLoic Poulain 76569baa3a6SLoic Poulain return generic_file_mmap(file, vma); 76669baa3a6SLoic Poulain } 76769baa3a6SLoic Poulain 768cd82cca7SChristoph Hellwig const struct file_operations def_blk_fops = { 769cd82cca7SChristoph Hellwig .open = blkdev_open, 7707ee34cbcSChristoph Hellwig .release = blkdev_release, 771cd82cca7SChristoph Hellwig .llseek = blkdev_llseek, 772cd82cca7SChristoph Hellwig .read_iter = blkdev_read_iter, 773cd82cca7SChristoph Hellwig .write_iter = blkdev_write_iter, 7743e08773cSChristoph Hellwig .iopoll = iocb_bio_iopoll, 77569baa3a6SLoic Poulain .mmap = blkdev_mmap, 776cd82cca7SChristoph Hellwig .fsync = blkdev_fsync, 7778a709512SChristoph Hellwig .unlocked_ioctl = blkdev_ioctl, 778cd82cca7SChristoph Hellwig #ifdef CONFIG_COMPAT 779cd82cca7SChristoph Hellwig .compat_ioctl = compat_blkdev_ioctl, 780cd82cca7SChristoph Hellwig #endif 7812cb1e089SDavid Howells .splice_read = filemap_splice_read, 782cd82cca7SChristoph Hellwig .splice_write = iter_file_splice_write, 783cd82cca7SChristoph Hellwig .fallocate = blkdev_fallocate, 784cd82cca7SChristoph Hellwig }; 785cd82cca7SChristoph Hellwig 786cd82cca7SChristoph Hellwig static __init int blkdev_init(void) 787cd82cca7SChristoph Hellwig { 788cd82cca7SChristoph Hellwig return bioset_init(&blkdev_dio_pool, 4, 789cd82cca7SChristoph Hellwig offsetof(struct blkdev_dio, bio), 790cd82cca7SChristoph Hellwig BIOSET_NEED_BVECS|BIOSET_PERCPU_CACHE); 791cd82cca7SChristoph Hellwig } 792cd82cca7SChristoph Hellwig module_init(blkdev_init); 793