2158 lines · 53.2 KB · C
RawDownload
/* *  linux/fs/block_dev.c * *  Copyright (C) 1991, 1992  Linus Torvalds *  Copyright (C) 2001  Andrea Arcangeli <andrea@suse.de> SuSE */ #include <linux/init.h>#include <linux/mm.h>#include <linux/fcntl.h>#include <linux/slab.h>#include <linux/kmod.h>#include <linux/major.h>#include <linux/device_cgroup.h>#include <linux/highmem.h>#include <linux/blkdev.h>#include <linux/backing-dev.h>#include <linux/module.h>#include <linux/blkpg.h>#include <linux/magic.h>#include <linux/dax.h>#include <linux/buffer_head.h>#include <linux/swap.h>#include <linux/pagevec.h>#include <linux/writeback.h>#include <linux/mpage.h>#include <linux/mount.h>#include <linux/uio.h>#include <linux/namei.h>#include <linux/log2.h>#include <linux/cleancache.h>#include <linux/dax.h>#include <linux/badblocks.h>#include <linux/task_io_accounting_ops.h>#include <linux/falloc.h>#include <linux/uaccess.h>#include "internal.h" struct bdev_inode {	struct block_device bdev;	struct inode vfs_inode;}; static const struct address_space_operations def_blk_aops; static inline struct bdev_inode *BDEV_I(struct inode *inode){	return container_of(inode, struct bdev_inode, vfs_inode);} struct block_device *I_BDEV(struct inode *inode){	return &BDEV_I(inode)->bdev;}EXPORT_SYMBOL(I_BDEV); void __vfs_msg(struct super_block *sb, const char *prefix, const char *fmt, ...){	struct va_format vaf;	va_list args; 	va_start(args, fmt);	vaf.fmt = fmt;	vaf.va = &args;	printk_ratelimited("%sVFS (%s): %pV\n", prefix, sb->s_id, &vaf);	va_end(args);} static void bdev_write_inode(struct block_device *bdev){	struct inode *inode = bdev->bd_inode;	int ret; 	spin_lock(&inode->i_lock);	while (inode->i_state & I_DIRTY) {		spin_unlock(&inode->i_lock);		ret = write_inode_now(inode, true);		if (ret) {			char name[BDEVNAME_SIZE];			pr_warn_ratelimited("VFS: Dirty inode writeback failed "					    "for block device %s (err=%d).\n",					    bdevname(bdev, name), ret);		}		spin_lock(&inode->i_lock);	}	spin_unlock(&inode->i_lock);} /* Kill _all_ buffers and pagecache , dirty or not.. */void kill_bdev(struct block_device *bdev){	struct address_space *mapping = bdev->bd_inode->i_mapping; 	if (mapping->nrpages == 0 && mapping->nrexceptional == 0)		return; 	invalidate_bh_lrus();	truncate_inode_pages(mapping, 0);}	EXPORT_SYMBOL(kill_bdev); /* Invalidate clean unused buffers and pagecache. */void invalidate_bdev(struct block_device *bdev){	struct address_space *mapping = bdev->bd_inode->i_mapping; 	if (mapping->nrpages) {		invalidate_bh_lrus();		lru_add_drain_all();	/* make sure all lru add caches are flushed */		invalidate_mapping_pages(mapping, 0, -1);	}	/* 99% of the time, we don't need to flush the cleancache on the bdev.	 * But, for the strange corners, lets be cautious	 */	cleancache_invalidate_inode(mapping);}EXPORT_SYMBOL(invalidate_bdev); int set_blocksize(struct block_device *bdev, int size){	/* Size must be a power of two, and between 512 and PAGE_SIZE */	if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size))		return -EINVAL; 	/* Size cannot be smaller than the size supported by the device */	if (size < bdev_logical_block_size(bdev))		return -EINVAL; 	/* Don't change the size if it is same as current */	if (bdev->bd_block_size != size) {		sync_blockdev(bdev);		bdev->bd_block_size = size;		bdev->bd_inode->i_blkbits = blksize_bits(size);		kill_bdev(bdev);	}	return 0;} EXPORT_SYMBOL(set_blocksize); int sb_set_blocksize(struct super_block *sb, int size){	if (set_blocksize(sb->s_bdev, size))		return 0;	/* If we get here, we know size is power of two	 * and it's value is between 512 and PAGE_SIZE */	sb->s_blocksize = size;	sb->s_blocksize_bits = blksize_bits(size);	return sb->s_blocksize;} EXPORT_SYMBOL(sb_set_blocksize); int sb_min_blocksize(struct super_block *sb, int size){	int minsize = bdev_logical_block_size(sb->s_bdev);	if (size < minsize)		size = minsize;	return sb_set_blocksize(sb, size);} EXPORT_SYMBOL(sb_min_blocksize); static intblkdev_get_block(struct inode *inode, sector_t iblock,		struct buffer_head *bh, int create){	bh->b_bdev = I_BDEV(inode);	bh->b_blocknr = iblock;	set_buffer_mapped(bh);	return 0;} static struct inode *bdev_file_inode(struct file *file){	return file->f_mapping->host;} static unsigned int dio_bio_write_op(struct kiocb *iocb){	unsigned int op = REQ_OP_WRITE | REQ_SYNC | REQ_IDLE; 	/* avoid the need for a I/O completion work item */	if (iocb->ki_flags & IOCB_DSYNC)		op |= REQ_FUA;	return op;} #define DIO_INLINE_BIO_VECS 4 static void blkdev_bio_end_io_simple(struct bio *bio){	struct task_struct *waiter = bio->bi_private; 	WRITE_ONCE(bio->bi_private, NULL);	wake_up_process(waiter);} static ssize_t__blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter,		int nr_pages){	struct file *file = iocb->ki_filp;	struct block_device *bdev = I_BDEV(bdev_file_inode(file));	struct bio_vec inline_vecs[DIO_INLINE_BIO_VECS], *vecs, *bvec;	loff_t pos = iocb->ki_pos;	bool should_dirty = false;	struct bio bio;	ssize_t ret;	blk_qc_t qc;	int i; 	if ((pos | iov_iter_alignment(iter)) &	    (bdev_logical_block_size(bdev) - 1))		return -EINVAL; 	if (nr_pages <= DIO_INLINE_BIO_VECS)		vecs = inline_vecs;	else {		vecs = kmalloc(nr_pages * sizeof(struct bio_vec), GFP_KERNEL);		if (!vecs)			return -ENOMEM;	} 	bio_init(&bio, vecs, nr_pages);	bio.bi_bdev = bdev;	bio.bi_iter.bi_sector = pos >> 9;	bio.bi_write_hint = iocb->ki_hint;	bio.bi_private = current;	bio.bi_end_io = blkdev_bio_end_io_simple; 	ret = bio_iov_iter_get_pages(&bio, iter);	if (unlikely(ret))		return ret;	ret = bio.bi_iter.bi_size; 	if (iov_iter_rw(iter) == READ) {		bio.bi_opf = REQ_OP_READ;		if (iter_is_iovec(iter))			should_dirty = true;	} else {		bio.bi_opf = dio_bio_write_op(iocb);		task_io_account_write(ret);	} 	qc = submit_bio(&bio);	for (;;) {		set_current_state(TASK_UNINTERRUPTIBLE);		if (!READ_ONCE(bio.bi_private))			break;		if (!(iocb->ki_flags & IOCB_HIPRI) ||		    !blk_mq_poll(bdev_get_queue(bdev), qc))			io_schedule();	}	__set_current_state(TASK_RUNNING); 	bio_for_each_segment_all(bvec, &bio, i) {		if (should_dirty && !PageCompound(bvec->bv_page))			set_page_dirty_lock(bvec->bv_page);		put_page(bvec->bv_page);	} 	if (vecs != inline_vecs)		kfree(vecs); 	if (unlikely(bio.bi_status))		ret = blk_status_to_errno(bio.bi_status); 	bio_uninit(&bio); 	return ret;} struct blkdev_dio {	union {		struct kiocb		*iocb;		struct task_struct	*waiter;	};	size_t			size;	atomic_t		ref;	bool			multi_bio : 1;	bool			should_dirty : 1;	bool			is_sync : 1;	struct bio		bio;}; static struct bio_set *blkdev_dio_pool __read_mostly; static void blkdev_bio_end_io(struct bio *bio){	struct blkdev_dio *dio = bio->bi_private;	bool should_dirty = dio->should_dirty; 	if (dio->multi_bio && !atomic_dec_and_test(&dio->ref)) {		if (bio->bi_status && !dio->bio.bi_status)			dio->bio.bi_status = bio->bi_status;	} else {		if (!dio->is_sync) {			struct kiocb *iocb = dio->iocb;			ssize_t ret; 			if (likely(!dio->bio.bi_status)) {				ret = dio->size;				iocb->ki_pos += ret;			} else {				ret = blk_status_to_errno(dio->bio.bi_status);			} 			dio->iocb->ki_complete(iocb, ret, 0);			bio_put(&dio->bio);		} else {			struct task_struct *waiter = dio->waiter; 			WRITE_ONCE(dio->waiter, NULL);			wake_up_process(waiter);		}	} 	if (should_dirty) {		bio_check_pages_dirty(bio);	} else {		struct bio_vec *bvec;		int i; 		bio_for_each_segment_all(bvec, bio, i)			put_page(bvec->bv_page);		bio_put(bio);	}} static ssize_t__blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages){	struct file *file = iocb->ki_filp;	struct inode *inode = bdev_file_inode(file);	struct block_device *bdev = I_BDEV(inode);	struct blk_plug plug;	struct blkdev_dio *dio;	struct bio *bio;	bool is_read = (iov_iter_rw(iter) == READ), is_sync;	loff_t pos = iocb->ki_pos;	blk_qc_t qc = BLK_QC_T_NONE;	int ret = 0; 	if ((pos | iov_iter_alignment(iter)) &	    (bdev_logical_block_size(bdev) - 1))		return -EINVAL; 	bio = bio_alloc_bioset(GFP_KERNEL, nr_pages, blkdev_dio_pool);	bio_get(bio); /* extra ref for the completion handler */ 	dio = container_of(bio, struct blkdev_dio, bio);	dio->is_sync = is_sync = is_sync_kiocb(iocb);	if (dio->is_sync)		dio->waiter = current;	else		dio->iocb = iocb; 	dio->size = 0;	dio->multi_bio = false;	dio->should_dirty = is_read && (iter->type == ITER_IOVEC); 	blk_start_plug(&plug);	for (;;) {		bio->bi_bdev = bdev;		bio->bi_iter.bi_sector = pos >> 9;		bio->bi_write_hint = iocb->ki_hint;		bio->bi_private = dio;		bio->bi_end_io = blkdev_bio_end_io; 		ret = bio_iov_iter_get_pages(bio, iter);		if (unlikely(ret)) {			bio->bi_status = BLK_STS_IOERR;			bio_endio(bio);			break;		} 		if (is_read) {			bio->bi_opf = REQ_OP_READ;			if (dio->should_dirty)				bio_set_pages_dirty(bio);		} else {			bio->bi_opf = dio_bio_write_op(iocb);			task_io_account_write(bio->bi_iter.bi_size);		} 		dio->size += bio->bi_iter.bi_size;		pos += bio->bi_iter.bi_size; 		nr_pages = iov_iter_npages(iter, BIO_MAX_PAGES);		if (!nr_pages) {			qc = submit_bio(bio);			break;		} 		if (!dio->multi_bio) {			dio->multi_bio = true;			atomic_set(&dio->ref, 2);		} else {			atomic_inc(&dio->ref);		} 		submit_bio(bio);		bio = bio_alloc(GFP_KERNEL, nr_pages);	}	blk_finish_plug(&plug); 	if (!is_sync)		return -EIOCBQUEUED; 	for (;;) {		set_current_state(TASK_UNINTERRUPTIBLE);		if (!READ_ONCE(dio->waiter))			break; 		if (!(iocb->ki_flags & IOCB_HIPRI) ||		    !blk_mq_poll(bdev_get_queue(bdev), qc))			io_schedule();	}	__set_current_state(TASK_RUNNING); 	if (!ret)		ret = blk_status_to_errno(dio->bio.bi_status);	if (likely(!ret))		ret = dio->size; 	bio_put(&dio->bio);	return ret;} static ssize_tblkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter){	int nr_pages; 	nr_pages = iov_iter_npages(iter, BIO_MAX_PAGES + 1);	if (!nr_pages)		return 0;	if (is_sync_kiocb(iocb) && nr_pages <= BIO_MAX_PAGES)		return __blkdev_direct_IO_simple(iocb, iter, nr_pages); 	return __blkdev_direct_IO(iocb, iter, min(nr_pages, BIO_MAX_PAGES));} static __init int blkdev_init(void){	blkdev_dio_pool = bioset_create(4, offsetof(struct blkdev_dio, bio), BIOSET_NEED_BVECS);	if (!blkdev_dio_pool)		return -ENOMEM;	return 0;}module_init(blkdev_init); int __sync_blockdev(struct block_device *bdev, int wait){	if (!bdev)		return 0;	if (!wait)		return filemap_flush(bdev->bd_inode->i_mapping);	return filemap_write_and_wait(bdev->bd_inode->i_mapping);} /* * Write out and wait upon all the dirty data associated with a block * device via its mapping.  Does not take the superblock lock. */int sync_blockdev(struct block_device *bdev){	return __sync_blockdev(bdev, 1);}EXPORT_SYMBOL(sync_blockdev); /* * Write out and wait upon all dirty data associated with this * device.   Filesystem data as well as the underlying block * device.  Takes the superblock lock. */int fsync_bdev(struct block_device *bdev){	struct super_block *sb = get_super(bdev);	if (sb) {		int res = sync_filesystem(sb);		drop_super(sb);		return res;	}	return sync_blockdev(bdev);}EXPORT_SYMBOL(fsync_bdev); /** * freeze_bdev  --  lock a filesystem and force it into a consistent state * @bdev:	blockdevice to lock * * If a superblock is found on this device, we take the s_umount semaphore * on it to make sure nobody unmounts until the snapshot creation is done. * The reference counter (bd_fsfreeze_count) guarantees that only the last * unfreeze process can unfreeze the frozen filesystem actually when multiple * freeze requests arrive simultaneously. It counts up in freeze_bdev() and * count down in thaw_bdev(). When it becomes 0, thaw_bdev() will unfreeze * actually.

Lines 1–500 of 2158.