diff options
Diffstat (limited to 'include/linux/blkdev.h')
| -rw-r--r-- | include/linux/blkdev.h | 107 | 
1 files changed, 81 insertions, 26 deletions
| diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 38a5ff772a37..c0d2b7927c1f 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -35,6 +35,7 @@ struct sg_io_hdr;  struct bsg_job;  struct blkcg_gq;  struct blk_flush_queue; +struct pr_ops;  #define BLKDEV_MIN_RQ	4  #define BLKDEV_MAX_RQ	128	/* Default maximum */ @@ -208,7 +209,7 @@ static inline unsigned short req_get_ioprio(struct request *req)  struct blk_queue_ctx;  typedef void (request_fn_proc) (struct request_queue *q); -typedef void (make_request_fn) (struct request_queue *q, struct bio *bio); +typedef blk_qc_t (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 *); @@ -369,6 +370,10 @@ struct request_queue {  	 */  	struct kobject mq_kobj; +#ifdef  CONFIG_BLK_DEV_INTEGRITY +	struct blk_integrity integrity; +#endif	/* CONFIG_BLK_DEV_INTEGRITY */ +  #ifdef CONFIG_PM  	struct device		*dev;  	int			rpm_status; @@ -450,12 +455,14 @@ struct request_queue {  #endif  	struct rcu_head		rcu_head;  	wait_queue_head_t	mq_freeze_wq; -	struct percpu_ref	mq_usage_counter; +	struct percpu_ref	q_usage_counter;  	struct list_head	all_q_node;  	struct blk_mq_tag_set	*tag_set;  	struct list_head	tag_set_list;  	struct bio_set		*bio_split; + +	bool			mq_sysfs_init_done;  };  #define QUEUE_FLAG_QUEUED	1	/* uses generic tag queueing */ @@ -480,6 +487,7 @@ struct request_queue {  #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_POLL	       22	/* IO polling enabled if set */  #define QUEUE_FLAG_DEFAULT	((1 << QUEUE_FLAG_IO_STAT) |		\  				 (1 << QUEUE_FLAG_STACKABLE)	|	\ @@ -754,7 +762,7 @@ 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 generic_make_request(struct bio *bio); +extern blk_qc_t 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 *);  extern void __blk_put_request(struct request_queue *, struct request *); @@ -786,6 +794,8 @@ extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t,  extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t,  			 struct scsi_ioctl_command __user *); +extern int blk_queue_enter(struct request_queue *q, gfp_t gfp); +extern void blk_queue_exit(struct request_queue *q);  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); @@ -807,6 +817,8 @@ extern int blk_execute_rq(struct request_queue *, struct gendisk *,  extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *,  				  struct request *, int, rq_end_io_fn *); +bool blk_poll(struct request_queue *q, blk_qc_t cookie); +  static inline struct request_queue *bdev_get_queue(struct block_device *bdev)  {  	return bdev->bd_disk->queue;	/* this is never NULL */ @@ -1368,6 +1380,26 @@ static inline bool bvec_gap_to_prev(struct request_queue *q,  		((bprv->bv_offset + bprv->bv_len) & queue_virt_boundary(q));  } +static inline bool bio_will_gap(struct request_queue *q, struct bio *prev, +			 struct bio *next) +{ +	if (!bio_has_data(prev)) +		return false; + +	return bvec_gap_to_prev(q, &prev->bi_io_vec[prev->bi_vcnt - 1], +				next->bi_io_vec[0].bv_offset); +} + +static inline bool req_gap_back_merge(struct request *req, struct bio *bio) +{ +	return bio_will_gap(req->q, req->biotail, bio); +} + +static inline bool req_gap_front_merge(struct request *req, struct bio *bio) +{ +	return bio_will_gap(req->q, bio, req->bio); +} +  struct work_struct;  int kblockd_schedule_work(struct work_struct *work);  int kblockd_schedule_delayed_work(struct delayed_work *dwork, unsigned long delay); @@ -1440,22 +1472,13 @@ struct blk_integrity_iter {  typedef int (integrity_processing_fn) (struct blk_integrity_iter *); -struct blk_integrity { -	integrity_processing_fn	*generate_fn; -	integrity_processing_fn	*verify_fn; - -	unsigned short		flags; -	unsigned short		tuple_size; -	unsigned short		interval; -	unsigned short		tag_size; - -	const char		*name; - -	struct kobject		kobj; +struct blk_integrity_profile { +	integrity_processing_fn		*generate_fn; +	integrity_processing_fn		*verify_fn; +	const char			*name;  }; -extern bool blk_integrity_is_initialized(struct gendisk *); -extern int blk_integrity_register(struct gendisk *, struct blk_integrity *); +extern void blk_integrity_register(struct gendisk *, struct blk_integrity *);  extern void blk_integrity_unregister(struct gendisk *);  extern int blk_integrity_compare(struct gendisk *, struct gendisk *);  extern int blk_rq_map_integrity_sg(struct request_queue *, struct bio *, @@ -1466,15 +1489,20 @@ extern bool blk_integrity_merge_rq(struct request_queue *, struct request *,  extern bool blk_integrity_merge_bio(struct request_queue *, struct request *,  				    struct bio *); -static inline -struct blk_integrity *bdev_get_integrity(struct block_device *bdev) +static inline struct blk_integrity *blk_get_integrity(struct gendisk *disk)  { -	return bdev->bd_disk->integrity; +	struct blk_integrity *bi = &disk->queue->integrity; + +	if (!bi->profile) +		return NULL; + +	return bi;  } -static inline struct blk_integrity *blk_get_integrity(struct gendisk *disk) +static inline +struct blk_integrity *bdev_get_integrity(struct block_device *bdev)  { -	return disk->integrity; +	return blk_get_integrity(bdev->bd_disk);  }  static inline bool blk_integrity_rq(struct request *rq) @@ -1494,6 +1522,26 @@ queue_max_integrity_segments(struct request_queue *q)  	return q->limits.max_integrity_segments;  } +static inline bool integrity_req_gap_back_merge(struct request *req, +						struct bio *next) +{ +	struct bio_integrity_payload *bip = bio_integrity(req->bio); +	struct bio_integrity_payload *bip_next = bio_integrity(next); + +	return bvec_gap_to_prev(req->q, &bip->bip_vec[bip->bip_vcnt - 1], +				bip_next->bip_vec[0].bv_offset); +} + +static inline bool integrity_req_gap_front_merge(struct request *req, +						 struct bio *bio) +{ +	struct bio_integrity_payload *bip = bio_integrity(bio); +	struct bio_integrity_payload *bip_next = bio_integrity(req->bio); + +	return bvec_gap_to_prev(req->q, &bip->bip_vec[bip->bip_vcnt - 1], +				bip_next->bip_vec[0].bv_offset); +} +  #else /* CONFIG_BLK_DEV_INTEGRITY */  struct bio; @@ -1528,10 +1576,9 @@ static inline int blk_integrity_compare(struct gendisk *a, struct gendisk *b)  {  	return 0;  } -static inline int blk_integrity_register(struct gendisk *d, +static inline void blk_integrity_register(struct gendisk *d,  					 struct blk_integrity *b)  { -	return 0;  }  static inline void blk_integrity_unregister(struct gendisk *d)  { @@ -1556,9 +1603,16 @@ static inline bool blk_integrity_merge_bio(struct request_queue *rq,  {  	return true;  } -static inline bool blk_integrity_is_initialized(struct gendisk *g) + +static inline bool integrity_req_gap_back_merge(struct request *req, +						struct bio *next) +{ +	return false; +} +static inline bool integrity_req_gap_front_merge(struct request *req, +						 struct bio *bio)  { -	return 0; +	return false;  }  #endif /* CONFIG_BLK_DEV_INTEGRITY */ @@ -1581,6 +1635,7 @@ struct block_device_operations {  	/* this callback is with swap_lock and sometimes page table lock held */  	void (*swap_slot_free_notify) (struct block_device *, unsigned long);  	struct module *owner; +	const struct pr_ops *pr_ops;  };  extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int, |