Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+140 -1
+2 -1
drivers/target/iscsi/Makefile
··· 15 15 iscsi_target_util.o \ 16 16 iscsi_target.o \ 17 17 iscsi_target_configfs.o \ 18 - iscsi_target_stat.o 18 + iscsi_target_stat.o \ 19 + iscsi_target_transport.o 19 20 20 21 obj-$(CONFIG_ISCSI_TARGET) += iscsi_target_mod.o
+55
drivers/target/iscsi/iscsi_target_transport.c
··· 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);
+83
include/target/iscsi/iscsi_transport.h
··· 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);