bsg: bind bsg to request_queue instead of gendisk
This patch binds bsg devices to request_queue instead of gendisk. Any objects (like transport entities) can define own request_handler and create own bsg device. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
Родитель
45e79a3acd
Коммит
d351af01b9
37
block/bsg.c
37
block/bsg.c
|
@ -34,7 +34,6 @@
|
||||||
static char bsg_version[] = "block layer sg (bsg) 0.4";
|
static char bsg_version[] = "block layer sg (bsg) 0.4";
|
||||||
|
|
||||||
struct bsg_device {
|
struct bsg_device {
|
||||||
struct gendisk *disk;
|
|
||||||
request_queue_t *queue;
|
request_queue_t *queue;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
struct list_head busy_list;
|
struct list_head busy_list;
|
||||||
|
@ -46,7 +45,7 @@ struct bsg_device {
|
||||||
int done_cmds;
|
int done_cmds;
|
||||||
wait_queue_head_t wq_done;
|
wait_queue_head_t wq_done;
|
||||||
wait_queue_head_t wq_free;
|
wait_queue_head_t wq_free;
|
||||||
char name[BDEVNAME_SIZE];
|
char name[BUS_ID_SIZE];
|
||||||
int max_queue;
|
int max_queue;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
};
|
};
|
||||||
|
@ -375,7 +374,7 @@ static void bsg_add_command(struct bsg_device *bd, request_queue_t *q,
|
||||||
dprintk("%s: queueing rq %p, bc %p\n", bd->name, rq, bc);
|
dprintk("%s: queueing rq %p, bc %p\n", bd->name, rq, bc);
|
||||||
|
|
||||||
rq->end_io_data = bc;
|
rq->end_io_data = bc;
|
||||||
blk_execute_rq_nowait(q, bd->disk, rq, 1, bsg_rq_end_io);
|
blk_execute_rq_nowait(q, NULL, rq, 1, bsg_rq_end_io);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct bsg_command *bsg_next_done_cmd(struct bsg_device *bd)
|
static inline struct bsg_command *bsg_next_done_cmd(struct bsg_device *bd)
|
||||||
|
@ -741,7 +740,7 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct bsg_device *bsg_add_device(struct inode *inode,
|
static struct bsg_device *bsg_add_device(struct inode *inode,
|
||||||
struct gendisk *disk,
|
struct request_queue *rq,
|
||||||
struct file *file)
|
struct file *file)
|
||||||
{
|
{
|
||||||
struct bsg_device *bd = NULL;
|
struct bsg_device *bd = NULL;
|
||||||
|
@ -753,17 +752,16 @@ static struct bsg_device *bsg_add_device(struct inode *inode,
|
||||||
if (!bd)
|
if (!bd)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
bd->disk = disk;
|
bd->queue = rq;
|
||||||
bd->queue = disk->queue;
|
kobject_get(&rq->kobj);
|
||||||
kobject_get(&disk->queue->kobj);
|
|
||||||
bsg_set_block(bd, file);
|
bsg_set_block(bd, file);
|
||||||
|
|
||||||
atomic_set(&bd->ref_count, 1);
|
atomic_set(&bd->ref_count, 1);
|
||||||
bd->minor = iminor(inode);
|
bd->minor = iminor(inode);
|
||||||
mutex_lock(&bsg_mutex);
|
mutex_lock(&bsg_mutex);
|
||||||
hlist_add_head(&bd->dev_list,&bsg_device_list[bsg_list_idx(bd->minor)]);
|
hlist_add_head(&bd->dev_list, &bsg_device_list[bsg_list_idx(bd->minor)]);
|
||||||
|
|
||||||
strncpy(bd->name, disk->disk_name, sizeof(bd->name) - 1);
|
strncpy(bd->name, rq->bsg_dev.class_dev->class_id, sizeof(bd->name) - 1);
|
||||||
dprintk("bound to <%s>, max queue %d\n",
|
dprintk("bound to <%s>, max queue %d\n",
|
||||||
format_dev_t(buf, inode->i_rdev), bd->max_queue);
|
format_dev_t(buf, inode->i_rdev), bd->max_queue);
|
||||||
|
|
||||||
|
@ -817,7 +815,7 @@ static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file)
|
||||||
if (!bcd)
|
if (!bcd)
|
||||||
return ERR_PTR(-ENODEV);
|
return ERR_PTR(-ENODEV);
|
||||||
|
|
||||||
return bsg_add_device(inode, bcd->disk, file);
|
return bsg_add_device(inode, bcd->queue, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bsg_open(struct inode *inode, struct file *file)
|
static int bsg_open(struct inode *inode, struct file *file)
|
||||||
|
@ -900,7 +898,7 @@ bsg_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
|
||||||
case SG_EMULATED_HOST:
|
case SG_EMULATED_HOST:
|
||||||
case SCSI_IOCTL_SEND_COMMAND: {
|
case SCSI_IOCTL_SEND_COMMAND: {
|
||||||
void __user *uarg = (void __user *) arg;
|
void __user *uarg = (void __user *) arg;
|
||||||
return scsi_cmd_ioctl(file, bd->queue, bd->disk, cmd, uarg);
|
return scsi_cmd_ioctl(file, bd->queue, NULL, cmd, uarg);
|
||||||
}
|
}
|
||||||
case SG_IO: {
|
case SG_IO: {
|
||||||
struct request *rq;
|
struct request *rq;
|
||||||
|
@ -915,7 +913,7 @@ bsg_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
|
||||||
return PTR_ERR(rq);
|
return PTR_ERR(rq);
|
||||||
|
|
||||||
bio = rq->bio;
|
bio = rq->bio;
|
||||||
blk_execute_rq(bd->queue, bd->disk, rq, 0);
|
blk_execute_rq(bd->queue, NULL, rq, 0);
|
||||||
blk_complete_sgv4_hdr_rq(rq, &hdr, bio);
|
blk_complete_sgv4_hdr_rq(rq, &hdr, bio);
|
||||||
|
|
||||||
if (copy_to_user(uarg, &hdr, sizeof(hdr)))
|
if (copy_to_user(uarg, &hdr, sizeof(hdr)))
|
||||||
|
@ -945,24 +943,23 @@ static struct file_operations bsg_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
|
||||||
void bsg_unregister_disk(struct gendisk *disk)
|
void bsg_unregister_queue(struct request_queue *q)
|
||||||
{
|
{
|
||||||
struct bsg_class_device *bcd = &disk->bsg_dev;
|
struct bsg_class_device *bcd = &q->bsg_dev;
|
||||||
|
|
||||||
if (!bcd->class_dev)
|
if (!bcd->class_dev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mutex_lock(&bsg_mutex);
|
mutex_lock(&bsg_mutex);
|
||||||
sysfs_remove_link(&bcd->disk->queue->kobj, "bsg");
|
sysfs_remove_link(&q->kobj, "bsg");
|
||||||
class_device_destroy(bsg_class, MKDEV(BSG_MAJOR, bcd->minor));
|
class_device_destroy(bsg_class, MKDEV(BSG_MAJOR, bcd->minor));
|
||||||
bcd->class_dev = NULL;
|
bcd->class_dev = NULL;
|
||||||
list_del_init(&bcd->list);
|
list_del_init(&bcd->list);
|
||||||
mutex_unlock(&bsg_mutex);
|
mutex_unlock(&bsg_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bsg_register_disk(struct gendisk *disk)
|
int bsg_register_queue(struct request_queue *q, char *name)
|
||||||
{
|
{
|
||||||
request_queue_t *q = disk->queue;
|
|
||||||
struct bsg_class_device *bcd;
|
struct bsg_class_device *bcd;
|
||||||
dev_t dev;
|
dev_t dev;
|
||||||
|
|
||||||
|
@ -972,7 +969,7 @@ int bsg_register_disk(struct gendisk *disk)
|
||||||
if (!q->request_fn)
|
if (!q->request_fn)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
bcd = &disk->bsg_dev;
|
bcd = &q->bsg_dev;
|
||||||
memset(bcd, 0, sizeof(*bcd));
|
memset(bcd, 0, sizeof(*bcd));
|
||||||
INIT_LIST_HEAD(&bcd->list);
|
INIT_LIST_HEAD(&bcd->list);
|
||||||
|
|
||||||
|
@ -980,8 +977,8 @@ int bsg_register_disk(struct gendisk *disk)
|
||||||
dev = MKDEV(BSG_MAJOR, bsg_device_nr);
|
dev = MKDEV(BSG_MAJOR, bsg_device_nr);
|
||||||
bcd->minor = bsg_device_nr;
|
bcd->minor = bsg_device_nr;
|
||||||
bsg_device_nr++;
|
bsg_device_nr++;
|
||||||
bcd->disk = disk;
|
bcd->queue = q;
|
||||||
bcd->class_dev = class_device_create(bsg_class, NULL, dev, bcd->dev, "%s", disk->disk_name);
|
bcd->class_dev = class_device_create(bsg_class, NULL, dev, bcd->dev, "%s", name);
|
||||||
if (!bcd->class_dev)
|
if (!bcd->class_dev)
|
||||||
goto err;
|
goto err;
|
||||||
list_add_tail(&bcd->list, &bsg_class_list);
|
list_add_tail(&bcd->list, &bsg_class_list);
|
||||||
|
|
|
@ -4091,7 +4091,7 @@ int blk_register_queue(struct gendisk *disk)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bsg_register_disk(disk);
|
ret = bsg_register_queue(q, disk->disk_name);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
elv_unregister_queue(q);
|
elv_unregister_queue(q);
|
||||||
kobject_unregister(&q->kobj);
|
kobject_unregister(&q->kobj);
|
||||||
|
@ -4106,7 +4106,7 @@ void blk_unregister_queue(struct gendisk *disk)
|
||||||
request_queue_t *q = disk->queue;
|
request_queue_t *q = disk->queue;
|
||||||
|
|
||||||
if (q && q->request_fn) {
|
if (q && q->request_fn) {
|
||||||
bsg_unregister_disk(disk);
|
bsg_unregister_queue(q);
|
||||||
elv_unregister_queue(q);
|
elv_unregister_queue(q);
|
||||||
|
|
||||||
kobject_uevent(&q->kobj, KOBJ_REMOVE);
|
kobject_uevent(&q->kobj, KOBJ_REMOVE);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <linux/bio.h>
|
#include <linux/bio.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/stringify.h>
|
#include <linux/stringify.h>
|
||||||
|
#include <linux/bsg.h>
|
||||||
|
|
||||||
#include <asm/scatterlist.h>
|
#include <asm/scatterlist.h>
|
||||||
|
|
||||||
|
@ -470,6 +471,10 @@ struct request_queue
|
||||||
unsigned int bi_size;
|
unsigned int bi_size;
|
||||||
|
|
||||||
struct mutex sysfs_lock;
|
struct mutex sysfs_lock;
|
||||||
|
|
||||||
|
#if defined(CONFIG_BLK_DEV_BSG)
|
||||||
|
struct bsg_class_device bsg_dev;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define QUEUE_FLAG_CLUSTER 0 /* cluster several segments into 1 */
|
#define QUEUE_FLAG_CLUSTER 0 /* cluster several segments into 1 */
|
||||||
|
|
|
@ -47,16 +47,16 @@ struct bsg_class_device {
|
||||||
struct class_device *class_dev;
|
struct class_device *class_dev;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
int minor;
|
int minor;
|
||||||
struct gendisk *disk;
|
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
struct request_queue *queue;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int bsg_register_disk(struct gendisk *);
|
extern int bsg_register_queue(struct request_queue *, char *);
|
||||||
extern void bsg_unregister_disk(struct gendisk *);
|
extern void bsg_unregister_queue(struct request_queue *);
|
||||||
#else
|
#else
|
||||||
struct bsg_class_device { };
|
struct bsg_class_device { };
|
||||||
#define bsg_register_disk(disk) (0)
|
#define bsg_register_queue(disk, name) (0)
|
||||||
#define bsg_unregister_disk(disk) do { } while (0)
|
#define bsg_unregister_queue(disk) do { } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
|
|
|
@ -67,7 +67,6 @@ struct partition {
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/bsg.h>
|
|
||||||
|
|
||||||
struct partition {
|
struct partition {
|
||||||
unsigned char boot_ind; /* 0x80 - active */
|
unsigned char boot_ind; /* 0x80 - active */
|
||||||
|
@ -92,7 +91,6 @@ struct hd_struct {
|
||||||
#ifdef CONFIG_FAIL_MAKE_REQUEST
|
#ifdef CONFIG_FAIL_MAKE_REQUEST
|
||||||
int make_it_fail;
|
int make_it_fail;
|
||||||
#endif
|
#endif
|
||||||
struct bsg_class_device bsg_dev;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GENHD_FL_REMOVABLE 1
|
#define GENHD_FL_REMOVABLE 1
|
||||||
|
|
Загрузка…
Ссылка в новой задаче