diff options
Diffstat (limited to 'include/linux/blkdev.h')
| -rw-r--r-- | include/linux/blkdev.h | 717 | 
1 files changed, 560 insertions, 157 deletions
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index aae86fd10c4..8699bcf5f09 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1,12 +1,14 @@  #ifndef _LINUX_BLKDEV_H  #define _LINUX_BLKDEV_H +#include <linux/sched.h> +  #ifdef CONFIG_BLOCK -#include <linux/sched.h>  #include <linux/major.h>  #include <linux/genhd.h>  #include <linux/list.h> +#include <linux/llist.h>  #include <linux/timer.h>  #include <linux/workqueue.h>  #include <linux/pagemap.h> @@ -14,14 +16,15 @@  #include <linux/wait.h>  #include <linux/mempool.h>  #include <linux/bio.h> -#include <linux/module.h>  #include <linux/stringify.h>  #include <linux/gfp.h>  #include <linux/bsg.h>  #include <linux/smp.h> +#include <linux/rcupdate.h>  #include <asm/scatterlist.h> +struct module;  struct scsi_ioctl_command;  struct request_queue; @@ -30,23 +33,38 @@ struct request_pm_state;  struct blk_trace;  struct request;  struct sg_io_hdr; +struct bsg_job; +struct blkcg_gq;  #define BLKDEV_MIN_RQ	4  #define BLKDEV_MAX_RQ	128	/* Default maximum */ +/* + * Maximum number of blkcg policies allowed to be registered concurrently. + * Defined here to simplify include dependency. + */ +#define BLKCG_MAX_POLS		2 +  struct request;  typedef void (rq_end_io_fn)(struct request *, int); +#define BLK_RL_SYNCFULL		(1U << 0) +#define BLK_RL_ASYNCFULL	(1U << 1) +  struct request_list { +	struct request_queue	*q;	/* the queue this rl belongs to */ +#ifdef CONFIG_BLK_CGROUP +	struct blkcg_gq		*blkg;	/* blkg this request pool belongs to */ +#endif  	/*  	 * count[], starved[], and wait[] are indexed by  	 * BLK_RW_SYNC/BLK_RW_ASYNC  	 */ -	int count[2]; -	int starved[2]; -	int elvpriv; -	mempool_t *rq_pool; -	wait_queue_head_t wait[2]; +	int			count[2]; +	int			starved[2]; +	mempool_t		*rq_pool; +	wait_queue_head_t	wait[2]; +	unsigned int		flags;  };  /* @@ -72,17 +90,22 @@ enum rq_cmd_type_bits {  #define BLK_MAX_CDB	16  /* - * try to put the fields that are referenced together in the same cacheline. - * if you modify this structure, be sure to check block/blk-core.c:rq_init() - * as well! + * Try to put the fields that are referenced together in the same cacheline. + * + * If you modify this structure, make sure to update blk_rq_init() and + * especially blk_mq_rq_ctx_init() to take care of the added fields.   */  struct request {  	struct list_head queuelist; -	struct call_single_data csd; +	union { +		struct call_single_data csd; +		unsigned long fifo_time; +	};  	struct request_queue *q; +	struct blk_mq_ctx *mq_ctx; -	unsigned int cmd_flags; +	u64 cmd_flags;  	enum rq_cmd_type_bits cmd_type;  	unsigned long atomic_flags; @@ -95,7 +118,18 @@ struct request {  	struct bio *bio;  	struct bio *biotail; -	struct hlist_node hash;	/* merge hash */ +	/* +	 * The hash is used inside the scheduler, and killed once the +	 * request reaches the dispatch list. The ipi_list is only used +	 * to queue the request for softirq completion, which is long +	 * after the request has been unhashed (and even removed from +	 * the dispatch list). +	 */ +	union { +		struct hlist_node hash;	/* merge hash */ +		struct list_head ipi_list; +	}; +  	/*  	 * The rb_node is only used inside the io scheduler, requests  	 * are pruned when moved to the dispatch queue. So let the @@ -108,15 +142,28 @@ struct request {  	/*  	 * Three pointers are available for the IO schedulers, if they need -	 * more they have to dynamically allocate it. +	 * more they have to dynamically allocate it.  Flush requests are +	 * never put on the IO scheduler. So let the flush fields share +	 * space with the elevator data.  	 */ -	void *elevator_private; -	void *elevator_private2; -	void *elevator_private3; +	union { +		struct { +			struct io_cq		*icq; +			void			*priv[2]; +		} elv; + +		struct { +			unsigned int		seq; +			struct list_head	list; +			rq_end_io_fn		*saved_end_io; +		} flush; +	};  	struct gendisk *rq_disk; +	struct hd_struct *part;  	unsigned long start_time;  #ifdef CONFIG_BLK_CGROUP +	struct request_list *rl;		/* rl this rq is alloced from */  	unsigned long long start_time_ns;  	unsigned long long io_start_time_ns;    /* when passed to hardware */  #endif @@ -130,10 +177,7 @@ struct request {  	unsigned short ioprio; -	int ref_count; -  	void *special;		/* opaque pointer available for LLD use */ -	char *buffer;		/* kaddr of the current segment if available */  	int tag;  	int errors; @@ -185,11 +229,12 @@ struct request_pm_state  #include <linux/elevator.h> +struct blk_queue_ctx; +  typedef void (request_fn_proc) (struct request_queue *q); -typedef int (make_request_fn) (struct request_queue *q, struct bio *bio); +typedef void (make_request_fn) (struct request_queue *q, struct bio *bio);  typedef int (prep_rq_fn) (struct request_queue *, struct request *);  typedef void (unprep_rq_fn) (struct request_queue *, struct request *); -typedef void (unplug_fn) (struct request_queue *);  struct bio_vec;  struct bvec_merge_data { @@ -203,6 +248,7 @@ typedef int (merge_bvec_fn) (struct request_queue *, struct bvec_merge_data *,  typedef void (softirq_done_fn)(struct request *);  typedef int (dma_drain_needed_fn)(struct request *);  typedef int (lld_busy_fn) (struct request_queue *q); +typedef int (bsg_job_fn) (struct bsg_job *);  enum blk_eh_timer_return {  	BLK_EH_NOT_HANDLED, @@ -234,6 +280,7 @@ struct queue_limits {  	unsigned long		seg_boundary_mask;  	unsigned int		max_hw_sectors; +	unsigned int		chunk_sectors;  	unsigned int		max_sectors;  	unsigned int		max_segment_size;  	unsigned int		physical_block_size; @@ -241,6 +288,7 @@ struct queue_limits {  	unsigned int		io_min;  	unsigned int		io_opt;  	unsigned int		max_discard_sectors; +	unsigned int		max_write_same_sectors;  	unsigned int		discard_granularity;  	unsigned int		discard_alignment; @@ -250,35 +298,51 @@ struct queue_limits {  	unsigned char		misaligned;  	unsigned char		discard_misaligned; -	unsigned char		no_cluster; -	signed char		discard_zeroes_data; +	unsigned char		cluster; +	unsigned char		discard_zeroes_data; +	unsigned char		raid_partial_stripes_expensive;  }; -struct request_queue -{ +struct request_queue {  	/*  	 * Together with queue_head for cacheline sharing  	 */  	struct list_head	queue_head;  	struct request		*last_merge;  	struct elevator_queue	*elevator; +	int			nr_rqs[2];	/* # allocated [a]sync rqs */ +	int			nr_rqs_elvpriv;	/* # allocated rqs w/ elvpriv */  	/* -	 * the queue request freelist, one for reads and one for writes +	 * If blkcg is not used, @q->root_rl serves all requests.  If blkcg +	 * is used, root blkg allocates from @q->root_rl and all other +	 * blkgs from their own blkg->rl.  Which one to use should be +	 * determined using bio_request_list().  	 */ -	struct request_list	rq; +	struct request_list	root_rl;  	request_fn_proc		*request_fn;  	make_request_fn		*make_request_fn;  	prep_rq_fn		*prep_rq_fn;  	unprep_rq_fn		*unprep_rq_fn; -	unplug_fn		*unplug_fn;  	merge_bvec_fn		*merge_bvec_fn;  	softirq_done_fn		*softirq_done_fn;  	rq_timed_out_fn		*rq_timed_out_fn;  	dma_drain_needed_fn	*dma_drain_needed;  	lld_busy_fn		*lld_busy_fn; +	struct blk_mq_ops	*mq_ops; + +	unsigned int		*mq_map; + +	/* sw queues */ +	struct blk_mq_ctx __percpu	*queue_ctx; +	unsigned int		nr_queues; + +	/* hw dispatch queues */ +	struct blk_mq_hw_ctx	**queue_hw_ctx; +	unsigned int		nr_hw_queues; +  	/*  	 * Dispatch queue sorting  	 */ @@ -286,12 +350,9 @@ struct request_queue  	struct request		*boundary_rq;  	/* -	 * Auto-unplugging state +	 * Delayed queue handling  	 */ -	struct timer_list	unplug_timer; -	int			unplug_thresh;	/* After this many requests */ -	unsigned long		unplug_delay;	/* After this many jiffies */ -	struct work_struct	unplug_work; +	struct delayed_work	delay_work;  	struct backing_dev_info	backing_dev_info; @@ -302,14 +363,20 @@ struct request_queue  	void			*queuedata;  	/* -	 * queue needs bounce pages for pages above this limit +	 * various queue flags, see QUEUE_* below  	 */ -	gfp_t			bounce_gfp; +	unsigned long		queue_flags;  	/* -	 * various queue flags, see QUEUE_* below +	 * ida allocated id for this queue.  Used to index queues from +	 * ioctx.  	 */ -	unsigned long		queue_flags; +	int			id; + +	/* +	 * queue needs bounce pages for pages above this limit +	 */ +	gfp_t			bounce_gfp;  	/*  	 * protects queue structures from reentrancy. ->__queue_lock should @@ -325,6 +392,17 @@ struct request_queue  	struct kobject kobj;  	/* +	 * mq queue kobject +	 */ +	struct kobject mq_kobj; + +#ifdef CONFIG_PM_RUNTIME +	struct device		*dev; +	int			rpm_status; +	unsigned int		nr_pending; +#endif + +	/*  	 * queue settings  	 */  	unsigned long		nr_requests;	/* Max # of requests */ @@ -332,8 +410,8 @@ struct request_queue  	unsigned int		nr_congestion_off;  	unsigned int		nr_batching; -	void			*dma_drain_buffer;  	unsigned int		dma_drain_size; +	void			*dma_drain_buffer;  	unsigned int		dma_pad_mask;  	unsigned int		dma_alignment; @@ -342,11 +420,24 @@ struct request_queue  	unsigned int		nr_sorted;  	unsigned int		in_flight[2]; +	/* +	 * Number of active block driver functions for which blk_drain_queue() +	 * must wait. Must be incremented around functions that unlock the +	 * queue_lock internally, e.g. scsi_request_fn(). +	 */ +	unsigned int		request_fn_active;  	unsigned int		rq_timeout;  	struct timer_list	timeout;  	struct list_head	timeout_list; +	struct list_head	icq_list; +#ifdef CONFIG_BLK_CGROUP +	DECLARE_BITMAP		(blkcg_pols, BLKCG_MAX_POLS); +	struct blkcg_gq		*root_blkg; +	struct list_head	blkg_list; +#endif +  	struct queue_limits	limits;  	/* @@ -362,15 +453,27 @@ struct request_queue  	 * for flush operations  	 */  	unsigned int		flush_flags; -	unsigned int		flush_seq; -	int			flush_err; -	struct request		flush_rq; -	struct request		*orig_flush_rq; -	struct list_head	pending_flushes; +	unsigned int		flush_not_queueable:1; +	unsigned int		flush_queue_delayed:1; +	unsigned int		flush_pending_idx:1; +	unsigned int		flush_running_idx:1; +	unsigned long		flush_pending_since; +	struct list_head	flush_queue[2]; +	struct list_head	flush_data_in_flight; +	struct request		*flush_rq; +	spinlock_t		mq_flush_lock; + +	struct list_head	requeue_list; +	spinlock_t		requeue_lock; +	struct work_struct	requeue_work;  	struct mutex		sysfs_lock; +	int			bypass_depth; +  #if defined(CONFIG_BLK_DEV_BSG) +	bsg_job_fn		*bsg_job_fn; +	int			bsg_job_size;  	struct bsg_class_device bsg_dev;  #endif @@ -378,44 +481,51 @@ struct request_queue  	/* Throttle data */  	struct throtl_data *td;  #endif +	struct rcu_head		rcu_head; +	wait_queue_head_t	mq_freeze_wq; +	struct percpu_counter	mq_usage_counter; +	struct list_head	all_q_node; + +	struct blk_mq_tag_set	*tag_set; +	struct list_head	tag_set_list;  }; -#define QUEUE_FLAG_CLUSTER	0	/* cluster several segments into 1 */  #define QUEUE_FLAG_QUEUED	1	/* uses generic tag queueing */  #define QUEUE_FLAG_STOPPED	2	/* queue is stopped */  #define	QUEUE_FLAG_SYNCFULL	3	/* read queue has been filled */  #define QUEUE_FLAG_ASYNCFULL	4	/* write queue has been filled */ -#define QUEUE_FLAG_DEAD		5	/* queue being torn down */ -#define QUEUE_FLAG_REENTER	6	/* Re-entrancy avoidance */ -#define QUEUE_FLAG_PLUGGED	7	/* queue is plugged */ -#define QUEUE_FLAG_ELVSWITCH	8	/* don't use elevator, just do FIFO */ -#define QUEUE_FLAG_BIDI		9	/* queue supports bidi requests */ -#define QUEUE_FLAG_NOMERGES    10	/* disable merge attempts */ -#define QUEUE_FLAG_SAME_COMP   11	/* force complete on same CPU */ -#define QUEUE_FLAG_FAIL_IO     12	/* fake timeout */ -#define QUEUE_FLAG_STACKABLE   13	/* supports request stacking */ -#define QUEUE_FLAG_NONROT      14	/* non-rotational device (SSD) */ +#define QUEUE_FLAG_DYING	5	/* queue being torn down */ +#define QUEUE_FLAG_BYPASS	6	/* act as dumb FIFO queue */ +#define QUEUE_FLAG_BIDI		7	/* queue supports bidi requests */ +#define QUEUE_FLAG_NOMERGES     8	/* disable merge attempts */ +#define QUEUE_FLAG_SAME_COMP	9	/* complete on same CPU-group */ +#define QUEUE_FLAG_FAIL_IO     10	/* fake timeout */ +#define QUEUE_FLAG_STACKABLE   11	/* supports request stacking */ +#define QUEUE_FLAG_NONROT      12	/* non-rotational device (SSD) */  #define QUEUE_FLAG_VIRT        QUEUE_FLAG_NONROT /* paravirt device */ -#define QUEUE_FLAG_IO_STAT     15	/* do IO stats */ -#define QUEUE_FLAG_DISCARD     16	/* supports DISCARD */ -#define QUEUE_FLAG_NOXMERGES   17	/* No extended merges */ -#define QUEUE_FLAG_ADD_RANDOM  18	/* Contributes to random pool */ -#define QUEUE_FLAG_SECDISCARD  19	/* supports SECDISCARD */ +#define QUEUE_FLAG_IO_STAT     13	/* do IO stats */ +#define QUEUE_FLAG_DISCARD     14	/* supports DISCARD */ +#define QUEUE_FLAG_NOXMERGES   15	/* No extended merges */ +#define QUEUE_FLAG_ADD_RANDOM  16	/* Contributes to random pool */ +#define QUEUE_FLAG_SECDISCARD  17	/* supports SECDISCARD */ +#define QUEUE_FLAG_SAME_FORCE  18	/* force complete on same CPU */ +#define QUEUE_FLAG_DEAD        19	/* queue tear-down finished */ +#define QUEUE_FLAG_INIT_DONE   20	/* queue is initialized */ +#define QUEUE_FLAG_NO_SG_MERGE 21	/* don't attempt to merge SG segments*/ +#define QUEUE_FLAG_SG_GAPS     22	/* queue doesn't support SG gaps */  #define QUEUE_FLAG_DEFAULT	((1 << QUEUE_FLAG_IO_STAT) |		\ -				 (1 << QUEUE_FLAG_CLUSTER) |		\  				 (1 << QUEUE_FLAG_STACKABLE)	|	\  				 (1 << QUEUE_FLAG_SAME_COMP)	|	\  				 (1 << QUEUE_FLAG_ADD_RANDOM)) -static inline int queue_is_locked(struct request_queue *q) +#define QUEUE_FLAG_MQ_DEFAULT	((1 << QUEUE_FLAG_IO_STAT) |		\ +				 (1 << QUEUE_FLAG_SAME_COMP)) + +static inline void queue_lockdep_assert_held(struct request_queue *q)  { -#ifdef CONFIG_SMP -	spinlock_t *lock = q->queue_lock; -	return lock && spin_is_locked(lock); -#else -	return 1; -#endif +	if (q->queue_lock) +		lockdep_assert_held(q->queue_lock);  }  static inline void queue_flag_set_unlocked(unsigned int flag, @@ -427,7 +537,7 @@ static inline void queue_flag_set_unlocked(unsigned int flag,  static inline int queue_flag_test_and_clear(unsigned int flag,  					    struct request_queue *q)  { -	WARN_ON_ONCE(!queue_is_locked(q)); +	queue_lockdep_assert_held(q);  	if (test_bit(flag, &q->queue_flags)) {  		__clear_bit(flag, &q->queue_flags); @@ -440,7 +550,7 @@ static inline int queue_flag_test_and_clear(unsigned int flag,  static inline int queue_flag_test_and_set(unsigned int flag,  					  struct request_queue *q)  { -	WARN_ON_ONCE(!queue_is_locked(q)); +	queue_lockdep_assert_held(q);  	if (!test_bit(flag, &q->queue_flags)) {  		__set_bit(flag, &q->queue_flags); @@ -452,7 +562,7 @@ static inline int queue_flag_test_and_set(unsigned int flag,  static inline void queue_flag_set(unsigned int flag, struct request_queue *q)  { -	WARN_ON_ONCE(!queue_is_locked(q)); +	queue_lockdep_assert_held(q);  	__set_bit(flag, &q->queue_flags);  } @@ -469,13 +579,16 @@ static inline int queue_in_flight(struct request_queue *q)  static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)  { -	WARN_ON_ONCE(!queue_is_locked(q)); +	queue_lockdep_assert_held(q);  	__clear_bit(flag, &q->queue_flags);  } -#define blk_queue_plugged(q)	test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags)  #define blk_queue_tagged(q)	test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags)  #define blk_queue_stopped(q)	test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags) +#define blk_queue_dying(q)	test_bit(QUEUE_FLAG_DYING, &(q)->queue_flags) +#define blk_queue_dead(q)	test_bit(QUEUE_FLAG_DEAD, &(q)->queue_flags) +#define blk_queue_bypass(q)	test_bit(QUEUE_FLAG_BYPASS, &(q)->queue_flags) +#define blk_queue_init_done(q)	test_bit(QUEUE_FLAG_INIT_DONE, &(q)->queue_flags)  #define blk_queue_nomerges(q)	test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags)  #define blk_queue_noxmerges(q)	\  	test_bit(QUEUE_FLAG_NOXMERGES, &(q)->queue_flags) @@ -494,8 +607,7 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)  #define blk_account_rq(rq) \  	(((rq)->cmd_flags & REQ_STARTED) && \ -	 ((rq)->cmd_type == REQ_TYPE_FS || \ -	  ((rq)->cmd_flags & REQ_DISCARD))) +	 ((rq)->cmd_type == REQ_TYPE_FS))  #define blk_pm_request(rq)	\  	((rq)->cmd_type == REQ_TYPE_PM_SUSPEND || \ @@ -508,7 +620,21 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)  #define list_entry_rq(ptr)	list_entry((ptr), struct request, queuelist) -#define rq_data_dir(rq)		((rq)->cmd_flags & 1) +#define rq_data_dir(rq)		(((rq)->cmd_flags & 1) != 0) + +/* + * Driver can handle struct request, if it either has an old style + * request_fn defined, or is blk-mq based. + */ +static inline bool queue_is_rq_based(struct request_queue *q) +{ +	return q->request_fn || q->mq_ops; +} + +static inline unsigned int blk_queue_cluster(struct request_queue *q) +{ +	return q->limits.cluster; +}  /*   * We regard a request as sync, if either a read or a sync write @@ -523,40 +649,60 @@ static inline bool rq_is_sync(struct request *rq)  	return rw_is_sync(rq->cmd_flags);  } -static inline int blk_queue_full(struct request_queue *q, int sync) +static inline bool blk_rl_full(struct request_list *rl, bool sync)  { -	if (sync) -		return test_bit(QUEUE_FLAG_SYNCFULL, &q->queue_flags); -	return test_bit(QUEUE_FLAG_ASYNCFULL, &q->queue_flags); +	unsigned int flag = sync ? BLK_RL_SYNCFULL : BLK_RL_ASYNCFULL; + +	return rl->flags & flag;  } -static inline void blk_set_queue_full(struct request_queue *q, int sync) +static inline void blk_set_rl_full(struct request_list *rl, bool sync)  { -	if (sync) -		queue_flag_set(QUEUE_FLAG_SYNCFULL, q); -	else -		queue_flag_set(QUEUE_FLAG_ASYNCFULL, q); +	unsigned int flag = sync ? BLK_RL_SYNCFULL : BLK_RL_ASYNCFULL; + +	rl->flags |= flag;  } -static inline void blk_clear_queue_full(struct request_queue *q, int sync) +static inline void blk_clear_rl_full(struct request_list *rl, bool sync)  { -	if (sync) -		queue_flag_clear(QUEUE_FLAG_SYNCFULL, q); -	else -		queue_flag_clear(QUEUE_FLAG_ASYNCFULL, q); +	unsigned int flag = sync ? BLK_RL_SYNCFULL : BLK_RL_ASYNCFULL; + +	rl->flags &= ~flag;  } +static inline bool rq_mergeable(struct request *rq) +{ +	if (rq->cmd_type != REQ_TYPE_FS) +		return false; -/* - * mergeable request must not have _NOMERGE or _BARRIER bit set, nor may - * it already be started by driver. - */ -#define RQ_NOMERGE_FLAGS	\ -	(REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA) -#define rq_mergeable(rq)	\ -	(!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && \ -	 (((rq)->cmd_flags & REQ_DISCARD) || \ -	  (rq)->cmd_type == REQ_TYPE_FS)) +	if (rq->cmd_flags & REQ_NOMERGE_FLAGS) +		return false; + +	return true; +} + +static inline bool blk_check_merge_flags(unsigned int flags1, +					 unsigned int flags2) +{ +	if ((flags1 & REQ_DISCARD) != (flags2 & REQ_DISCARD)) +		return false; + +	if ((flags1 & REQ_SECURE) != (flags2 & REQ_SECURE)) +		return false; + +	if ((flags1 & REQ_WRITE_SAME) != (flags2 & REQ_WRITE_SAME)) +		return false; + +	return true; +} + +static inline bool blk_write_same_mergeable(struct bio *a, struct bio *b) +{ +	if (bio_data(a) == bio_data(b)) +		return true; + +	return false; +}  /*   * q->prep_rq_fn return values @@ -612,7 +758,7 @@ struct rq_map_data {  };  struct req_iterator { -	int i; +	struct bvec_iter iter;  	struct bio *bio;  }; @@ -625,10 +771,11 @@ struct req_iterator {  #define rq_for_each_segment(bvl, _rq, _iter)			\  	__rq_for_each_bio(_iter.bio, _rq)			\ -		bio_for_each_segment(bvl, _iter.bio, _iter.i) +		bio_for_each_segment(bvl, _iter.bio, _iter.iter) -#define rq_iter_last(rq, _iter)					\ -		(_iter.bio->bi_next == NULL && _iter.i == _iter.bio->bi_vcnt-1) +#define rq_iter_last(bvec, _iter)				\ +		(_iter.bio->bi_next == NULL &&			\ +		 bio_iter_last(bvec, _iter.iter))  #ifndef ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE  # error	"You should define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE for your platform" @@ -643,7 +790,6 @@ static inline void rq_flush_dcache_pages(struct request *rq)  extern int blk_register_queue(struct gendisk *disk);  extern void blk_unregister_queue(struct gendisk *disk); -extern void register_disk(struct gendisk *dev);  extern void generic_make_request(struct bio *bio);  extern void blk_rq_init(struct request_queue *q, struct request *rq);  extern void blk_put_request(struct request *); @@ -651,7 +797,7 @@ extern void __blk_put_request(struct request_queue *, struct request *);  extern struct request *blk_get_request(struct request_queue *, int, gfp_t);  extern struct request *blk_make_request(struct request_queue *, struct bio *,  					gfp_t); -extern void blk_insert_request(struct request_queue *, struct request *, int, void *); +extern void blk_rq_set_block_pc(struct request *);  extern void blk_requeue_request(struct request_queue *, struct request *);  extern void blk_add_request_payload(struct request *rq, struct page *page,  		unsigned int len); @@ -664,15 +810,18 @@ extern int blk_rq_prep_clone(struct request *rq, struct request *rq_src,  extern void blk_rq_unprep_clone(struct request *rq);  extern int blk_insert_cloned_request(struct request_queue *q,  				     struct request *rq); -extern void blk_plug_device(struct request_queue *); -extern void blk_plug_device_unlocked(struct request_queue *); -extern int blk_remove_plug(struct request_queue *); +extern void blk_delay_queue(struct request_queue *, unsigned long);  extern void blk_recount_segments(struct request_queue *, struct bio *); +extern int scsi_verify_blk_ioctl(struct block_device *, unsigned int); +extern int scsi_cmd_blk_ioctl(struct block_device *, fmode_t, +			      unsigned int, void __user *);  extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t,  			  unsigned int, void __user *);  extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t,  			 struct scsi_ioctl_command __user *); +extern void blk_queue_bio(struct request_queue *q, struct bio *bio); +  /*   * A queue has just exitted congestion.  Note this in the global counter of   * congested queues, and wake up anyone who was waiting for requests to be @@ -696,21 +845,21 @@ extern void blk_start_queue(struct request_queue *q);  extern void blk_stop_queue(struct request_queue *q);  extern void blk_sync_queue(struct request_queue *q);  extern void __blk_stop_queue(struct request_queue *q); -extern void __blk_run_queue(struct request_queue *); +extern void __blk_run_queue(struct request_queue *q);  extern void blk_run_queue(struct request_queue *); +extern void blk_run_queue_async(struct request_queue *q);  extern int blk_rq_map_user(struct request_queue *, struct request *,  			   struct rq_map_data *, void __user *, unsigned long,  			   gfp_t);  extern int blk_rq_unmap_user(struct bio *);  extern int blk_rq_map_kern(struct request_queue *, struct request *, void *, unsigned int, gfp_t);  extern int blk_rq_map_user_iov(struct request_queue *, struct request *, -			       struct rq_map_data *, struct sg_iovec *, int, -			       unsigned int, gfp_t); +			       struct rq_map_data *, const struct sg_iovec *, +			       int, unsigned int, gfp_t);  extern int blk_execute_rq(struct request_queue *, struct gendisk *,  			  struct request *, int);  extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *,  				  struct request *, int, rq_end_io_fn *); -extern void blk_unplug(struct request_queue *q);  static inline struct request_queue *bdev_get_queue(struct block_device *bdev)  { @@ -752,6 +901,57 @@ static inline unsigned int blk_rq_cur_sectors(const struct request *rq)  	return blk_rq_cur_bytes(rq) >> 9;  } +static inline unsigned int blk_queue_get_max_sectors(struct request_queue *q, +						     unsigned int cmd_flags) +{ +	if (unlikely(cmd_flags & REQ_DISCARD)) +		return min(q->limits.max_discard_sectors, UINT_MAX >> 9); + +	if (unlikely(cmd_flags & REQ_WRITE_SAME)) +		return q->limits.max_write_same_sectors; + +	return q->limits.max_sectors; +} + +/* + * Return maximum size of a request at given offset. Only valid for + * file system requests. + */ +static inline unsigned int blk_max_size_offset(struct request_queue *q, +					       sector_t offset) +{ +	if (!q->limits.chunk_sectors) +		return q->limits.max_sectors; + +	return q->limits.chunk_sectors - +			(offset & (q->limits.chunk_sectors - 1)); +} + +static inline unsigned int blk_rq_get_max_sectors(struct request *rq) +{ +	struct request_queue *q = rq->q; + +	if (unlikely(rq->cmd_type == REQ_TYPE_BLOCK_PC)) +		return q->limits.max_hw_sectors; + +	if (!q->limits.chunk_sectors) +		return blk_queue_get_max_sectors(q, rq->cmd_flags); + +	return min(blk_max_size_offset(q, blk_rq_pos(rq)), +			blk_queue_get_max_sectors(q, rq->cmd_flags)); +} + +static inline unsigned int blk_rq_count_bios(struct request *rq) +{ +	unsigned int nr_bios = 0; +	struct bio *bio; + +	__rq_for_each_bio(bio, rq) +		nr_bios++; + +	return nr_bios; +} +  /*   * Request issue related functions.   */ @@ -774,6 +974,7 @@ extern struct request *blk_fetch_request(struct request_queue *q);   */  extern bool blk_update_request(struct request *rq, int error,  			       unsigned int nr_bytes); +extern void blk_finish_request(struct request *rq, int error);  extern bool blk_end_request(struct request *rq, int error,  			    unsigned int nr_bytes);  extern void blk_end_request_all(struct request *rq, int error); @@ -788,7 +989,6 @@ extern bool __blk_end_request_err(struct request *rq, int error);  extern void blk_complete_request(struct request *);  extern void __blk_complete_request(struct request *);  extern void blk_abort_request(struct request *); -extern void blk_abort_queue(struct request_queue *);  extern void blk_unprep_request(struct request *);  /* @@ -796,20 +996,21 @@ extern void blk_unprep_request(struct request *);   */  extern struct request_queue *blk_init_queue_node(request_fn_proc *rfn,  					spinlock_t *lock, int node_id); -extern struct request_queue *blk_init_allocated_queue_node(struct request_queue *, -							   request_fn_proc *, -							   spinlock_t *, int node_id);  extern struct request_queue *blk_init_queue(request_fn_proc *, spinlock_t *);  extern struct request_queue *blk_init_allocated_queue(struct request_queue *,  						      request_fn_proc *, spinlock_t *);  extern void blk_cleanup_queue(struct request_queue *);  extern void blk_queue_make_request(struct request_queue *, make_request_fn *);  extern void blk_queue_bounce_limit(struct request_queue *, u64); +extern void blk_limits_max_hw_sectors(struct queue_limits *, unsigned int);  extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int); +extern void blk_queue_chunk_sectors(struct request_queue *, unsigned int);  extern void blk_queue_max_segments(struct request_queue *, unsigned short);  extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);  extern void blk_queue_max_discard_sectors(struct request_queue *q,  		unsigned int max_discard_sectors); +extern void blk_queue_max_write_same_sectors(struct request_queue *q, +		unsigned int max_write_same_sectors);  extern void blk_queue_logical_block_size(struct request_queue *, unsigned short);  extern void blk_queue_physical_block_size(struct request_queue *, unsigned int);  extern void blk_queue_alignment_offset(struct request_queue *q, @@ -819,6 +1020,7 @@ extern void blk_queue_io_min(struct request_queue *q, unsigned int min);  extern void blk_limits_io_opt(struct queue_limits *limits, unsigned int opt);  extern void blk_queue_io_opt(struct request_queue *q, unsigned int opt);  extern void blk_set_default_limits(struct queue_limits *lim); +extern void blk_set_stacking_limits(struct queue_limits *lim);  extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,  			    sector_t offset);  extern int bdev_stack_limits(struct queue_limits *t, struct block_device *bdev, @@ -842,22 +1044,104 @@ extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *);  extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *);  extern void blk_queue_rq_timeout(struct request_queue *, unsigned int);  extern void blk_queue_flush(struct request_queue *q, unsigned int flush); +extern void blk_queue_flush_queueable(struct request_queue *q, bool queueable);  extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);  extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *); +extern int blk_bio_map_sg(struct request_queue *q, struct bio *bio, +			  struct scatterlist *sglist);  extern void blk_dump_rq_flags(struct request *, char *); -extern void generic_unplug_device(struct request_queue *);  extern long nr_blockdev_pages(void); -int blk_get_queue(struct request_queue *); +bool __must_check blk_get_queue(struct request_queue *);  struct request_queue *blk_alloc_queue(gfp_t);  struct request_queue *blk_alloc_queue_node(gfp_t, int);  extern void blk_put_queue(struct request_queue *);  /* + * block layer runtime pm functions + */ +#ifdef CONFIG_PM_RUNTIME +extern void blk_pm_runtime_init(struct request_queue *q, struct device *dev); +extern int blk_pre_runtime_suspend(struct request_queue *q); +extern void blk_post_runtime_suspend(struct request_queue *q, int err); +extern void blk_pre_runtime_resume(struct request_queue *q); +extern void blk_post_runtime_resume(struct request_queue *q, int err); +#else +static inline void blk_pm_runtime_init(struct request_queue *q, +	struct device *dev) {} +static inline int blk_pre_runtime_suspend(struct request_queue *q) +{ +	return -ENOSYS; +} +static inline void blk_post_runtime_suspend(struct request_queue *q, int err) {} +static inline void blk_pre_runtime_resume(struct request_queue *q) {} +static inline void blk_post_runtime_resume(struct request_queue *q, int err) {} +#endif + +/* + * blk_plug permits building a queue of related requests by holding the I/O + * fragments for a short period. This allows merging of sequential requests + * into single larger request. As the requests are moved from a per-task list to + * the device's request_queue in a batch, this results in improved scalability + * as the lock contention for request_queue lock is reduced. + * + * It is ok not to disable preemption when adding the request to the plug list + * or when attempting a merge, because blk_schedule_flush_list() will only flush + * the plug list when the task sleeps by itself. For details, please see + * schedule() where blk_schedule_flush_plug() is called. + */ +struct blk_plug { +	struct list_head list; /* requests */ +	struct list_head mq_list; /* blk-mq requests */ +	struct list_head cb_list; /* md requires an unplug callback */ +}; +#define BLK_MAX_REQUEST_COUNT 16 + +struct blk_plug_cb; +typedef void (*blk_plug_cb_fn)(struct blk_plug_cb *, bool); +struct blk_plug_cb { +	struct list_head list; +	blk_plug_cb_fn callback; +	void *data; +}; +extern struct blk_plug_cb *blk_check_plugged(blk_plug_cb_fn unplug, +					     void *data, int size); +extern void blk_start_plug(struct blk_plug *); +extern void blk_finish_plug(struct blk_plug *); +extern void blk_flush_plug_list(struct blk_plug *, bool); + +static inline void blk_flush_plug(struct task_struct *tsk) +{ +	struct blk_plug *plug = tsk->plug; + +	if (plug) +		blk_flush_plug_list(plug, false); +} + +static inline void blk_schedule_flush_plug(struct task_struct *tsk) +{ +	struct blk_plug *plug = tsk->plug; + +	if (plug) +		blk_flush_plug_list(plug, true); +} + +static inline bool blk_needs_flush_plug(struct task_struct *tsk) +{ +	struct blk_plug *plug = tsk->plug; + +	return plug && +		(!list_empty(&plug->list) || +		 !list_empty(&plug->mq_list) || +		 !list_empty(&plug->cb_list)); +} + +/*   * tag stuff   */ -#define blk_rq_tagged(rq)		((rq)->cmd_flags & REQ_QUEUED) +#define blk_rq_tagged(rq) \ +	((rq)->mq_ctx || ((rq)->cmd_flags & REQ_QUEUED))  extern int blk_queue_start_tag(struct request_queue *, struct request *);  extern struct request *blk_queue_find_tag(struct request_queue *, int);  extern void blk_queue_end_tag(struct request_queue *, struct request *); @@ -881,6 +1165,8 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt,  extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *);  extern int blkdev_issue_discard(struct block_device *bdev, sector_t sector,  		sector_t nr_sects, gfp_t gfp_mask, unsigned long flags); +extern int blkdev_issue_write_same(struct block_device *bdev, sector_t sector, +		sector_t nr_sects, gfp_t gfp_mask, struct page *page);  extern int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,  			sector_t nr_sects, gfp_t gfp_mask);  static inline int sb_issue_discard(struct super_block *sb, sector_t block, @@ -1026,15 +1312,40 @@ static inline int queue_discard_alignment(struct request_queue *q)  static inline int queue_limit_discard_alignment(struct queue_limits *lim, sector_t sector)  { -	unsigned int alignment = (sector << 9) & (lim->discard_granularity - 1); +	unsigned int alignment, granularity, offset; + +	if (!lim->max_discard_sectors) +		return 0; + +	/* Why are these in bytes, not sectors? */ +	alignment = lim->discard_alignment >> 9; +	granularity = lim->discard_granularity >> 9; +	if (!granularity) +		return 0; -	return (lim->discard_granularity + lim->discard_alignment - alignment) -		& (lim->discard_granularity - 1); +	/* Offset of the partition start in 'granularity' sectors */ +	offset = sector_div(sector, granularity); + +	/* And why do we do this modulus *again* in blkdev_issue_discard()? */ +	offset = (granularity + alignment - offset) % granularity; + +	/* Turn it back into bytes, gaah */ +	return offset << 9; +} + +static inline int bdev_discard_alignment(struct block_device *bdev) +{ +	struct request_queue *q = bdev_get_queue(bdev); + +	if (bdev != bdev->bd_contains) +		return bdev->bd_part->discard_alignment; + +	return q->limits.discard_alignment;  }  static inline unsigned int queue_discard_zeroes_data(struct request_queue *q)  { -	if (q->limits.discard_zeroes_data == 1) +	if (q->limits.max_discard_sectors && q->limits.discard_zeroes_data == 1)  		return 1;  	return 0; @@ -1045,6 +1356,16 @@ static inline unsigned int bdev_discard_zeroes_data(struct block_device *bdev)  	return queue_discard_zeroes_data(bdev_get_queue(bdev));  } +static inline unsigned int bdev_write_same(struct block_device *bdev) +{ +	struct request_queue *q = bdev_get_queue(bdev); + +	if (q) +		return q->limits.max_write_same_sectors; + +	return 0; +} +  static inline int queue_dma_alignment(struct request_queue *q)  {  	return q ? q->dma_alignment : 511; @@ -1073,6 +1394,11 @@ static inline unsigned int block_size(struct block_device *bdev)  	return bdev->bd_block_size;  } +static inline bool queue_flush_queueable(struct request_queue *q) +{ +	return !q->flush_not_queueable; +} +  typedef struct {struct page *v;} Sector;  unsigned char *read_dev_sector(struct block_device *, sector_t, Sector *); @@ -1083,8 +1409,9 @@ static inline void put_dev_sector(Sector p)  }  struct work_struct; -int kblockd_schedule_work(struct request_queue *q, struct work_struct *work); -int kblockd_schedule_delayed_work(struct request_queue *q, struct delayed_work *dwork, unsigned long delay); +int kblockd_schedule_work(struct work_struct *work); +int kblockd_schedule_delayed_work(struct delayed_work *dwork, unsigned long delay); +int kblockd_schedule_delayed_work_on(int cpu, struct delayed_work *dwork, unsigned long delay);  #ifdef CONFIG_BLK_CGROUP  /* @@ -1128,24 +1455,6 @@ static inline uint64_t rq_io_start_time_ns(struct request *req)  }  #endif -#ifdef CONFIG_BLK_DEV_THROTTLING -extern int blk_throtl_init(struct request_queue *q); -extern void blk_throtl_exit(struct request_queue *q); -extern int blk_throtl_bio(struct request_queue *q, struct bio **bio); -extern void throtl_schedule_delayed_work(struct request_queue *q, unsigned long delay); -extern void throtl_shutdown_timer_wq(struct request_queue *q); -#else /* CONFIG_BLK_DEV_THROTTLING */ -static inline int blk_throtl_bio(struct request_queue *q, struct bio **bio) -{ -	return 0; -} - -static inline int blk_throtl_init(struct request_queue *q) { return 0; } -static inline int blk_throtl_exit(struct request_queue *q) { return 0; } -static inline void throtl_schedule_delayed_work(struct request_queue *q, unsigned long delay) {} -static inline void throtl_shutdown_timer_wq(struct request_queue *q) {} -#endif /* CONFIG_BLK_DEV_THROTTLING */ -  #define MODULE_ALIAS_BLOCKDEV(major,minor) \  	MODULE_ALIAS("block-major-" __stringify(major) "-" __stringify(minor))  #define MODULE_ALIAS_BLOCKDEV_MAJOR(major) \ @@ -1186,6 +1495,7 @@ struct blk_integrity {  	struct kobject		kobj;  }; +extern bool blk_integrity_is_initialized(struct gendisk *);  extern int blk_integrity_register(struct gendisk *, struct blk_integrity *);  extern void blk_integrity_unregister(struct gendisk *);  extern int blk_integrity_compare(struct gendisk *, struct gendisk *); @@ -1230,28 +1540,84 @@ queue_max_integrity_segments(struct request_queue *q)  #else /* CONFIG_BLK_DEV_INTEGRITY */ -#define blk_integrity_rq(rq)			(0) -#define blk_rq_count_integrity_sg(a, b)		(0) -#define blk_rq_map_integrity_sg(a, b, c)	(0) -#define bdev_get_integrity(a)			(0) -#define blk_get_integrity(a)			(0) -#define blk_integrity_compare(a, b)		(0) -#define blk_integrity_register(a, b)		(0) -#define blk_integrity_unregister(a)		do { } while (0); -#define blk_queue_max_integrity_segments(a, b)	do { } while (0); -#define queue_max_integrity_segments(a)		(0) -#define blk_integrity_merge_rq(a, b, c)		(0) -#define blk_integrity_merge_bio(a, b, c)	(0) +struct bio; +struct block_device; +struct gendisk; +struct blk_integrity; + +static inline int blk_integrity_rq(struct request *rq) +{ +	return 0; +} +static inline int blk_rq_count_integrity_sg(struct request_queue *q, +					    struct bio *b) +{ +	return 0; +} +static inline int blk_rq_map_integrity_sg(struct request_queue *q, +					  struct bio *b, +					  struct scatterlist *s) +{ +	return 0; +} +static inline struct blk_integrity *bdev_get_integrity(struct block_device *b) +{ +	return 0; +} +static inline struct blk_integrity *blk_get_integrity(struct gendisk *disk) +{ +	return NULL; +} +static inline int blk_integrity_compare(struct gendisk *a, struct gendisk *b) +{ +	return 0; +} +static inline int blk_integrity_register(struct gendisk *d, +					 struct blk_integrity *b) +{ +	return 0; +} +static inline void blk_integrity_unregister(struct gendisk *d) +{ +} +static inline void blk_queue_max_integrity_segments(struct request_queue *q, +						    unsigned int segs) +{ +} +static inline unsigned short queue_max_integrity_segments(struct request_queue *q) +{ +	return 0; +} +static inline int blk_integrity_merge_rq(struct request_queue *rq, +					 struct request *r1, +					 struct request *r2) +{ +	return 0; +} +static inline int blk_integrity_merge_bio(struct request_queue *rq, +					  struct request *r, +					  struct bio *b) +{ +	return 0; +} +static inline bool blk_integrity_is_initialized(struct gendisk *g) +{ +	return 0; +}  #endif /* CONFIG_BLK_DEV_INTEGRITY */  struct block_device_operations {  	int (*open) (struct block_device *, fmode_t); -	int (*release) (struct gendisk *, fmode_t); +	void (*release) (struct gendisk *, fmode_t); +	int (*rw_page)(struct block_device *, sector_t, struct page *, int rw);  	int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);  	int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);  	int (*direct_access) (struct block_device *, sector_t,  						void **, unsigned long *); +	unsigned int (*check_events) (struct gendisk *disk, +				      unsigned int clearing); +	/* ->media_changed() is DEPRECATED, use ->check_events() instead */  	int (*media_changed) (struct gendisk *);  	void (*unlock_native_capacity) (struct gendisk *);  	int (*revalidate_disk) (struct gendisk *); @@ -1263,7 +1629,13 @@ struct block_device_operations {  extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int,  				 unsigned long); +extern int bdev_read_page(struct block_device *, sector_t, struct page *); +extern int bdev_write_page(struct block_device *, sector_t, struct page *, +						struct writeback_control *);  #else /* CONFIG_BLOCK */ + +struct block_device; +  /*   * stubs for when the block layer is configured out   */ @@ -1274,6 +1646,37 @@ static inline long nr_blockdev_pages(void)  	return 0;  } +struct blk_plug { +}; + +static inline void blk_start_plug(struct blk_plug *plug) +{ +} + +static inline void blk_finish_plug(struct blk_plug *plug) +{ +} + +static inline void blk_flush_plug(struct task_struct *task) +{ +} + +static inline void blk_schedule_flush_plug(struct task_struct *task) +{ +} + + +static inline bool blk_needs_flush_plug(struct task_struct *tsk) +{ +	return false; +} + +static inline int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask, +				     sector_t *error_sector) +{ +	return 0; +} +  #endif /* CONFIG_BLOCK */  #endif  | 
