#include <linux/interrupt.h>
#include <linux/blkdev.h>
#include <linux/blk-mq.h>
#include <linux/hdreg.h>
#include <linux/cdrom.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/scatterlist.h>
#include <linux/bitmap.h>
#include <linux/list.h>
#include <linux/workqueue.h>
#include <linux/sched/mm.h>
#include <xen/xen.h>
#include <xen/xenbus.h>
#include <xen/grant_table.h>
#include <xen/events.h>
#include <xen/page.h>
#include <xen/platform_pci.h>
#include <xen/interface/grant_table.h>
#include <xen/interface/io/blkif.h>
#include <xen/interface/io/protocols.h>
#include <asm/xen/hypervisor.h>
#define HAS_EXTRA_REQ …
enum blkif_state { … };
struct grant { … };
enum blk_req_status { … };
struct blk_shadow { … };
struct blkif_req { … };
static inline struct blkif_req *blkif_req(struct request *rq)
{ … }
static DEFINE_MUTEX(blkfront_mutex);
static const struct block_device_operations xlvbd_block_fops;
static struct delayed_work blkfront_work;
static LIST_HEAD(info_list);
static unsigned int xen_blkif_max_segments = …;
module_param_named(max_indirect_segments, xen_blkif_max_segments, uint, 0444);
MODULE_PARM_DESC(…) …;
static unsigned int xen_blkif_max_queues = …;
module_param_named(max_queues, xen_blkif_max_queues, uint, 0444);
MODULE_PARM_DESC(…) …;
static unsigned int xen_blkif_max_ring_order;
module_param_named(max_ring_page_order, xen_blkif_max_ring_order, int, 0444);
MODULE_PARM_DESC(…) …;
static bool __read_mostly xen_blkif_trusted = …;
module_param_named(trusted, xen_blkif_trusted, bool, 0644);
MODULE_PARM_DESC(…) …;
#define BLK_RING_SIZE(info) …
#define RINGREF_NAME_LEN …
#define QUEUE_NAME_LEN …
struct blkfront_ring_info { … };
struct blkfront_info
{ … };
static unsigned int nr_minors;
static unsigned long *minors;
static DEFINE_SPINLOCK(minor_lock);
#define PARTS_PER_DISK …
#define PARTS_PER_EXT_DISK …
#define BLKIF_MAJOR(dev) …
#define BLKIF_MINOR(dev) …
#define EXT_SHIFT …
#define EXTENDED …
#define VDEV_IS_EXTENDED(dev) …
#define BLKIF_MINOR_EXT(dev) …
#define EMULATED_HD_DISK_MINOR_OFFSET …
#define EMULATED_HD_DISK_NAME_OFFSET …
#define EMULATED_SD_DISK_MINOR_OFFSET …
#define EMULATED_SD_DISK_NAME_OFFSET …
#define DEV_NAME …
#define GRANTS_PER_PSEG …
#define GRANTS_PER_INDIRECT_FRAME …
#define INDIRECT_GREFS(_grants) …
static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo);
static void blkfront_gather_backend_features(struct blkfront_info *info);
static int negotiate_mq(struct blkfront_info *info);
#define for_each_rinfo(info, ptr, idx) …
static inline struct blkfront_ring_info *
get_rinfo(const struct blkfront_info *info, unsigned int i)
{ … }
static int get_id_from_freelist(struct blkfront_ring_info *rinfo)
{ … }
static int add_id_to_freelist(struct blkfront_ring_info *rinfo,
unsigned long id)
{ … }
static int fill_grant_buffer(struct blkfront_ring_info *rinfo, int num)
{ … }
static struct grant *get_free_grant(struct blkfront_ring_info *rinfo)
{ … }
static inline void grant_foreign_access(const struct grant *gnt_list_entry,
const struct blkfront_info *info)
{ … }
static struct grant *get_grant(grant_ref_t *gref_head,
unsigned long gfn,
struct blkfront_ring_info *rinfo)
{ … }
static struct grant *get_indirect_grant(grant_ref_t *gref_head,
struct blkfront_ring_info *rinfo)
{ … }
static const char *op_name(int op)
{ … }
static int xlbd_reserve_minors(unsigned int minor, unsigned int nr)
{ … }
static void xlbd_release_minors(unsigned int minor, unsigned int nr)
{ … }
static void blkif_restart_queue_callback(void *arg)
{ … }
static int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg)
{ … }
static int blkif_ioctl(struct block_device *bdev, blk_mode_t mode,
unsigned command, unsigned long argument)
{ … }
static unsigned long blkif_ring_get_request(struct blkfront_ring_info *rinfo,
struct request *req,
struct blkif_request **ring_req)
{ … }
static int blkif_queue_discard_req(struct request *req, struct blkfront_ring_info *rinfo)
{ … }
struct setup_rw_req { … };
static void blkif_setup_rw_req_grant(unsigned long gfn, unsigned int offset,
unsigned int len, void *data)
{ … }
static void blkif_setup_extra_req(struct blkif_request *first,
struct blkif_request *second)
{ … }
static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *rinfo)
{ … }
static int blkif_queue_request(struct request *req, struct blkfront_ring_info *rinfo)
{ … }
static inline void flush_requests(struct blkfront_ring_info *rinfo)
{ … }
static blk_status_t blkif_queue_rq(struct blk_mq_hw_ctx *hctx,
const struct blk_mq_queue_data *qd)
{ … }
static void blkif_complete_rq(struct request *rq)
{ … }
static const struct blk_mq_ops blkfront_mq_ops = …;
static void blkif_set_queue_limits(const struct blkfront_info *info,
struct queue_limits *lim)
{ … }
static const char *flush_info(struct blkfront_info *info)
{ … }
static void xlvbd_flush(struct blkfront_info *info)
{ … }
static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset)
{ … }
static char *encode_disk_name(char *ptr, unsigned int n)
{ … }
static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
struct blkfront_info *info)
{ … }
static inline void kick_pending_request_queues_locked(struct blkfront_ring_info *rinfo)
{ … }
static void kick_pending_request_queues(struct blkfront_ring_info *rinfo)
{ … }
static void blkif_restart_queue(struct work_struct *work)
{ … }
static void blkif_free_ring(struct blkfront_ring_info *rinfo)
{ … }
static void blkif_free(struct blkfront_info *info, int suspend)
{ … }
struct copy_from_grant { … };
static void blkif_copy_from_grant(unsigned long gfn, unsigned int offset,
unsigned int len, void *data)
{ … }
static enum blk_req_status blkif_rsp_to_req_status(int rsp)
{ … }
static int blkif_get_final_status(enum blk_req_status s1,
enum blk_req_status s2)
{ … }
static int blkif_completion(unsigned long *id,
struct blkfront_ring_info *rinfo,
struct blkif_response *bret)
{ … }
static irqreturn_t blkif_interrupt(int irq, void *dev_id)
{ … }
static int setup_blkring(struct xenbus_device *dev,
struct blkfront_ring_info *rinfo)
{ … }
static int write_per_ring_nodes(struct xenbus_transaction xbt,
struct blkfront_ring_info *rinfo, const char *dir)
{ … }
static bool feature_persistent = …;
module_param(feature_persistent, bool, 0644);
MODULE_PARM_DESC(…) …;
static int talk_to_blkback(struct xenbus_device *dev,
struct blkfront_info *info)
{ … }
static int negotiate_mq(struct blkfront_info *info)
{ … }
static int blkfront_probe(struct xenbus_device *dev,
const struct xenbus_device_id *id)
{ … }
static int blkif_recover(struct blkfront_info *info)
{ … }
static int blkfront_resume(struct xenbus_device *dev)
{ … }
static void blkfront_closing(struct blkfront_info *info)
{ … }
static void blkfront_setup_discard(struct blkfront_info *info)
{ … }
static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo)
{ … }
static void blkfront_gather_backend_features(struct blkfront_info *info)
{ … }
static void blkfront_connect(struct blkfront_info *info)
{ … }
static void blkback_changed(struct xenbus_device *dev,
enum xenbus_state backend_state)
{ … }
static void blkfront_remove(struct xenbus_device *xbdev)
{ … }
static int blkfront_is_ready(struct xenbus_device *dev)
{ … }
static const struct block_device_operations xlvbd_block_fops = …;
static const struct xenbus_device_id blkfront_ids[] = …;
static struct xenbus_driver blkfront_driver = …;
static void purge_persistent_grants(struct blkfront_info *info)
{ … }
static void blkfront_delay_work(struct work_struct *work)
{ … }
static int __init xlblk_init(void)
{ … }
module_init(…) …;
static void __exit xlblk_exit(void)
{ … }
module_exit(xlblk_exit);
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;
MODULE_ALIAS_BLOCKDEV_MAJOR(…);
MODULE_ALIAS(…) …;
MODULE_ALIAS(…) …;