mirror of
https://github.com/SCST-project/scst.git
synced 2026-08-18 13:16:34 +00:00
ISCSI target sysfs implementation, except "enabled" attribute.
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1305 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -25,8 +25,6 @@
|
||||
|
||||
#define ISCSI_PROC_LOG_ENTRY_NAME "trace_level"
|
||||
|
||||
#include <linux/proc_fs.h>
|
||||
|
||||
static struct scst_trace_log iscsi_local_trace_tbl[] =
|
||||
{
|
||||
{ TRACE_D_READ, "d_read" },
|
||||
@@ -233,6 +231,43 @@ err:
|
||||
goto out;
|
||||
}
|
||||
|
||||
#else /* CONFIG_SCST_PROC */
|
||||
|
||||
static ssize_t iscsi_version_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
sprintf(buf, "%s\n", ISCSI_VERSION_STRING);
|
||||
|
||||
#ifdef CONFIG_SCST_EXTRACHECKS
|
||||
strcat(buf, "EXTRACHECKS\n");
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCST_TRACING
|
||||
strcat(buf, "TRACING\n");
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCST_DEBUG
|
||||
strcat(buf, "DEBUG\n");
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCST_ISCSI_DEBUG_DIGEST_FAILURES
|
||||
strcat(buf, "DEBUG_DIGEST_FAILURES\n");
|
||||
#endif
|
||||
|
||||
TRACE_EXIT();
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
static struct kobj_attribute iscsi_version_attr =
|
||||
__ATTR(version, S_IRUGO, iscsi_version_show, NULL);
|
||||
|
||||
const struct attribute *iscsi_attrs[] = {
|
||||
&iscsi_version_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
/* target_mutex supposed to be locked */
|
||||
@@ -265,8 +300,11 @@ static int del_conn(struct iscsi_target *target, void __user *ptr)
|
||||
return err;
|
||||
|
||||
session = session_lookup(target, info.sid);
|
||||
if (!session)
|
||||
if (!session) {
|
||||
PRINT_ERROR("Session %llx not found",
|
||||
(long long unsigned int)info.sid);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
return conn_del(session, &info);
|
||||
}
|
||||
|
||||
+191
-7
@@ -21,8 +21,6 @@
|
||||
#include "iscsi.h"
|
||||
#include "digest.h"
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
|
||||
static int print_conn_state(char *p, size_t size, struct iscsi_conn *conn)
|
||||
{
|
||||
int pos = 0;
|
||||
@@ -62,16 +60,22 @@ out:
|
||||
return pos;
|
||||
}
|
||||
|
||||
static void print_digest_state(char *p, size_t size, unsigned long flags)
|
||||
static int print_digest_state(char *p, size_t size, unsigned long flags)
|
||||
{
|
||||
int pos;
|
||||
|
||||
if (DIGEST_NONE & flags)
|
||||
snprintf(p, size, "%s", "none");
|
||||
pos = scnprintf(p, size, "%s", "none");
|
||||
else if (DIGEST_CRC32C & flags)
|
||||
snprintf(p, size, "%s", "crc32c");
|
||||
pos = scnprintf(p, size, "%s", "crc32c");
|
||||
else
|
||||
snprintf(p, size, "%s", "unknown");
|
||||
pos = scnprintf(p, size, "%s", "unknown");
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
|
||||
/* target_mutex supposed to be locked */
|
||||
void conn_info_show(struct seq_file *seq, struct iscsi_session *session)
|
||||
{
|
||||
@@ -109,6 +113,107 @@ void conn_info_show(struct seq_file *seq, struct iscsi_session *session)
|
||||
}
|
||||
}
|
||||
|
||||
#else /* CONFIG_SCST_PROC */
|
||||
|
||||
static int conn_free(struct iscsi_conn *conn);
|
||||
|
||||
static void iscsi_conn_release(struct kobject *kobj)
|
||||
{
|
||||
struct iscsi_conn *conn;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
conn = container_of(kobj, struct iscsi_conn, iscsi_conn_kobj);
|
||||
|
||||
conn_free(conn);
|
||||
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
static struct kobj_type iscsi_conn_ktype = {
|
||||
.sysfs_ops = &scst_sysfs_ops,
|
||||
.release = iscsi_conn_release,
|
||||
};
|
||||
|
||||
static ssize_t iscsi_conn_cid_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
int pos;
|
||||
struct iscsi_conn *conn;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
conn = container_of(kobj, struct iscsi_conn, iscsi_conn_kobj);
|
||||
|
||||
pos = sprintf(buf, "%u", conn->cid);
|
||||
|
||||
TRACE_EXIT_RES(pos);
|
||||
return pos;
|
||||
}
|
||||
|
||||
static struct kobj_attribute iscsi_conn_cid_attr =
|
||||
__ATTR(cid, S_IRUGO, iscsi_conn_cid_show, NULL);
|
||||
|
||||
static ssize_t iscsi_conn_state_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
int pos;
|
||||
struct iscsi_conn *conn;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
conn = container_of(kobj, struct iscsi_conn, iscsi_conn_kobj);
|
||||
|
||||
pos = print_conn_state(buf, SCST_SYSFS_BLOCK_SIZE, conn);
|
||||
|
||||
TRACE_EXIT_RES(pos);
|
||||
return pos;
|
||||
}
|
||||
|
||||
static struct kobj_attribute iscsi_conn_state_attr =
|
||||
__ATTR(state, S_IRUGO, iscsi_conn_state_show, NULL);
|
||||
|
||||
static ssize_t iscsi_conn_hdigest_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
int pos;
|
||||
struct iscsi_conn *conn;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
conn = container_of(kobj, struct iscsi_conn, iscsi_conn_kobj);
|
||||
|
||||
pos = print_digest_state(buf, SCST_SYSFS_BLOCK_SIZE,
|
||||
conn->hdigest_type);
|
||||
|
||||
TRACE_EXIT_RES(pos);
|
||||
return pos;
|
||||
}
|
||||
|
||||
static struct kobj_attribute iscsi_conn_hdigest_attr =
|
||||
__ATTR(hdigest, S_IRUGO, iscsi_conn_hdigest_show, NULL);
|
||||
|
||||
static ssize_t iscsi_conn_ddigest_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
int pos;
|
||||
struct iscsi_conn *conn;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
conn = container_of(kobj, struct iscsi_conn, iscsi_conn_kobj);
|
||||
|
||||
pos = print_digest_state(buf, SCST_SYSFS_BLOCK_SIZE,
|
||||
conn->ddigest_type);
|
||||
|
||||
TRACE_EXIT_RES(pos);
|
||||
return pos;
|
||||
}
|
||||
|
||||
static struct kobj_attribute iscsi_conn_ddigest_attr =
|
||||
__ATTR(ddigest, S_IRUGO, iscsi_conn_ddigest_show, NULL);
|
||||
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
/* target_mutex supposed to be locked */
|
||||
@@ -389,7 +494,11 @@ out:
|
||||
}
|
||||
|
||||
/* target_mutex supposed to be locked */
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
int conn_free(struct iscsi_conn *conn)
|
||||
#else
|
||||
static int conn_free(struct iscsi_conn *conn)
|
||||
#endif
|
||||
{
|
||||
TRACE_MGMT_DBG("Freeing conn %p (sess=%p, %#Lx %u)", conn,
|
||||
conn->session,
|
||||
@@ -437,6 +546,10 @@ static int iscsi_conn_alloc(struct iscsi_session *session,
|
||||
{
|
||||
struct iscsi_conn *conn;
|
||||
int res = 0;
|
||||
#ifndef CONFIG_SCST_PROC
|
||||
struct sock *sk;
|
||||
char addr[64];
|
||||
#endif
|
||||
|
||||
conn = kzalloc(sizeof(*conn), GFP_KERNEL);
|
||||
if (!conn) {
|
||||
@@ -487,6 +600,70 @@ static int iscsi_conn_alloc(struct iscsi_session *session,
|
||||
if (res != 0)
|
||||
goto out_err_free2;
|
||||
|
||||
#ifndef CONFIG_SCST_PROC
|
||||
sk = conn->sock->sk;
|
||||
switch (sk->sk_family) {
|
||||
case AF_INET:
|
||||
snprintf(addr, sizeof(addr),
|
||||
"%u.%u.%u.%u", NIPQUAD(inet_sk(sk)->daddr));
|
||||
break;
|
||||
case AF_INET6:
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
|
||||
snprintf(addr, sizeof(addr),
|
||||
"[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]",
|
||||
NIP6(inet6_sk(sk)->daddr));
|
||||
#else
|
||||
snprintf(addr, sizeof(addr), "[%p6]",
|
||||
&inet6_sk(sk)->daddr);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
res = kobject_init_and_add(&conn->iscsi_conn_kobj, &iscsi_conn_ktype,
|
||||
scst_sysfs_get_sess_kobj(session->scst_sess), addr);
|
||||
if (res != 0) {
|
||||
PRINT_ERROR("Unable create sysfs entries for conn %s",
|
||||
addr);
|
||||
goto out_err_free2;
|
||||
}
|
||||
|
||||
TRACE_DBG("conn %p, iscsi_conn_kobj %p", conn, &conn->iscsi_conn_kobj);
|
||||
|
||||
res = sysfs_create_file(&conn->iscsi_conn_kobj,
|
||||
&iscsi_conn_state_attr.attr);
|
||||
if (res != 0) {
|
||||
PRINT_ERROR("Unable create sysfs attribute %s for conn %s",
|
||||
iscsi_conn_state_attr.attr.name, addr);
|
||||
goto out_err_free3;
|
||||
}
|
||||
|
||||
res = sysfs_create_file(&conn->iscsi_conn_kobj,
|
||||
&iscsi_conn_cid_attr.attr);
|
||||
if (res != 0) {
|
||||
PRINT_ERROR("Unable create sysfs attribute %s for conn %s",
|
||||
iscsi_conn_state_attr.attr.name, addr);
|
||||
goto out_err_free3;
|
||||
}
|
||||
|
||||
res = sysfs_create_file(&conn->iscsi_conn_kobj,
|
||||
&iscsi_conn_hdigest_attr.attr);
|
||||
if (res != 0) {
|
||||
PRINT_ERROR("Unable create sysfs attribute %s for conn %s",
|
||||
iscsi_conn_hdigest_attr.attr.name, addr);
|
||||
goto out_err_free3;
|
||||
}
|
||||
|
||||
res = sysfs_create_file(&conn->iscsi_conn_kobj,
|
||||
&iscsi_conn_ddigest_attr.attr);
|
||||
if (res != 0) {
|
||||
PRINT_ERROR("Unable create sysfs attribute %s for conn %s",
|
||||
iscsi_conn_ddigest_attr.attr.name, addr);
|
||||
goto out_err_free3;
|
||||
}
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
list_add_tail(&conn->conn_list_entry, &session->conn_list);
|
||||
|
||||
*new_conn = conn;
|
||||
@@ -494,6 +671,11 @@ static int iscsi_conn_alloc(struct iscsi_session *session,
|
||||
out:
|
||||
return res;
|
||||
|
||||
#ifndef CONFIG_SCST_PROC
|
||||
out_err_free3:
|
||||
kobject_put(&conn->iscsi_conn_kobj);
|
||||
#endif
|
||||
|
||||
out_err_free2:
|
||||
fput(conn->file);
|
||||
|
||||
@@ -549,8 +731,10 @@ int conn_del(struct iscsi_session *session, struct iscsi_kern_conn_info *info)
|
||||
int err = -EEXIST;
|
||||
|
||||
conn = conn_lookup(session, info->cid);
|
||||
if (!conn)
|
||||
if (!conn) {
|
||||
PRINT_ERROR("Connection %d not found", info->cid);
|
||||
return err;
|
||||
}
|
||||
|
||||
PRINT_INFO("Deleting connection with initiator %s (%p)",
|
||||
conn->session->initiator_name, conn);
|
||||
|
||||
@@ -3143,12 +3143,41 @@ static int iscsi_target_release(struct scst_tgt *scst_tgt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SCST_PROC
|
||||
static struct scst_trace_log iscsi_local_trace_tbl[] =
|
||||
{
|
||||
{ TRACE_D_READ, "d_read" },
|
||||
{ TRACE_D_WRITE, "d_write" },
|
||||
{ TRACE_CONN_OC, "conn" },
|
||||
{ TRACE_CONN_OC_DBG, "conn_dbg" },
|
||||
{ TRACE_D_IOV, "iov" },
|
||||
{ TRACE_D_DUMP_PDU, "pdu" },
|
||||
{ TRACE_NET_PG, "net_page" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
#define ISCSI_TRACE_TLB_HELP ", d_read, d_write, conn, conn_dbg, iov, pdu, net_page"
|
||||
#endif
|
||||
|
||||
struct scst_tgt_template iscsi_template = {
|
||||
.name = "iscsi",
|
||||
.sg_tablesize = 0xFFFF /* no limit */,
|
||||
.threads_num = 0,
|
||||
.no_clustering = 1,
|
||||
.xmit_response_atomic = 0,
|
||||
#ifndef CONFIG_SCST_PROC
|
||||
.tgtt_attrs = iscsi_attrs,
|
||||
.tgt_attrs = iscsi_tgt_attrs,
|
||||
.sess_attrs = iscsi_sess_attrs,
|
||||
#endif
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
.default_trace_flags = ISCSI_DEFAULT_LOG_FLAGS,
|
||||
.trace_flags = &trace_flag,
|
||||
#ifndef CONFIG_SCST_PROC
|
||||
.trace_tbl = iscsi_local_trace_tbl,
|
||||
.trace_tbl_help = ISCSI_TRACE_TLB_HELP,
|
||||
#endif
|
||||
#endif
|
||||
.detect = iscsi_target_detect,
|
||||
.release = iscsi_target_release,
|
||||
.xmit_response = iscsi_xmit_response,
|
||||
|
||||
@@ -238,6 +238,11 @@ struct iscsi_conn {
|
||||
|
||||
/* Doesn't need any protection */
|
||||
u16 cid;
|
||||
|
||||
#ifndef CONFIG_SCST_PROC
|
||||
/* Doesn't need any protection */
|
||||
struct kobject iscsi_conn_kobj;
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
};
|
||||
|
||||
struct iscsi_pdu {
|
||||
@@ -429,7 +434,9 @@ extern struct iscsi_conn *conn_lookup(struct iscsi_session *, u16);
|
||||
extern void conn_reinst_finished(struct iscsi_conn *);
|
||||
extern int conn_add(struct iscsi_session *, struct iscsi_kern_conn_info *);
|
||||
extern int conn_del(struct iscsi_session *, struct iscsi_kern_conn_info *);
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
extern int conn_free(struct iscsi_conn *);
|
||||
#endif
|
||||
extern void iscsi_make_conn_rd_active(struct iscsi_conn *conn);
|
||||
|
||||
#define ISCSI_CONN_ACTIVE_CLOSE 1
|
||||
@@ -454,6 +461,9 @@ extern int istwr(void *arg);
|
||||
extern void iscsi_task_mgmt_affected_cmds_done(struct scst_mgmt_cmd *scst_mcmd);
|
||||
|
||||
/* target.c */
|
||||
#ifndef CONFIG_SCST_PROC
|
||||
extern const struct attribute *iscsi_tgt_attrs[];
|
||||
#endif
|
||||
struct iscsi_target *target_lookup_by_id(u32);
|
||||
extern int target_add(struct iscsi_kern_target_info *);
|
||||
extern int target_del(u32 id);
|
||||
@@ -468,9 +478,14 @@ extern const struct seq_operations iscsi_seq_op;
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
extern int iscsi_procfs_init(void);
|
||||
extern void iscsi_procfs_exit(void);
|
||||
#else
|
||||
extern const struct attribute *iscsi_attrs[];
|
||||
#endif
|
||||
|
||||
/* session.c */
|
||||
#ifndef CONFIG_SCST_PROC
|
||||
extern const struct attribute *iscsi_sess_attrs[];
|
||||
#endif
|
||||
extern const struct file_operations session_seq_fops;
|
||||
extern struct iscsi_session *session_lookup(struct iscsi_target *, u64);
|
||||
extern void sess_reinst_finished(struct iscsi_session *);
|
||||
|
||||
@@ -553,7 +553,11 @@ static void close_conn(struct iscsi_conn *conn)
|
||||
|
||||
mutex_lock(&target->target_mutex);
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
conn_free(conn);
|
||||
#else
|
||||
kobject_put(&conn->iscsi_conn_kobj);
|
||||
#endif
|
||||
|
||||
if (list_empty(&session->conn_list)) {
|
||||
sBUG_ON(session->sess_reinst_successor != NULL);
|
||||
|
||||
@@ -348,4 +348,54 @@ const struct file_operations session_seq_fops = {
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
#else /* CONFIG_SCST_PROC */
|
||||
|
||||
static ssize_t iscsi_sess_sid_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
int pos;
|
||||
struct scst_session *scst_sess;
|
||||
struct iscsi_session *sess;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
scst_sess = container_of(kobj, struct scst_session, sess_kobj);
|
||||
sess = (struct iscsi_session *)scst_sess_get_tgt_priv(scst_sess);
|
||||
|
||||
pos = sprintf(buf, "%llx\n", sess->sid);
|
||||
|
||||
TRACE_EXIT_RES(pos);
|
||||
return pos;
|
||||
}
|
||||
|
||||
static struct kobj_attribute iscsi_sess_sid_attr =
|
||||
__ATTR(sid, S_IRUGO, iscsi_sess_sid_show, NULL);
|
||||
|
||||
static ssize_t iscsi_sess_reinstating_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
int pos;
|
||||
struct scst_session *scst_sess;
|
||||
struct iscsi_session *sess;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
scst_sess = container_of(kobj, struct scst_session, sess_kobj);
|
||||
sess = (struct iscsi_session *)scst_sess_get_tgt_priv(scst_sess);
|
||||
|
||||
pos = sprintf(buf, "%d\n", sess->sess_reinstating ? 1 : 0);
|
||||
|
||||
TRACE_EXIT_RES(pos);
|
||||
return pos;
|
||||
}
|
||||
|
||||
static struct kobj_attribute iscsi_sess_reinstating_attr =
|
||||
__ATTR(reinstating, S_IRUGO, iscsi_sess_reinstating_show, NULL);
|
||||
|
||||
const struct attribute *iscsi_sess_attrs[] = {
|
||||
&iscsi_sess_sid_attr.attr,
|
||||
&iscsi_sess_reinstating_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
@@ -92,6 +92,8 @@ static int iscsi_target_create(struct iscsi_kern_target_info *info, u32 tid)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
scst_tgt_set_tgt_priv(target->scst_tgt, target);
|
||||
|
||||
list_add_tail(&target->target_list_entry, &target_list);
|
||||
|
||||
return 0;
|
||||
@@ -272,6 +274,8 @@ void target_del_all(void)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
|
||||
static struct list_head *seq_list_start(struct list_head *head, loff_t pos)
|
||||
{
|
||||
@@ -337,3 +341,33 @@ const struct seq_operations iscsi_seq_op = {
|
||||
.stop = iscsi_seq_stop,
|
||||
.show = iscsi_seq_show,
|
||||
};
|
||||
|
||||
#else /* CONFIG_SCST_PROC */
|
||||
|
||||
static ssize_t iscsi_tgt_tid_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
int pos;
|
||||
struct scst_tgt *scst_tgt;
|
||||
struct iscsi_target *tgt;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
scst_tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
|
||||
tgt = (struct iscsi_target *)scst_tgt_get_tgt_priv(scst_tgt);
|
||||
|
||||
pos = sprintf(buf, "%u\n", tgt->tid);
|
||||
|
||||
TRACE_EXIT_RES(pos);
|
||||
return pos;
|
||||
}
|
||||
|
||||
static struct kobj_attribute iscsi_tgt_tid_attr =
|
||||
__ATTR(tid, S_IRUGO, iscsi_tgt_tid_show, NULL);
|
||||
|
||||
const struct attribute *iscsi_tgt_attrs[] = {
|
||||
&iscsi_tgt_tid_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
@@ -151,7 +151,8 @@ int kernel_conn_destroy(u32 tid, u64 sid, u32 cid)
|
||||
|
||||
if ((err = ioctl(ctrl_fd, DEL_CONN, &info)) < 0) {
|
||||
err = -errno;
|
||||
log_error("Can't destroy conn %d %u\n", errno, cid);
|
||||
log_error("Can't destroy conn (errno %d, tid %u, sid 0x%"
|
||||
PRIx64 ", cid %u\n", errno, tid, sid, cid);
|
||||
}
|
||||
|
||||
return err;
|
||||
|
||||
@@ -864,6 +864,9 @@ struct scst_tgt_template {
|
||||
|
||||
/* Optional sysfs target attributes */
|
||||
const struct attribute **tgt_attrs;
|
||||
|
||||
/* Optional sysfs session attributes */
|
||||
const struct attribute **sess_attrs;
|
||||
#endif
|
||||
|
||||
/** Private, must be inited to 0 by memset() **/
|
||||
@@ -3239,6 +3242,9 @@ struct proc_dir_entry *scst_create_proc_entry(struct proc_dir_entry *root,
|
||||
|
||||
#else /* CONFIG_SCST_PROC */
|
||||
|
||||
/* Regular SCST sysfs operations */
|
||||
extern struct sysfs_ops scst_sysfs_ops;
|
||||
|
||||
/*
|
||||
* Returns target driver's root sysfs kobject.
|
||||
* The driver can create own files/directories/links here.
|
||||
@@ -3279,6 +3285,16 @@ static inline struct kobject *scst_sysfs_get_dev_kobj(
|
||||
return &dev->dev_kobj;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns session's root sysfs kobject.
|
||||
* The driver can create own files/directories/links here.
|
||||
*/
|
||||
static inline struct kobject *scst_sysfs_get_sess_kobj(
|
||||
struct scst_session *sess)
|
||||
{
|
||||
return &sess->sess_kobj;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
/* Returns target name */
|
||||
|
||||
+18
-2
@@ -37,7 +37,8 @@ static struct kobject *scst_devices_kobj;
|
||||
static struct kobject *scst_sgv_kobj;
|
||||
static struct kobject *scst_handlers_kobj;
|
||||
|
||||
static struct sysfs_ops scst_sysfs_ops;
|
||||
struct sysfs_ops scst_sysfs_ops;
|
||||
EXPORT_SYMBOL(scst_sysfs_ops);
|
||||
|
||||
static const char *scst_dev_handler_types[] =
|
||||
{
|
||||
@@ -670,6 +671,7 @@ static struct kobj_type scst_session_ktype = {
|
||||
int scst_create_sess_sysfs(struct scst_session *sess)
|
||||
{
|
||||
int retval = 0;
|
||||
const struct attribute **pattr;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
@@ -688,6 +690,20 @@ int scst_create_sess_sysfs(struct scst_session *sess)
|
||||
* it will be done by the _put function() called by the caller.
|
||||
*/
|
||||
|
||||
pattr = sess->tgt->tgtt->sess_attrs;
|
||||
if (pattr != NULL) {
|
||||
while (*pattr != NULL) {
|
||||
retval = sysfs_create_file(&sess->sess_kobj, *pattr);
|
||||
if (retval != 0) {
|
||||
PRINT_ERROR("Can't add sess attr %s for sess "
|
||||
"for initiator %s", (*pattr)->name,
|
||||
sess->initiator_name);
|
||||
goto out;
|
||||
}
|
||||
pattr++;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(retval);
|
||||
return retval;
|
||||
@@ -1515,7 +1531,7 @@ static ssize_t scst_store(struct kobject *kobj, struct attribute *attr,
|
||||
return kobj_attr->store(kobj, kobj_attr, buf, count);
|
||||
}
|
||||
|
||||
static struct sysfs_ops scst_sysfs_ops = {
|
||||
struct sysfs_ops scst_sysfs_ops = {
|
||||
.show = scst_show,
|
||||
.store = scst_store,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user