diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-03-07 00:53:26 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-04-25 04:05:26 -0400 |
commit | 3f99306337ba1871afc8568e8b36004ce3cee039 (patch) | |
tree | 897b8e70ebcd2b3973e1657feefd7ba42bab88b3 | |
parent | 20361e69ba0b52880f9a692bb80aceb989bf0e77 (diff) |
iscsi-target: Add iscsit_transport API template
Add basic struct iscsit_transport API template to allow iscsi-target for
running with external transport modules using existing iscsi_target_core.h
code.
For all external modules, this calls try_module_get() and module_put()
to obtain + release an external iscsit_transport module reference count.
Also include the iscsi-target symbols necessary in iscsi_transport.h to
allow external transport modules to function.
v3 changes:
- Add iscsit_build_reject export for ISTATE_SEND_REJECT usage
v2 changes:
- Drop unnecessary export of iscsit_get_transport + iscsit_put_transport (roland)
- Add ->iscsit_queue_data_in() to remove extra context switch on RDMA_WRITE
- Add ->iscsit_queue_status() to remove extra context switch on IB_SEND status
- Add ->iscsit_get_dataout() to remove extra context switch on RDMA_READ
- Drop ->iscsit_free_cmd()
- Drop ->iscsit_unmap_cmd()
- Rename iscsit_create_transport() -> iscsit_register_transport() (andy)
- Rename iscsit_destroy_transport() -> iscsit_unregister_transport() (andy)
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r-- | drivers/target/iscsi/Makefile | 3 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_transport.c | 55 | ||||
-rw-r--r-- | include/target/iscsi/iscsi_transport.h | 83 |
3 files changed, 140 insertions, 1 deletions
diff --git a/drivers/target/iscsi/Makefile b/drivers/target/iscsi/Makefile index 5b9a2cf7f0a9..13a92403fe3e 100644 --- a/drivers/target/iscsi/Makefile +++ b/drivers/target/iscsi/Makefile | |||
@@ -15,6 +15,7 @@ iscsi_target_mod-y += iscsi_target_parameters.o \ | |||
15 | iscsi_target_util.o \ | 15 | iscsi_target_util.o \ |
16 | iscsi_target.o \ | 16 | iscsi_target.o \ |
17 | iscsi_target_configfs.o \ | 17 | iscsi_target_configfs.o \ |
18 | iscsi_target_stat.o | 18 | iscsi_target_stat.o \ |
19 | iscsi_target_transport.o | ||
19 | 20 | ||
20 | obj-$(CONFIG_ISCSI_TARGET) += iscsi_target_mod.o | 21 | obj-$(CONFIG_ISCSI_TARGET) += iscsi_target_mod.o |
diff --git a/drivers/target/iscsi/iscsi_target_transport.c b/drivers/target/iscsi/iscsi_target_transport.c new file mode 100644 index 000000000000..882728fac30c --- /dev/null +++ b/drivers/target/iscsi/iscsi_target_transport.c | |||
@@ -0,0 +1,55 @@ | |||
1 | #include <linux/spinlock.h> | ||
2 | #include <linux/list.h> | ||
3 | #include <target/iscsi/iscsi_transport.h> | ||
4 | |||
5 | static LIST_HEAD(g_transport_list); | ||
6 | static DEFINE_MUTEX(transport_mutex); | ||
7 | |||
8 | struct iscsit_transport *iscsit_get_transport(int type) | ||
9 | { | ||
10 | struct iscsit_transport *t; | ||
11 | |||
12 | mutex_lock(&transport_mutex); | ||
13 | list_for_each_entry(t, &g_transport_list, t_node) { | ||
14 | if (t->transport_type == type) { | ||
15 | if (t->owner && !try_module_get(t->owner)) { | ||
16 | t = NULL; | ||
17 | } | ||
18 | mutex_unlock(&transport_mutex); | ||
19 | return t; | ||
20 | } | ||
21 | } | ||
22 | mutex_unlock(&transport_mutex); | ||
23 | |||
24 | return NULL; | ||
25 | } | ||
26 | |||
27 | void iscsit_put_transport(struct iscsit_transport *t) | ||
28 | { | ||
29 | if (t->owner) | ||
30 | module_put(t->owner); | ||
31 | } | ||
32 | |||
33 | int iscsit_register_transport(struct iscsit_transport *t) | ||
34 | { | ||
35 | INIT_LIST_HEAD(&t->t_node); | ||
36 | |||
37 | mutex_lock(&transport_mutex); | ||
38 | list_add_tail(&t->t_node, &g_transport_list); | ||
39 | mutex_unlock(&transport_mutex); | ||
40 | |||
41 | pr_debug("Registered iSCSI transport: %s\n", t->name); | ||
42 | |||
43 | return 0; | ||
44 | } | ||
45 | EXPORT_SYMBOL(iscsit_register_transport); | ||
46 | |||
47 | void iscsit_unregister_transport(struct iscsit_transport *t) | ||
48 | { | ||
49 | mutex_lock(&transport_mutex); | ||
50 | list_del(&t->t_node); | ||
51 | mutex_unlock(&transport_mutex); | ||
52 | |||
53 | pr_debug("Unregistered iSCSI transport: %s\n", t->name); | ||
54 | } | ||
55 | EXPORT_SYMBOL(iscsit_unregister_transport); | ||
diff --git a/include/target/iscsi/iscsi_transport.h b/include/target/iscsi/iscsi_transport.h new file mode 100644 index 000000000000..23a87d0cd72c --- /dev/null +++ b/include/target/iscsi/iscsi_transport.h | |||
@@ -0,0 +1,83 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/list.h> | ||
3 | #include "../../../drivers/target/iscsi/iscsi_target_core.h" | ||
4 | |||
5 | struct iscsit_transport { | ||
6 | #define ISCSIT_TRANSPORT_NAME 16 | ||
7 | char name[ISCSIT_TRANSPORT_NAME]; | ||
8 | int transport_type; | ||
9 | struct module *owner; | ||
10 | struct list_head t_node; | ||
11 | int (*iscsit_setup_np)(struct iscsi_np *, struct __kernel_sockaddr_storage *); | ||
12 | int (*iscsit_accept_np)(struct iscsi_np *, struct iscsi_conn *); | ||
13 | void (*iscsit_free_np)(struct iscsi_np *); | ||
14 | void (*iscsit_free_conn)(struct iscsi_conn *); | ||
15 | struct iscsi_cmd *(*iscsit_alloc_cmd)(struct iscsi_conn *, gfp_t); | ||
16 | int (*iscsit_get_login_rx)(struct iscsi_conn *, struct iscsi_login *); | ||
17 | int (*iscsit_put_login_tx)(struct iscsi_conn *, struct iscsi_login *, u32); | ||
18 | int (*iscsit_immediate_queue)(struct iscsi_conn *, struct iscsi_cmd *, int); | ||
19 | int (*iscsit_response_queue)(struct iscsi_conn *, struct iscsi_cmd *, int); | ||
20 | int (*iscsit_get_dataout)(struct iscsi_conn *, struct iscsi_cmd *, bool); | ||
21 | int (*iscsit_queue_data_in)(struct iscsi_conn *, struct iscsi_cmd *); | ||
22 | int (*iscsit_queue_status)(struct iscsi_conn *, struct iscsi_cmd *); | ||
23 | }; | ||
24 | |||
25 | /* | ||
26 | * From iscsi_target_transport.c | ||
27 | */ | ||
28 | |||
29 | extern int iscsit_register_transport(struct iscsit_transport *); | ||
30 | extern void iscsit_unregister_transport(struct iscsit_transport *); | ||
31 | extern struct iscsit_transport *iscsit_get_transport(int); | ||
32 | extern void iscsit_put_transport(struct iscsit_transport *); | ||
33 | |||
34 | /* | ||
35 | * From iscsi_target.c | ||
36 | */ | ||
37 | extern int iscsit_add_reject_from_cmd(u8, int, int, unsigned char *, | ||
38 | struct iscsi_cmd *); | ||
39 | extern int iscsit_setup_scsi_cmd(struct iscsi_conn *, struct iscsi_cmd *, | ||
40 | unsigned char *); | ||
41 | extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *); | ||
42 | extern int iscsit_process_scsi_cmd(struct iscsi_conn *, struct iscsi_cmd *, | ||
43 | struct iscsi_scsi_req *); | ||
44 | extern int iscsit_check_dataout_hdr(struct iscsi_conn *, unsigned char *, | ||
45 | struct iscsi_cmd **); | ||
46 | extern int iscsit_check_dataout_payload(struct iscsi_cmd *, struct iscsi_data *, | ||
47 | bool); | ||
48 | extern int iscsit_handle_nop_out(struct iscsi_conn *, struct iscsi_cmd *, | ||
49 | unsigned char *); | ||
50 | extern int iscsit_handle_logout_cmd(struct iscsi_conn *, struct iscsi_cmd *, | ||
51 | unsigned char *); | ||
52 | extern int iscsit_handle_task_mgt_cmd(struct iscsi_conn *, struct iscsi_cmd *, | ||
53 | unsigned char *); | ||
54 | extern void iscsit_build_rsp_pdu(struct iscsi_cmd *, struct iscsi_conn *, | ||
55 | bool, struct iscsi_scsi_rsp *); | ||
56 | extern void iscsit_build_nopin_rsp(struct iscsi_cmd *, struct iscsi_conn *, | ||
57 | struct iscsi_nopin *, bool); | ||
58 | extern void iscsit_build_task_mgt_rsp(struct iscsi_cmd *, struct iscsi_conn *, | ||
59 | struct iscsi_tm_rsp *); | ||
60 | extern void iscsit_build_reject(struct iscsi_cmd *, struct iscsi_conn *, | ||
61 | struct iscsi_reject *); | ||
62 | extern int iscsit_build_logout_rsp(struct iscsi_cmd *, struct iscsi_conn *, | ||
63 | struct iscsi_logout_rsp *); | ||
64 | extern int iscsit_logout_post_handler(struct iscsi_cmd *, struct iscsi_conn *); | ||
65 | /* | ||
66 | * From iscsi_target_device.c | ||
67 | */ | ||
68 | extern void iscsit_increment_maxcmdsn(struct iscsi_cmd *, struct iscsi_session *); | ||
69 | /* | ||
70 | * From iscsi_target_erl1.c | ||
71 | */ | ||
72 | extern void iscsit_stop_dataout_timer(struct iscsi_cmd *); | ||
73 | |||
74 | /* | ||
75 | * From iscsi_target_tmr.c | ||
76 | */ | ||
77 | extern int iscsit_tmr_post_handler(struct iscsi_cmd *, struct iscsi_conn *); | ||
78 | |||
79 | /* | ||
80 | * From iscsi_target_util.c | ||
81 | */ | ||
82 | extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, gfp_t); | ||
83 | extern int iscsit_sequence_cmd(struct iscsi_conn *, struct iscsi_cmd *, __be32); | ||