/* * * Copyright (C) 2011 Citrix Systems Inc. * * This file is part of Blktap2. * * Blktap2 is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation. * * Blktap2 is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License version 2 for more details. * * You should have received a copy of the GNU General Public License * version 2 along with Blktap2. If not, see * . * * */ #ifndef _BLKTAP_H_ #define _BLKTAP_H_ #include #include #include #include #include #include #include "linux-blktap.h" extern int blktap_debug_level; extern int blktap_ring_major; extern int blktap_device_major; #define BTPRINTK(level, tag, force, _f, _a...) \ do { \ if (blktap_debug_level > level && \ (force || printk_ratelimit())) \ printk(tag "%s: " _f, __func__, ##_a); \ } while (0) #define BTDBG(_f, _a...) BTPRINTK(8, KERN_DEBUG, 1, _f, ##_a) #define BTINFO(_f, _a...) BTPRINTK(0, KERN_INFO, 0, _f, ##_a) #define BTWARN(_f, _a...) BTPRINTK(0, KERN_WARNING, 0, _f, ##_a) #define BTERR(_f, _a...) BTPRINTK(0, KERN_ERR, 0, _f, ##_a) #define MAX_BLKTAP_DEVICE 1024 #define BLKTAP_DEVICE 4 #define BLKTAP_DEVICE_CLOSED 5 #define BLKTAP_SHUTDOWN_REQUESTED 8 #define BLKTAP_REQUEST_FREE 0 #define BLKTAP_REQUEST_PENDING 1 struct blktap_device { spinlock_t lock; struct gendisk *gd; }; struct blktap_request; struct blktap_ring { struct task_struct *task; struct vm_area_struct *vma; struct blktap_front_ring ring; unsigned long ring_vstart; unsigned long user_vstart; int n_pending; struct blktap_request *pending[BLKTAP_RING_SIZE]; wait_queue_head_t poll_wait; dev_t devno; struct device *dev; }; struct blktap_statistics { unsigned long st_print; int st_rd_req; int st_wr_req; int st_tr_req; int st_oo_req; int st_fl_req; int st_rd_sect; int st_wr_sect; int st_tr_sect; s64 st_rd_cnt; s64 st_rd_sum_usecs; s64 st_rd_max_usecs; s64 st_wr_cnt; s64 st_wr_sum_usecs; s64 st_wr_max_usecs; }; struct blktap_request { struct blktap *tap; struct request *rq; int usr_idx; int operation; struct scatterlist sg_table[BLKTAP_SEGMENT_MAX]; struct page *pages[BLKTAP_SEGMENT_MAX]; int nr_pages; }; #define blktap_for_each_sg(_sg, _req, _i) \ for (_sg = (_req)->sg_table, _i = 0; \ _i < (_req)->nr_pages; \ (_sg)++, (_i)++) struct blktap { int minor; unsigned long dev_inuse; struct blktap_ring ring; struct blktap_device device; struct blktap_page_pool *pool; wait_queue_head_t remove_wait; struct work_struct remove_work; char name[BLKTAP_NAME_MAX]; struct blktap_statistics stats; }; struct blktap_page_pool { struct mempool_s *bufs; spinlock_t lock; struct kobject kobj; wait_queue_head_t wait; }; extern struct mutex blktap_lock; extern struct blktap **blktaps; extern int blktap_max_minor; int blktap_control_destroy_tap(struct blktap *); size_t blktap_control_debug(struct blktap *, char *, size_t); int blktap_ring_init(void); void blktap_ring_exit(void); size_t blktap_ring_debug(struct blktap *, char *, size_t); int blktap_ring_create(struct blktap *); int blktap_ring_destroy(struct blktap *); struct blktap_request *blktap_ring_make_request(struct blktap *); void blktap_ring_free_request(struct blktap *,struct blktap_request *); void blktap_ring_submit_request(struct blktap *, struct blktap_request *); int blktap_ring_map_request(struct blktap *, struct file *, struct blktap_request *); void blktap_ring_unmap_request(struct blktap *, struct blktap_request *); void blktap_ring_set_message(struct blktap *, int); void blktap_ring_kick_user(struct blktap *); int blktap_sysfs_init(void); void blktap_sysfs_exit(void); int blktap_sysfs_create(struct blktap *); void blktap_sysfs_destroy(struct blktap *); int blktap_device_init(void); void blktap_device_exit(void); size_t blktap_device_debug(struct blktap *, char *, size_t); int blktap_device_create(struct blktap *, struct blktap_device_info *); int blktap_device_destroy(struct blktap *); void blktap_device_destroy_sync(struct blktap *); void blktap_device_run_queue(struct blktap *, struct file *); void blktap_device_end_request(struct blktap *, struct blktap_request *, int); int blktap_page_pool_init(struct kobject *); void blktap_page_pool_exit(void); struct blktap_page_pool *blktap_page_pool_get(const char *); size_t blktap_request_debug(struct blktap *, char *, size_t); struct blktap_request *blktap_request_alloc(struct blktap *); int blktap_request_get_pages(struct blktap *, struct blktap_request *, int); void blktap_request_free(struct blktap *, struct blktap_request *); void blktap_request_bounce(struct blktap *, struct blktap_request *, int); #endif