From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx> This patch adds top level BSG support to QEMU-KVM block and adds the BDS_* prefixed defines for SG_IO and BSG. It adds the BDS_SCSI_GENERIC and BDS_BSG assignments in block/raw-posix.c:hdev_open() using S_ISCHR() and major(st.st_rdev) in order to determine when we are dealing with scsi-generic or scsi-bsg backstores. It also adds a special case BSG check in find_protocol() using the BSG major in order to avoid the strchr() for ':' as we expect filenames to contain /dev/bsg/H:C:T:L. This path also adds a struct BlockDriverState->fd to save a opened file descriptor with format_name = 'raw' for use by scsi-bsg. Signed-off-by: Nicholas A. Bellinger <nab@xxxxxxxxxxxxxxx> --- block.c | 23 ++++++++++++++++++++--- block.h | 1 + block/raw-posix.c | 17 +++++++++++++++-- block_int.h | 5 +++++ 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/block.c b/block.c index 88dbc00..3cd18ec 100644 --- a/block.c +++ b/block.c @@ -285,8 +285,12 @@ static BlockDriver *find_protocol(const char *filename) { BlockDriver *drv1; char protocol[128]; - int len; + int len, bsg = 0; const char *p; +#if defined(__linux__) + struct stat st; +#endif + /* TODO Drivers without bdrv_file_open must be specified explicitly */ @@ -296,7 +300,15 @@ static BlockDriver *find_protocol(const char *filename) return bdrv_find_format("file"); #endif p = strchr(filename, ':'); - if (!p) { +#if defined(__linux__) + if (stat(filename, &st) < 0) + return NULL; + /* This is not yet defined in include/linux/major.h.. */ + if (S_ISCHR(st.st_mode) && major(st.st_rdev) == 254) + bsg = 1; +#endif + + if (!p || bsg) { drv1 = find_hdev_driver(filename); if (!drv1) { drv1 = bdrv_find_format("file"); @@ -1209,7 +1221,12 @@ int bdrv_is_read_only(BlockDriverState *bs) int bdrv_is_sg(BlockDriverState *bs) { - return bs->sg; + return bs->sg == BDS_SCSI_GENERIC; +} + +int bdrv_is_bsg(BlockDriverState *bs) +{ + return bs->sg == BDS_BSG; } int bdrv_enable_write_cache(BlockDriverState *bs) diff --git a/block.h b/block.h index f87d24e..4faeedc 100644 --- a/block.h +++ b/block.h @@ -146,6 +146,7 @@ int bdrv_get_translation_hint(BlockDriverState *bs); int bdrv_is_removable(BlockDriverState *bs); int bdrv_is_read_only(BlockDriverState *bs); int bdrv_is_sg(BlockDriverState *bs); +int bdrv_is_bsg(BlockDriverState *bs); int bdrv_enable_write_cache(BlockDriverState *bs); int bdrv_is_inserted(BlockDriverState *bs); int bdrv_media_changed(BlockDriverState *bs); diff --git a/block/raw-posix.c b/block/raw-posix.c index 1515ca9..d349109 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -52,6 +52,7 @@ #include <sys/ioctl.h> #include <linux/cdrom.h> #include <linux/fd.h> +#include <linux/major.h> #endif #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) #include <signal.h> @@ -843,6 +844,9 @@ static int hdev_probe_device(const char *filename) static int hdev_open(BlockDriverState *bs, const char *filename, int flags) { BDRVRawState *s = bs->opaque; +#if defined(__linux__) + struct stat st; +#endif #ifdef CONFIG_COCOA if (strstart(filename, "/dev/cdrom", NULL)) { @@ -873,8 +877,17 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) s->type = FTYPE_FILE; #if defined(__linux__) - if (strstart(filename, "/dev/sg", NULL)) { - bs->sg = 1; + if (stat(filename, &st) < 0) { + printf("stat() failed errno: %d\n", errno); + return -1; + } + if (S_ISCHR(st.st_mode)) { + if (major(st.st_rdev) == SCSI_GENERIC_MAJOR) { + bs->sg = BDS_SCSI_GENERIC; + } else if (major(st.st_rdev) == 254) { + /* This is not yet defined in include/linux/major.h.. */ + bs->sg = BDS_BSG; + } } #endif diff --git a/block_int.h b/block_int.h index 1a7240c..74bcb1a 100644 --- a/block_int.h +++ b/block_int.h @@ -40,6 +40,10 @@ #define BLOCK_OPT_CLUSTER_SIZE "cluster_size" #define BLOCK_OPT_PREALLOC "preallocation" +#define BDS_NONE 0 +#define BDS_SCSI_GENERIC 1 +#define BDS_BSG 2 + typedef struct AIOPool { void (*cancel)(BlockDriverAIOCB *acb); int aiocb_size; @@ -141,6 +145,7 @@ struct BlockDriverState { int encrypted; /* if true, the media is encrypted */ int valid_key; /* if true, a valid encryption key has been set */ int sg; /* if true, the device is a /dev/sg* */ + int fd; /* Used for BSG file descriptor */ /* event callback when inserting/removing */ void (*change_cb)(void *opaque); void *change_opaque; -- 1.5.6.5 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html