diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-19 18:02:22 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-19 18:02:22 -0800 |
commit | ed55635e2e4df3169f21ae4047004b7235de956e (patch) | |
tree | 59483776aa04d2b87023059f8a84c5c08d15373f /drivers/target | |
parent | 5be95b7e24bde4d93ff1bff5911b303043753168 (diff) | |
parent | ae450e246e8540300699480a3780a420a028b73f (diff) |
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target fixes from Nicholas Bellinger:
"The highlights this merge window include:
- Allow target fabric drivers to function as built-in. (Roland)
- Fix tcm_loop multi-TPG endpoint nexus bug. (Hannes)
- Move per device config_item_type into se_subsystem_api, allowing
configfs attributes to be defined at module_init time. (Jerome +
nab)
- Convert existing IBLOCK/FILEIO/RAMDISK/PSCSI/TCMU drivers to use
external configfs attributes. (nab)
- A number of iser-target fixes related to active session + network
portal shutdown stability during extended stress testing. (Sagi +
Slava)
- Dynamic allocation of T10-PI contexts for iser-target, fixing a
potentially bogus iscsi_np->tpg_np pointer reference in >= v3.14
code. (Sagi)
- iser-target performance + scalability improvements. (Sagi)
- Fixes for SPC-4 Persistent Reservation AllRegistrants spec
compliance. (Ilias + James + nab)
- Avoid potential short kern_sendmsg() in iscsi-target for now until
Al's conversion to use msghdr iteration is merged post -rc1.
(Viro)
Also, Sagi has requested a number of iser-target patches (9) that
address stability issues he's encountered during extended stress
testing be considered for v3.10.y + v3.14.y code. Given the amount of
LOC involved, it will certainly require extra backporting effort.
Apologies in advance to Greg-KH & Co on this. Sagi and I will be
working post-merge to ensure they each get applied correctly"
* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (53 commits)
target: Allow AllRegistrants to re-RESERVE existing reservation
uapi/linux/target_core_user.h: fix headers_install.sh badness
iscsi-target: Fail connection on short sendmsg writes
iscsi-target: nullify session in failed login sequence
target: Avoid dropping AllRegistrants reservation during unregister
target: Fix R_HOLDER bit usage for AllRegistrants
iscsi-target: Drop left-over bogus iscsi_np->tpg_np
iser-target: Fix wc->wr_id cast warning
iser-target: Remove code duplication
iser-target: Adjust log levels and prettify some prints
iser-target: Use debug_level parameter to control logging level
iser-target: Fix logout sequence
iser-target: Don't wait for session commands from completion context
iser-target: Reduce CQ lock contention by batch polling
iser-target: Introduce isert_poll_budget
iser-target: Remove an atomic operation from the IO path
iser-target: Remove redundant call to isert_conn_terminate
iser-target: Use single CQ for TX and RX
iser-target: Centralize completion elements to a context
iser-target: Cast wr_id with uintptr_t instead of unsinged long
...
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 1 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_core.h | 1 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_login.c | 11 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_tpg.c | 1 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_transport.c | 3 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_util.c | 26 | ||||
-rw-r--r-- | drivers/target/loopback/tcm_loop.c | 66 | ||||
-rw-r--r-- | drivers/target/loopback/tcm_loop.h | 7 | ||||
-rw-r--r-- | drivers/target/target_core_configfs.c | 344 | ||||
-rw-r--r-- | drivers/target/target_core_device.c | 90 | ||||
-rw-r--r-- | drivers/target/target_core_file.c | 42 | ||||
-rw-r--r-- | drivers/target/target_core_hba.c | 7 | ||||
-rw-r--r-- | drivers/target/target_core_iblock.c | 42 | ||||
-rw-r--r-- | drivers/target/target_core_internal.h | 28 | ||||
-rw-r--r-- | drivers/target/target_core_pr.c | 125 | ||||
-rw-r--r-- | drivers/target/target_core_pscsi.c | 26 | ||||
-rw-r--r-- | drivers/target/target_core_rd.c | 41 | ||||
-rw-r--r-- | drivers/target/target_core_user.c | 42 |
18 files changed, 462 insertions, 441 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 73e58d22e325..f8ec32298906 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -609,6 +609,7 @@ static int __init iscsi_target_init_module(void) return ret; r2t_out: + iscsit_unregister_transport(&iscsi_target_transport); kmem_cache_destroy(lio_r2t_cache); ooo_out: kmem_cache_destroy(lio_ooo_cache); diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 302eb3b78715..09a522bae222 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h @@ -790,7 +790,6 @@ struct iscsi_np { void *np_context; struct iscsit_transport *np_transport; struct list_head np_list; - struct iscsi_tpg_np *tpg_np; } ____cacheline_aligned; struct iscsi_tpg_np { diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 480f2e0ecc11..713c0c1877ab 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -281,7 +281,6 @@ static int iscsi_login_zero_tsih_s1( { struct iscsi_session *sess = NULL; struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf; - enum target_prot_op sup_pro_ops; int ret; sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL); @@ -343,9 +342,8 @@ static int iscsi_login_zero_tsih_s1( kfree(sess); return -ENOMEM; } - sup_pro_ops = conn->conn_transport->iscsit_get_sup_prot_ops(conn); - sess->se_sess = transport_init_session(sup_pro_ops); + sess->se_sess = transport_init_session(TARGET_PROT_NORMAL); if (IS_ERR(sess->se_sess)) { iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, ISCSI_LOGIN_STATUS_NO_RESOURCES); @@ -1161,6 +1159,7 @@ void iscsi_target_login_sess_out(struct iscsi_conn *conn, } kfree(conn->sess->sess_ops); kfree(conn->sess); + conn->sess = NULL; old_sess_out: iscsi_stop_login_thread_timer(np); @@ -1204,6 +1203,9 @@ old_sess_out: conn->sock = NULL; } + if (conn->conn_transport->iscsit_wait_conn) + conn->conn_transport->iscsit_wait_conn(conn); + if (conn->conn_transport->iscsit_free_conn) conn->conn_transport->iscsit_free_conn(conn); @@ -1364,6 +1366,9 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) } login->zero_tsih = zero_tsih; + conn->sess->se_sess->sup_prot_ops = + conn->conn_transport->iscsit_get_sup_prot_ops(conn); + tpg = conn->tpg; if (!tpg) { pr_err("Unable to locate struct iscsi_conn->tpg\n"); diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c index c3cb5c15efda..9053a3c0c6e5 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c @@ -501,7 +501,6 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal( init_completion(&tpg_np->tpg_np_comp); kref_init(&tpg_np->tpg_np_kref); tpg_np->tpg_np = np; - np->tpg_np = tpg_np; tpg_np->tpg = tpg; spin_lock(&tpg->tpg_np_lock); diff --git a/drivers/target/iscsi/iscsi_target_transport.c b/drivers/target/iscsi/iscsi_target_transport.c index 882728fac30c..08217d62fb0d 100644 --- a/drivers/target/iscsi/iscsi_target_transport.c +++ b/drivers/target/iscsi/iscsi_target_transport.c @@ -26,8 +26,7 @@ struct iscsit_transport *iscsit_get_transport(int type) void iscsit_put_transport(struct iscsit_transport *t) { - if (t->owner) - module_put(t->owner); + module_put(t->owner); } int iscsit_register_transport(struct iscsit_transport *t) diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 7c6a95bcb35e..bcd88ec99793 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -1356,15 +1356,15 @@ static int iscsit_do_tx_data( struct iscsi_conn *conn, struct iscsi_data_count *count) { - int data = count->data_length, total_tx = 0, tx_loop = 0, iov_len; + int ret, iov_len; struct kvec *iov_p; struct msghdr msg; if (!conn || !conn->sock || !conn->conn_ops) return -1; - if (data <= 0) { - pr_err("Data length is: %d\n", data); + if (count->data_length <= 0) { + pr_err("Data length is: %d\n", count->data_length); return -1; } @@ -1373,20 +1373,16 @@ static int iscsit_do_tx_data( iov_p = count->iov; iov_len = count->iov_count; - while (total_tx < data) { - tx_loop = kernel_sendmsg(conn->sock, &msg, iov_p, iov_len, - (data - total_tx)); - if (tx_loop <= 0) { - pr_debug("tx_loop: %d total_tx %d\n", - tx_loop, total_tx); - return tx_loop; - } - total_tx += tx_loop; - pr_debug("tx_loop: %d, total_tx: %d, data: %d\n", - tx_loop, total_tx, data); + ret = kernel_sendmsg(conn->sock, &msg, iov_p, iov_len, + count->data_length); + if (ret != count->data_length) { + pr_err("Unexpected ret: %d send data %d\n", + ret, count->data_length); + return -EPIPE; } + pr_debug("ret: %d, sent data: %d\n", ret, count->data_length); - return total_tx; + return ret; } int rx_data( diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 4d1b7224a7f2..7172a71f9f0b 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -138,7 +138,7 @@ static void tcm_loop_submission_work(struct work_struct *work) set_host_byte(sc, DID_TRANSPORT_DISRUPTED); goto out_done; } - tl_nexus = tl_hba->tl_nexus; + tl_nexus = tl_tpg->tl_nexus; if (!tl_nexus) { scmd_printk(KERN_ERR, sc, "TCM_Loop I_T Nexus" " does not exist\n"); @@ -218,16 +218,26 @@ static int tcm_loop_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc) * to struct scsi_device */ static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg, - struct tcm_loop_nexus *tl_nexus, int lun, int task, enum tcm_tmreq_table tmr) { struct se_cmd *se_cmd = NULL; struct se_session *se_sess; struct se_portal_group *se_tpg; + struct tcm_loop_nexus *tl_nexus; struct tcm_loop_cmd *tl_cmd = NULL; struct tcm_loop_tmr *tl_tmr = NULL; int ret = TMR_FUNCTION_FAILED, rc; + /* + * Locate the tl_nexus and se_sess pointers + */ + tl_nexus = tl_tpg->tl_nexus; + if (!tl_nexus) { + pr_err("Unable to perform device reset without" + " active I_T Nexus\n"); + return ret; + } + tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_KERNEL); if (!tl_cmd) { pr_err("Unable to allocate memory for tl_cmd\n"); @@ -243,7 +253,7 @@ static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg, se_cmd = &tl_cmd->tl_se_cmd; se_tpg = &tl_tpg->tl_se_tpg; - se_sess = tl_nexus->se_sess; + se_sess = tl_tpg->tl_nexus->se_sess; /* * Initialize struct se_cmd descriptor from target_core_mod infrastructure */ @@ -288,7 +298,6 @@ release: static int tcm_loop_abort_task(struct scsi_cmnd *sc) { struct tcm_loop_hba *tl_hba; - struct tcm_loop_nexus *tl_nexus; struct tcm_loop_tpg *tl_tpg; int ret = FAILED; @@ -296,21 +305,8 @@ static int tcm_loop_abort_task(struct scsi_cmnd *sc) * Locate the tcm_loop_hba_t pointer */ tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host); - /* - * Locate the tl_nexus and se_sess pointers - */ - tl_nexus = tl_hba->tl_nexus; - if (!tl_nexus) { - pr_err("Unable to perform device reset without" - " active I_T Nexus\n"); - return FAILED; - } - - /* - * Locate the tl_tpg pointer from TargetID in sc->device->id - */ tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id]; - ret = tcm_loop_issue_tmr(tl_tpg, tl_nexus, sc->device->lun, + ret = tcm_loop_issue_tmr(tl_tpg, sc->device->lun, sc->request->tag, TMR_ABORT_TASK); return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED; } @@ -322,7 +318,6 @@ static int tcm_loop_abort_task(struct scsi_cmnd *sc) static int tcm_loop_device_reset(struct scsi_cmnd *sc) { struct tcm_loop_hba *tl_hba; - struct tcm_loop_nexus *tl_nexus; struct tcm_loop_tpg *tl_tpg; int ret = FAILED; @@ -330,20 +325,9 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc) * Locate the tcm_loop_hba_t pointer */ tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host); - /* - * Locate the tl_nexus and se_sess pointers - */ - tl_nexus = tl_hba->tl_nexus; - if (!tl_nexus) { - pr_err("Unable to perform device reset without" - " active I_T Nexus\n"); - return FAILED; - } - /* - * Locate the tl_tpg pointer from TargetID in sc->device->id - */ tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id]; - ret = tcm_loop_issue_tmr(tl_tpg, tl_nexus, sc->device->lun, + + ret = tcm_loop_issue_tmr(tl_tpg, sc->device->lun, 0, TMR_LUN_RESET); return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED; } @@ -940,8 +924,8 @@ static int tcm_loop_make_nexus( struct tcm_loop_nexus *tl_nexus; int ret = -ENOMEM; - if (tl_tpg->tl_hba->tl_nexus) { - pr_debug("tl_tpg->tl_hba->tl_nexus already exists\n"); + if (tl_tpg->tl_nexus) { + pr_debug("tl_tpg->tl_nexus already exists\n"); return -EEXIST; } se_tpg = &tl_tpg->tl_se_tpg; @@ -976,7 +960,7 @@ static int tcm_loop_make_nexus( */ __transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl, tl_nexus->se_sess, tl_nexus); - tl_tpg->tl_hba->tl_nexus = tl_nexus; + tl_tpg->tl_nexus = tl_nexus; pr_debug("TCM_Loop_ConfigFS: Established I_T Nexus to emulated" " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba), name); @@ -992,12 +976,8 @@ static int tcm_loop_drop_nexus( { struct se_session *se_sess; struct tcm_loop_nexus *tl_nexus; - struct tcm_loop_hba *tl_hba = tpg->tl_hba; - if (!tl_hba) - return -ENODEV; - - tl_nexus = tl_hba->tl_nexus; + tl_nexus = tpg->tl_nexus; if (!tl_nexus) return -ENODEV; @@ -1013,13 +993,13 @@ static int tcm_loop_drop_nexus( } pr_debug("TCM_Loop_ConfigFS: Removing I_T Nexus to emulated" - " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba), + " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tpg->tl_hba), tl_nexus->se_sess->se_node_acl->initiatorname); /* * Release the SCSI I_T Nexus to the emulated SAS Target Port */ transport_deregister_session(tl_nexus->se_sess); - tpg->tl_hba->tl_nexus = NULL; + tpg->tl_nexus = NULL; kfree(tl_nexus); return 0; } @@ -1035,7 +1015,7 @@ static ssize_t tcm_loop_tpg_show_nexus( struct tcm_loop_nexus *tl_nexus; ssize_t ret; - tl_nexus = tl_tpg->tl_hba->tl_nexus; + tl_nexus = tl_tpg->tl_nexus; if (!tl_nexus) return -ENODEV; diff --git a/drivers/target/loopback/tcm_loop.h b/drivers/target/loopback/tcm_loop.h index 54c59d0b6608..6ae49f272ba6 100644 --- a/drivers/target/loopback/tcm_loop.h +++ b/drivers/target/loopback/tcm_loop.h @@ -27,11 +27,6 @@ struct tcm_loop_tmr { }; struct tcm_loop_nexus { - int it_nexus_active; - /* - * Pointer to Linux/SCSI HBA from linux/include/scsi_host.h - */ - struct scsi_host *sh; /* * Pointer to TCM session for I_T Nexus */ @@ -51,6 +46,7 @@ struct tcm_loop_tpg { atomic_t tl_tpg_port_count; struct se_portal_group tl_se_tpg; struct tcm_loop_hba *tl_hba; + struct tcm_loop_nexus *tl_nexus; }; struct tcm_loop_hba { @@ -59,7 +55,6 @@ struct tcm_loop_hba { struct se_hba_s *se_hba; struct se_lun *tl_hba_lun; struct se_port *tl_hba_lun_sep; - struct tcm_loop_nexus *tl_nexus; struct device dev; struct Scsi_Host *sh; struct tcm_loop_tpg tl_hba_tpgs[TL_TPGS_PER_HBA]; diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 79f9296a08ae..75d89adfccc0 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -50,6 +50,19 @@ #include "target_core_rd.h" #include "target_core_xcopy.h" +#define TB_CIT_SETUP(_name, _item_ops, _group_ops, _attrs) \ +static void target_core_setup_##_name##_cit(struct se_subsystem_api *sa) \ +{ \ + struct target_backend_cits *tbc = &sa->tb_cits; \ + struct config_item_type *cit = &tbc->tb_##_name##_cit; \ + \ + cit->ct_item_ops = _item_ops; \ + cit->ct_group_ops = _group_ops; \ + cit->ct_attrs = _attrs; \ + cit->ct_owner = sa->owner; \ + pr_debug("Setup generic %s\n", __stringify(_name)); \ +} + extern struct t10_alua_lu_gp *default_lu_gp; static LIST_HEAD(g_tf_list); @@ -126,48 +139,57 @@ static struct config_group *target_core_register_fabric( pr_debug("Target_Core_ConfigFS: REGISTER -> group: %p name:" " %s\n", group, name); - /* - * Below are some hardcoded request_module() calls to automatically - * local fabric modules when the following is called: - * - * mkdir -p /sys/kernel/config/target/$MODULE_NAME - * - * Note that this does not limit which TCM fabric module can be - * registered, but simply provids auto loading logic for modules with - * mkdir(2) system calls with known TCM fabric modules. - */ - if (!strncmp(name, "iscsi", 5)) { + + tf = target_core_get_fabric(name); + if (!tf) { + pr_err("target_core_register_fabric() trying autoload for %s\n", + name); + /* - * Automatically load the LIO Target fabric module when the - * following is called: + * Below are some hardcoded request_module() calls to automatically + * local fabric modules when the following is called: * - * mkdir -p $CONFIGFS/target/iscsi - */ - ret = request_module("iscsi_target_mod"); - if (ret < 0) { - pr_err("request_module() failed for" - " iscsi_target_mod.ko: %d\n", ret); - return ERR_PTR(-EINVAL); - } - } else if (!strncmp(name, "loopback", 8)) { - /* - * Automatically load the tcm_loop fabric module when the - * following is called: + * mkdir -p /sys/kernel/config/target/$MODULE_NAME * - * mkdir -p $CONFIGFS/target/loopback + * Note that this does not limit which TCM fabric module can be + * registered, but simply provids auto loading logic for modules with + * mkdir(2) system calls with known TCM fabric modules. */ - ret = request_module("tcm_loop"); - if (ret < 0) { - pr_err("request_module() failed for" - " tcm_loop.ko: %d\n", ret); - return ERR_PTR(-EINVAL); + + if (!strncmp(name, "iscsi", 5)) { + /* + * Automatically load the LIO Target fabric module when the + * following is called: + * + * mkdir -p $CONFIGFS/target/iscsi + */ + ret = request_module("iscsi_target_mod"); + if (ret < 0) { + pr_err("request_module() failed for" + " iscsi_target_mod.ko: %d\n", ret); + return ERR_PTR(-EINVAL); + } + } else if (!strncmp(name, "loopback", 8)) { + /* + * Automatically load the tcm_loop fabric module when the + * following is called: + * + * mkdir -p $CONFIGFS/target/loopback + */ + ret = request_module("tcm_loop"); + if (ret < 0) { + pr_err("request_module() failed for" + " tcm_loop.ko: %d\n", ret); + return ERR_PTR(-EINVAL); + } } + + tf = target_core_get_fabric(name); } - tf = target_core_get_fabric(name); if (!tf) { pr_err("target_core_get_fabric() failed for %s\n", - name); + name); return ERR_PTR(-EINVAL); } pr_debug("Target_Core_ConfigFS: REGISTER -> Located fabric:" @@ -562,198 +584,21 @@ EXPORT_SYMBOL(target_fabric_configfs_deregister); // Stop functions called by external Target Fabrics Modules //############################################################################*/ -/* Start functions for struct config_item_type target_core_dev_attrib_cit */ - -#define DEF_DEV_ATTRIB_SHOW(_name) \ -static ssize_t target_core_dev_show_attr_##_name( \ - struct se_dev_attrib *da, \ - char *page) \ -{ \ - return snprintf(page, PAGE_SIZE, "%u\n", \ - (u32)da->da_dev->dev_attrib._name); \ -} - -#define DEF_DEV_ATTRIB_STORE(_name) \ -static ssize_t target_core_dev_store_attr_##_name( \ - struct se_dev_attrib *da, \ - const char *page, \ - size_t count) \ -{ \ - unsigned long val; \ - int ret; \ - \ - ret = kstrtoul(page, 0, &val); \ - if (ret < 0) { \ - pr_err("kstrtoul() failed with" \ - " ret: %d\n", ret); \ - return -EINVAL; \ - } \ - ret = se_dev_set_##_name(da->da_dev, (u32)val); \ - \ - return (!ret) ? count : -EINVAL; \ -} - -#define DEF_DEV_ATTRIB(_name) \ -DEF_DEV_ATTRIB_SHOW(_name); \ -DEF_DEV_ATTRIB_STORE(_name); - -#define DEF_DEV_ATTRIB_RO(_name) \ -DEF_DEV_ATTRIB_SHOW(_name); +/* Start functions for struct config_item_type tb_dev_attrib_cit */ CONFIGFS_EATTR_STRUCT(target_core_dev_attrib, se_dev_attrib); -#define SE_DEV_ATTR(_name, _mode) \ -static struct target_core_dev_attrib_attribute \ - target_core_dev_attrib_##_name = \ - __CONFIGFS_EATTR(_name, _mode, \ - target_core_dev_show_attr_##_name, \ - target_core_dev_store_attr_##_name); - -#define SE_DEV_ATTR_RO(_name); \ -static struct target_core_dev_attrib_attribute \ - target_core_dev_attrib_##_name = \ - __CONFIGFS_EATTR_RO(_name, \ - target_core_dev_show_attr_##_name); - -DEF_DEV_ATTRIB(emulate_model_alias); -SE_DEV_ATTR(emulate_model_alias, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_dpo); -SE_DEV_ATTR(emulate_dpo, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_fua_write); -SE_DEV_ATTR(emulate_fua_write, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_fua_read); -SE_DEV_ATTR(emulate_fua_read, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_write_cache); -SE_DEV_ATTR(emulate_write_cache, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_ua_intlck_ctrl); -SE_DEV_ATTR(emulate_ua_intlck_ctrl, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_tas); -SE_DEV_ATTR(emulate_tas, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_tpu); -SE_DEV_ATTR(emulate_tpu, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_tpws); -SE_DEV_ATTR(emulate_tpws, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_caw); -SE_DEV_ATTR(emulate_caw, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_3pc); -SE_DEV_ATTR(emulate_3pc, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(pi_prot_type); -SE_DEV_ATTR(pi_prot_type, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB_RO(hw_pi_prot_type); -SE_DEV_ATTR_RO(hw_pi_prot_type); - -DEF_DEV_ATTRIB(pi_prot_format); -SE_DEV_ATTR(pi_prot_format, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(enforce_pr_isids); -SE_DEV_ATTR(enforce_pr_isids, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(is_nonrot); -SE_DEV_ATTR(is_nonrot, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(emulate_rest_reord); -SE_DEV_ATTR(emulate_rest_reord, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(force_pr_aptpl); -SE_DEV_ATTR(force_pr_aptpl, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB_RO(hw_block_size); -SE_DEV_ATTR_RO(hw_block_size); - -DEF_DEV_ATTRIB(block_size); -SE_DEV_ATTR(block_size, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB_RO(hw_max_sectors); -SE_DEV_ATTR_RO(hw_max_sectors); - -DEF_DEV_ATTRIB(fabric_max_sectors); -SE_DEV_ATTR(fabric_max_sectors, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(optimal_sectors); -SE_DEV_ATTR(optimal_sectors, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB_RO(hw_queue_depth); -SE_DEV_ATTR_RO(hw_queue_depth); - -DEF_DEV_ATTRIB(queue_depth); -SE_DEV_ATTR(queue_depth, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(max_unmap_lba_count); -SE_DEV_ATTR(max_unmap_lba_count, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(max_unmap_block_desc_count); -SE_DEV_ATTR(max_unmap_block_desc_count, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(unmap_granularity); -SE_DEV_ATTR(unmap_granularity, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(unmap_granularity_alignment); -SE_DEV_ATTR(unmap_granularity_alignment, S_IRUGO | S_IWUSR); - -DEF_DEV_ATTRIB(max_write_same_len); -SE_DEV_ATTR(max_write_same_len, S_IRUGO | S_IWUSR); - CONFIGFS_EATTR_OPS(target_core_dev_attrib, se_dev_attrib, da_group); -static struct configfs_attribute *target_core_dev_attrib_attrs[] = { - &target_core_dev_attrib_emulate_model_alias.attr, - &target_core_dev_attrib_emulate_dpo.attr, - &target_core_dev_attrib_emulate_fua_write.attr, - &target_core_dev_attrib_emulate_fua_read.attr, - &target_core_dev_attrib_emulate_write_cache.attr, - &target_core_dev_attrib_emulate_ua_intlck_ctrl.attr, - &target_core_dev_attrib_emulate_tas.attr, - &target_core_dev_attrib_emulate_tpu.attr, - &target_core_dev_attrib_emulate_tpws.attr, - &target_core_dev_attrib_emulate_caw.attr, - &target_core_dev_attrib_emulate_3pc.attr, - &target_core_dev_attrib_pi_prot_type.attr, - &target_core_dev_attrib_hw_pi_prot_type.attr, - &target_core_dev_attrib_pi_prot_format.attr, - &target_core_dev_attrib_enforce_pr_isids.attr, - &target_core_dev_attrib_force_pr_aptpl.attr, - &target_core_dev_attrib_is_nonrot.attr, - &target_core_dev_attrib_emulate_rest_reord.attr, - &target_core_dev_attrib_hw_block_size.attr, - &target_core_dev_attrib_block_size.attr, - &target_core_dev_attrib_hw_max_sectors.attr, - &target_core_dev_attrib_fabric_max_sectors.attr, - &target_core_dev_attrib_optimal_sectors.attr, - &target_core_dev_attrib_hw_queue_depth.attr, - &target_core_dev_attrib_queue_depth.attr, - &target_core_dev_attrib_max_unmap_lba_count.attr, - &target_core_dev_attrib_max_unmap_block_desc_count.attr, - &target_core_dev_attrib_unmap_granularity.attr, - &target_core_dev_attrib_unmap_granularity_alignment.attr, - &target_core_dev_attrib_max_write_same_len.attr, - NULL, -}; - static struct configfs_item_operations target_core_dev_attrib_ops = { .show_attribute = target_core_dev_attrib_attr_show, .store_attribute = target_core_dev_attrib_attr_store, }; -static struct config_item_type target_core_dev_attrib_cit = { - .ct_item_ops = &target_core_dev_attrib_ops, - .ct_attrs = target_core_dev_attrib_attrs, - .ct_owner = THIS_MODULE, -}; +TB_CIT_SETUP(dev_attrib, &target_core_dev_attrib_ops, NULL, NULL); -/* End functions for struct config_item_type target_core_dev_attrib_cit */ +/* End functions for struct config_item_type tb_dev_attrib_cit */ -/* Start functions for struct config_item_type target_core_dev_wwn_cit */ +/* Start functions for struct config_item_type tb_dev_wwn_cit */ CONFIGFS_EATTR_STRUCT(target_core_dev_wwn, t10_wwn); #define SE_DEV_WWN_ATTR(_name, _mode) \ @@ -984,15 +829,11 @@ static struct configfs_item_operations target_core_dev_wwn_ops = { .store_attribute = target_core_dev_wwn_attr_store, }; -static struct config_item_type target_core_dev_wwn_cit = { - .ct_item_ops = &target_core_dev_wwn_ops, - .ct_attrs = target_core_dev_wwn_attrs, - .ct_owner = THIS_MODULE, -}; +TB_CIT_SETUP(dev_wwn, &target_core_dev_wwn_ops, NULL, target_core_dev_wwn_attrs); -/* End functions for struct config_item_type target_core_dev_wwn_cit */ +/* End functions for struct config_item_type tb_dev_wwn_cit */ -/* Start functions for struct config_item_type target_core_dev_pr_cit */ +/* Start functions for struct config_item_type tb_dev_pr_cit */ CONFIGFS_EATTR_STRUCT(target_core_dev_pr, se_device); #define SE_DEV_PR_ATTR(_name, _mode) \ @@ -1453,15 +1294,11 @@ static struct configfs_item_operations target_core_dev_pr_ops = { .store_attribute = target_core_dev_pr_attr_store, }; -static struct config_item_type target_core_dev_pr_cit = { - .ct_item_ops = &target_core_dev_pr_ops, - .ct_attrs = target_core_dev_pr_attrs, - .ct_owner = THIS_MODULE, -}; +TB_CIT_SETUP(dev_pr, &target_core_dev_pr_ops, NULL, target_core_dev_pr_attrs); -/* End functions for struct config_item_type target_core_dev_pr_cit */ +/* End functions for struct config_item_type tb_dev_pr_cit */ -/* Start functions for struct config_item_type target_core_dev_cit */ +/* Start functions for struct config_item_type tb_dev_cit */ static ssize_t target_core_show_dev_info(void *p, char *page) { @@ -1925,7 +1762,7 @@ static struct target_core_configfs_attribute target_core_attr_dev_lba_map = { .store = target_core_store_dev_lba_map, }; -static struct configfs_attribute *lio_core_dev_attrs[] = { +static struct configfs_attribute *target_core_dev_attrs[] = { &target_core_attr_dev_info.attr, &target_core_attr_dev_control.attr, &target_core_attr_dev_alias.attr, @@ -1984,13 +1821,9 @@ static struct configfs_item_operations target_core_dev_item_ops = { .store_attribute = target_core_dev_store, }; -static struct config_item_type target_core_dev_cit = { - .ct_item_ops = &target_core_dev_item_ops, - .ct_attrs = lio_core_dev_attrs, - .ct_owner = THIS_MODULE, -}; +TB_CIT_SETUP(dev, &target_core_dev_item_ops, NULL, target_core_dev_attrs); -/* End functions for struct config_item_type target_core_dev_cit */ +/* End functions for struct config_item_type tb_dev_cit */ /* Start functions for struct config_item_type target_core_alua_lu_gp_cit */ @@ -2670,7 +2503,7 @@ static struct config_item_type target_core_alua_tg_pt_gp_cit = { /* End functions for struct config_item_type target_core_alua_tg_pt_gp_cit */ -/* Start functions for struct config_item_type target_core_alua_tg_pt_gps_cit */ +/* Start functions for struct config_item_type tb_alua_tg_pt_gps_cit */ static struct config_group *target_core_alua_create_tg_pt_gp( struct config_group *group, @@ -2721,12 +2554,9 @@ static struct configfs_group_operations target_core_alua_tg_pt_gps_group_ops = { .drop_item = &target_core_alua_drop_tg_pt_gp, }; -static struct config_item_type target_core_alua_tg_pt_gps_cit = { - .ct_group_ops = &target_core_alua_tg_pt_gps_group_ops, - .ct_owner = THIS_MODULE, -}; +TB_CIT_SETUP(dev_alua_tg_pt_gps, NULL, &target_core_alua_tg_pt_gps_group_ops, NULL); -/* End functions for struct config_item_type target_core_alua_tg_pt_gps_cit */ +/* End functions for struct config_item_type tb_alua_tg_pt_gps_cit */ /* Start functions for struct config_item_type target_core_alua_cit */ @@ -2744,7 +2574,7 @@ static struct config_item_type target_core_alua_cit = { /* End functions for struct config_item_type target_core_alua_cit */ -/* Start functions for struct config_item_type target_core_stat_cit */ +/* Start functions for struct config_item_type tb_dev_stat_cit */ static struct config_group *target_core_stat_mkdir( struct config_group *group, @@ -2765,12 +2595,9 @@ static struct configfs_group_operations target_core_stat_group_ops = { .drop_item = &target_core_stat_rmdir, }; -static struct config_item_type target_core_stat_cit = { - .ct_group_ops = &target_core_stat_group_ops, - .ct_owner = THIS_MODULE, -}; +TB_CIT_SETUP(dev_stat, NULL, &target_core_stat_group_ops, NULL); -/* End functions for struct config_item_type target_core_stat_cit */ +/* End functions for struct config_item_type tb_dev_stat_cit */ /* Start functions for struct config_item_type target_core_hba_cit */ @@ -2806,17 +2633,17 @@ static struct config_group *target_core_make_subdev( if (!dev_cg->default_groups) goto out_free_device; - config_group_init_type_name(dev_cg, name, &target_core_dev_cit); + config_group_init_type_name(dev_cg, name, &t->tb_cits.tb_dev_cit); config_group_init_type_name(&dev->dev_attrib.da_group, "attrib", - &target_core_dev_attrib_cit); + &t->tb_cits.tb_dev_attrib_cit); config_group_init_type_name(&dev->dev_pr_group, "pr", - &target_core_dev_pr_cit); + &t->tb_cits.tb_dev_pr_cit); config_group_init_type_name(&dev->t10_wwn.t10_wwn_group, "wwn", - &target_core_dev_wwn_cit); + &t->tb_cits.tb_dev_wwn_cit); config_group_init_type_name(&dev->t10_alua.alua_tg_pt_gps_group, - "alua", &target_core_alua_tg_pt_gps_cit); + "alua", &t->tb_cits.tb_dev_alua_tg_pt_gps_cit); config_group_init_type_name(&dev->dev_stat_grps.stat_group, - "statistics", &target_core_stat_cit); + "statistics", &t->tb_cits.tb_dev_stat_cit); dev_cg->default_groups[0] = &dev->dev_attrib.da_group; dev_cg->default_groups[1] = &dev->dev_pr_group; @@ -3110,6 +2937,17 @@ static struct config_item_type target_core_cit = { /* Stop functions for struct config_item_type target_core_hba_cit */ +void target_core_setup_sub_cits(struct se_subsystem_api *sa) +{ + target_core_setup_dev_cit(sa); + target_core_setup_dev_attrib_cit(sa); + target_core_setup_dev_pr_cit(sa); + target_core_setup_dev_wwn_cit(sa); + target_core_setup_dev_alua_tg_pt_gps_cit(sa); + target_core_setup_dev_stat_cit(sa); +} +EXPORT_SYMBOL(target_core_setup_sub_cits); + static int __init target_core_init_configfs(void) { struct config_group *target_cg, *hba_cg = NULL, *alua_cg = NULL; diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index |