linux/drivers/target/iscsi/iscsi_target_stat.c
<<
>>
Prefs
   1/*******************************************************************************
   2 * Modern ConfigFS group context specific iSCSI statistics based on original
   3 * iscsi_target_mib.c code
   4 *
   5 * Copyright (c) 2011-2013 Datera, Inc.
   6 *
   7 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License as published by
  11 * the Free Software Foundation; either version 2 of the License, or
  12 * (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 ******************************************************************************/
  19
  20#include <linux/configfs.h>
  21#include <linux/export.h>
  22#include <scsi/iscsi_proto.h>
  23#include <target/target_core_base.h>
  24#include <target/configfs_macros.h>
  25
  26#include "iscsi_target_core.h"
  27#include "iscsi_target_parameters.h"
  28#include "iscsi_target_device.h"
  29#include "iscsi_target_tpg.h"
  30#include "iscsi_target_util.h"
  31#include "iscsi_target_stat.h"
  32
  33#ifndef INITIAL_JIFFIES
  34#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
  35#endif
  36
  37/* Instance Attributes Table */
  38#define ISCSI_INST_NUM_NODES            1
  39#define ISCSI_INST_DESCR                "Storage Engine Target"
  40#define ISCSI_INST_LAST_FAILURE_TYPE    0
  41#define ISCSI_DISCONTINUITY_TIME        0
  42
  43#define ISCSI_NODE_INDEX                1
  44
  45#define ISPRINT(a)   ((a >= ' ') && (a <= '~'))
  46
  47/****************************************************************************
  48 * iSCSI MIB Tables
  49 ****************************************************************************/
  50/*
  51 * Instance Attributes Table
  52 */
  53CONFIGFS_EATTR_STRUCT(iscsi_stat_instance, iscsi_wwn_stat_grps);
  54#define ISCSI_STAT_INSTANCE_ATTR(_name, _mode)                  \
  55static struct iscsi_stat_instance_attribute                     \
  56                        iscsi_stat_instance_##_name =           \
  57        __CONFIGFS_EATTR(_name, _mode,                          \
  58        iscsi_stat_instance_show_attr_##_name,                  \
  59        iscsi_stat_instance_store_attr_##_name);
  60
  61#define ISCSI_STAT_INSTANCE_ATTR_RO(_name)                      \
  62static struct iscsi_stat_instance_attribute                     \
  63                        iscsi_stat_instance_##_name =           \
  64        __CONFIGFS_EATTR_RO(_name,                              \
  65        iscsi_stat_instance_show_attr_##_name);
  66
  67static ssize_t iscsi_stat_instance_show_attr_inst(
  68        struct iscsi_wwn_stat_grps *igrps, char *page)
  69{
  70        struct iscsi_tiqn *tiqn = container_of(igrps,
  71                                struct iscsi_tiqn, tiqn_stat_grps);
  72
  73        return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
  74}
  75ISCSI_STAT_INSTANCE_ATTR_RO(inst);
  76
  77static ssize_t iscsi_stat_instance_show_attr_min_ver(
  78        struct iscsi_wwn_stat_grps *igrps, char *page)
  79{
  80        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_DRAFT20_VERSION);
  81}
  82ISCSI_STAT_INSTANCE_ATTR_RO(min_ver);
  83
  84static ssize_t iscsi_stat_instance_show_attr_max_ver(
  85        struct iscsi_wwn_stat_grps *igrps, char *page)
  86{
  87        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_DRAFT20_VERSION);
  88}
  89ISCSI_STAT_INSTANCE_ATTR_RO(max_ver);
  90
  91static ssize_t iscsi_stat_instance_show_attr_portals(
  92        struct iscsi_wwn_stat_grps *igrps, char *page)
  93{
  94        struct iscsi_tiqn *tiqn = container_of(igrps,
  95                                struct iscsi_tiqn, tiqn_stat_grps);
  96
  97        return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_num_tpg_nps);
  98}
  99ISCSI_STAT_INSTANCE_ATTR_RO(portals);
 100
 101static ssize_t iscsi_stat_instance_show_attr_nodes(
 102        struct iscsi_wwn_stat_grps *igrps, char *page)
 103{
 104        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_INST_NUM_NODES);
 105}
 106ISCSI_STAT_INSTANCE_ATTR_RO(nodes);
 107
 108static ssize_t iscsi_stat_instance_show_attr_sessions(
 109        struct iscsi_wwn_stat_grps *igrps, char *page)
 110{
 111        struct iscsi_tiqn *tiqn = container_of(igrps,
 112                                struct iscsi_tiqn, tiqn_stat_grps);
 113
 114        return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_nsessions);
 115}
 116ISCSI_STAT_INSTANCE_ATTR_RO(sessions);
 117
 118static ssize_t iscsi_stat_instance_show_attr_fail_sess(
 119        struct iscsi_wwn_stat_grps *igrps, char *page)
 120{
 121        struct iscsi_tiqn *tiqn = container_of(igrps,
 122                                struct iscsi_tiqn, tiqn_stat_grps);
 123        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 124        u32 sess_err_count;
 125
 126        spin_lock_bh(&sess_err->lock);
 127        sess_err_count = (sess_err->digest_errors +
 128                          sess_err->cxn_timeout_errors +
 129                          sess_err->pdu_format_errors);
 130        spin_unlock_bh(&sess_err->lock);
 131
 132        return snprintf(page, PAGE_SIZE, "%u\n", sess_err_count);
 133}
 134ISCSI_STAT_INSTANCE_ATTR_RO(fail_sess);
 135
 136static ssize_t iscsi_stat_instance_show_attr_fail_type(
 137        struct iscsi_wwn_stat_grps *igrps, char *page)
 138{
 139        struct iscsi_tiqn *tiqn = container_of(igrps,
 140                                struct iscsi_tiqn, tiqn_stat_grps);
 141        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 142
 143        return snprintf(page, PAGE_SIZE, "%u\n",
 144                        sess_err->last_sess_failure_type);
 145}
 146ISCSI_STAT_INSTANCE_ATTR_RO(fail_type);
 147
 148static ssize_t iscsi_stat_instance_show_attr_fail_rem_name(
 149        struct iscsi_wwn_stat_grps *igrps, char *page)
 150{
 151        struct iscsi_tiqn *tiqn = container_of(igrps,
 152                                struct iscsi_tiqn, tiqn_stat_grps);
 153        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 154
 155        return snprintf(page, PAGE_SIZE, "%s\n",
 156                        sess_err->last_sess_fail_rem_name[0] ?
 157                        sess_err->last_sess_fail_rem_name : NONE);
 158}
 159ISCSI_STAT_INSTANCE_ATTR_RO(fail_rem_name);
 160
 161static ssize_t iscsi_stat_instance_show_attr_disc_time(
 162        struct iscsi_wwn_stat_grps *igrps, char *page)
 163{
 164        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_DISCONTINUITY_TIME);
 165}
 166ISCSI_STAT_INSTANCE_ATTR_RO(disc_time);
 167
 168static ssize_t iscsi_stat_instance_show_attr_description(
 169        struct iscsi_wwn_stat_grps *igrps, char *page)
 170{
 171        return snprintf(page, PAGE_SIZE, "%s\n", ISCSI_INST_DESCR);
 172}
 173ISCSI_STAT_INSTANCE_ATTR_RO(description);
 174
 175static ssize_t iscsi_stat_instance_show_attr_vendor(
 176        struct iscsi_wwn_stat_grps *igrps, char *page)
 177{
 178        return snprintf(page, PAGE_SIZE, "Datera, Inc. iSCSI-Target\n");
 179}
 180ISCSI_STAT_INSTANCE_ATTR_RO(vendor);
 181
 182static ssize_t iscsi_stat_instance_show_attr_version(
 183        struct iscsi_wwn_stat_grps *igrps, char *page)
 184{
 185        return snprintf(page, PAGE_SIZE, "%s\n", ISCSIT_VERSION);
 186}
 187ISCSI_STAT_INSTANCE_ATTR_RO(version);
 188
 189CONFIGFS_EATTR_OPS(iscsi_stat_instance, iscsi_wwn_stat_grps,
 190                iscsi_instance_group);
 191
 192static struct configfs_attribute *iscsi_stat_instance_attrs[] = {
 193        &iscsi_stat_instance_inst.attr,
 194        &iscsi_stat_instance_min_ver.attr,
 195        &iscsi_stat_instance_max_ver.attr,
 196        &iscsi_stat_instance_portals.attr,
 197        &iscsi_stat_instance_nodes.attr,
 198        &iscsi_stat_instance_sessions.attr,
 199        &iscsi_stat_instance_fail_sess.attr,
 200        &iscsi_stat_instance_fail_type.attr,
 201        &iscsi_stat_instance_fail_rem_name.attr,
 202        &iscsi_stat_instance_disc_time.attr,
 203        &iscsi_stat_instance_description.attr,
 204        &iscsi_stat_instance_vendor.attr,
 205        &iscsi_stat_instance_version.attr,
 206        NULL,
 207};
 208
 209static struct configfs_item_operations iscsi_stat_instance_item_ops = {
 210        .show_attribute         = iscsi_stat_instance_attr_show,
 211        .store_attribute        = iscsi_stat_instance_attr_store,
 212};
 213
 214struct config_item_type iscsi_stat_instance_cit = {
 215        .ct_item_ops            = &iscsi_stat_instance_item_ops,
 216        .ct_attrs               = iscsi_stat_instance_attrs,
 217        .ct_owner               = THIS_MODULE,
 218};
 219
 220/*
 221 * Instance Session Failure Stats Table
 222 */
 223CONFIGFS_EATTR_STRUCT(iscsi_stat_sess_err, iscsi_wwn_stat_grps);
 224#define ISCSI_STAT_SESS_ERR_ATTR(_name, _mode)                  \
 225static struct iscsi_stat_sess_err_attribute                     \
 226                        iscsi_stat_sess_err_##_name =           \
 227        __CONFIGFS_EATTR(_name, _mode,                          \
 228        iscsi_stat_sess_err_show_attr_##_name,                  \
 229        iscsi_stat_sess_err_store_attr_##_name);
 230
 231#define ISCSI_STAT_SESS_ERR_ATTR_RO(_name)                      \
 232static struct iscsi_stat_sess_err_attribute                     \
 233                        iscsi_stat_sess_err_##_name =           \
 234        __CONFIGFS_EATTR_RO(_name,                              \
 235        iscsi_stat_sess_err_show_attr_##_name);
 236
 237static ssize_t iscsi_stat_sess_err_show_attr_inst(
 238        struct iscsi_wwn_stat_grps *igrps, char *page)
 239{
 240        struct iscsi_tiqn *tiqn = container_of(igrps,
 241                                struct iscsi_tiqn, tiqn_stat_grps);
 242
 243        return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
 244}
 245ISCSI_STAT_SESS_ERR_ATTR_RO(inst);
 246
 247static ssize_t iscsi_stat_sess_err_show_attr_digest_errors(
 248        struct iscsi_wwn_stat_grps *igrps, char *page)
 249{
 250        struct iscsi_tiqn *tiqn = container_of(igrps,
 251                                struct iscsi_tiqn, tiqn_stat_grps);
 252        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 253
 254        return snprintf(page, PAGE_SIZE, "%u\n", sess_err->digest_errors);
 255}
 256ISCSI_STAT_SESS_ERR_ATTR_RO(digest_errors);
 257
 258static ssize_t iscsi_stat_sess_err_show_attr_cxn_errors(
 259        struct iscsi_wwn_stat_grps *igrps, char *page)
 260{
 261        struct iscsi_tiqn *tiqn = container_of(igrps,
 262                                struct iscsi_tiqn, tiqn_stat_grps);
 263        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 264
 265        return snprintf(page, PAGE_SIZE, "%u\n", sess_err->cxn_timeout_errors);
 266}
 267ISCSI_STAT_SESS_ERR_ATTR_RO(cxn_errors);
 268
 269static ssize_t iscsi_stat_sess_err_show_attr_format_errors(
 270        struct iscsi_wwn_stat_grps *igrps, char *page)
 271{
 272        struct iscsi_tiqn *tiqn = container_of(igrps,
 273                                struct iscsi_tiqn, tiqn_stat_grps);
 274        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 275
 276        return snprintf(page, PAGE_SIZE, "%u\n", sess_err->pdu_format_errors);
 277}
 278ISCSI_STAT_SESS_ERR_ATTR_RO(format_errors);
 279
 280CONFIGFS_EATTR_OPS(iscsi_stat_sess_err, iscsi_wwn_stat_grps,
 281                iscsi_sess_err_group);
 282
 283static struct configfs_attribute *iscsi_stat_sess_err_attrs[] = {
 284        &iscsi_stat_sess_err_inst.attr,
 285        &iscsi_stat_sess_err_digest_errors.attr,
 286        &iscsi_stat_sess_err_cxn_errors.attr,
 287        &iscsi_stat_sess_err_format_errors.attr,
 288        NULL,
 289};
 290
 291static struct configfs_item_operations iscsi_stat_sess_err_item_ops = {
 292        .show_attribute         = iscsi_stat_sess_err_attr_show,
 293        .store_attribute        = iscsi_stat_sess_err_attr_store,
 294};
 295
 296struct config_item_type iscsi_stat_sess_err_cit = {
 297        .ct_item_ops            = &iscsi_stat_sess_err_item_ops,
 298        .ct_attrs               = iscsi_stat_sess_err_attrs,
 299        .ct_owner               = THIS_MODULE,
 300};
 301
 302/*
 303 * Target Attributes Table
 304 */
 305CONFIGFS_EATTR_STRUCT(iscsi_stat_tgt_attr, iscsi_wwn_stat_grps);
 306#define ISCSI_STAT_TGT_ATTR(_name, _mode)                       \
 307static struct iscsi_stat_tgt_attr_attribute                     \
 308                        iscsi_stat_tgt_attr_##_name =           \
 309        __CONFIGFS_EATTR(_name, _mode,                          \
 310        iscsi_stat_tgt-attr_show_attr_##_name,                  \
 311        iscsi_stat_tgt_attr_store_attr_##_name);
 312
 313#define ISCSI_STAT_TGT_ATTR_RO(_name)                           \
 314static struct iscsi_stat_tgt_attr_attribute                     \
 315                        iscsi_stat_tgt_attr_##_name =           \
 316        __CONFIGFS_EATTR_RO(_name,                              \
 317        iscsi_stat_tgt_attr_show_attr_##_name);
 318
 319static ssize_t iscsi_stat_tgt_attr_show_attr_inst(
 320        struct iscsi_wwn_stat_grps *igrps, char *page)
 321{
 322        struct iscsi_tiqn *tiqn = container_of(igrps,
 323                                struct iscsi_tiqn, tiqn_stat_grps);
 324
 325        return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
 326}
 327ISCSI_STAT_TGT_ATTR_RO(inst);
 328
 329static ssize_t iscsi_stat_tgt_attr_show_attr_indx(
 330        struct iscsi_wwn_stat_grps *igrps, char *page)
 331{
 332        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_NODE_INDEX);
 333}
 334ISCSI_STAT_TGT_ATTR_RO(indx);
 335
 336static ssize_t iscsi_stat_tgt_attr_show_attr_login_fails(
 337        struct iscsi_wwn_stat_grps *igrps, char *page)
 338{
 339        struct iscsi_tiqn *tiqn = container_of(igrps,
 340                                struct iscsi_tiqn, tiqn_stat_grps);
 341        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 342        u32 fail_count;
 343
 344        spin_lock(&lstat->lock);
 345        fail_count = (lstat->redirects + lstat->authorize_fails +
 346                        lstat->authenticate_fails + lstat->negotiate_fails +
 347                        lstat->other_fails);
 348        spin_unlock(&lstat->lock);
 349
 350        return snprintf(page, PAGE_SIZE, "%u\n", fail_count);
 351}
 352ISCSI_STAT_TGT_ATTR_RO(login_fails);
 353
 354static ssize_t iscsi_stat_tgt_attr_show_attr_last_fail_time(
 355        struct iscsi_wwn_stat_grps *igrps, char *page)
 356{
 357        struct iscsi_tiqn *tiqn = container_of(igrps,
 358                                struct iscsi_tiqn, tiqn_stat_grps);
 359        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 360        u32 last_fail_time;
 361
 362        spin_lock(&lstat->lock);
 363        last_fail_time = lstat->last_fail_time ?
 364                        (u32)(((u32)lstat->last_fail_time -
 365                                INITIAL_JIFFIES) * 100 / HZ) : 0;
 366        spin_unlock(&lstat->lock);
 367
 368        return snprintf(page, PAGE_SIZE, "%u\n", last_fail_time);
 369}
 370ISCSI_STAT_TGT_ATTR_RO(last_fail_time);
 371
 372static ssize_t iscsi_stat_tgt_attr_show_attr_last_fail_type(
 373        struct iscsi_wwn_stat_grps *igrps, char *page)
 374{
 375        struct iscsi_tiqn *tiqn = container_of(igrps,
 376                                struct iscsi_tiqn, tiqn_stat_grps);
 377        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 378        u32 last_fail_type;
 379
 380        spin_lock(&lstat->lock);
 381        last_fail_type = lstat->last_fail_type;
 382        spin_unlock(&lstat->lock);
 383
 384        return snprintf(page, PAGE_SIZE, "%u\n", last_fail_type);
 385}
 386ISCSI_STAT_TGT_ATTR_RO(last_fail_type);
 387
 388static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_name(
 389        struct iscsi_wwn_stat_grps *igrps, char *page)
 390{
 391        struct iscsi_tiqn *tiqn = container_of(igrps,
 392                                struct iscsi_tiqn, tiqn_stat_grps);
 393        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 394        unsigned char buf[224];
 395
 396        spin_lock(&lstat->lock);
 397        snprintf(buf, 224, "%s", lstat->last_intr_fail_name[0] ?
 398                                lstat->last_intr_fail_name : NONE);
 399        spin_unlock(&lstat->lock);
 400
 401        return snprintf(page, PAGE_SIZE, "%s\n", buf);
 402}
 403ISCSI_STAT_TGT_ATTR_RO(fail_intr_name);
 404
 405static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_addr_type(
 406        struct iscsi_wwn_stat_grps *igrps, char *page)
 407{
 408        struct iscsi_tiqn *tiqn = container_of(igrps,
 409                        struct iscsi_tiqn, tiqn_stat_grps);
 410        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 411        int ret;
 412
 413        spin_lock(&lstat->lock);
 414        if (lstat->last_intr_fail_ip_family == AF_INET6)
 415                ret = snprintf(page, PAGE_SIZE, "ipv6\n");
 416        else
 417                ret = snprintf(page, PAGE_SIZE, "ipv4\n");
 418        spin_unlock(&lstat->lock);
 419
 420        return ret;
 421}
 422ISCSI_STAT_TGT_ATTR_RO(fail_intr_addr_type);
 423
 424static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_addr(
 425        struct iscsi_wwn_stat_grps *igrps, char *page)
 426{
 427        struct iscsi_tiqn *tiqn = container_of(igrps,
 428                        struct iscsi_tiqn, tiqn_stat_grps);
 429        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 430        int ret;
 431
 432        spin_lock(&lstat->lock);
 433        ret = snprintf(page, PAGE_SIZE, "%s\n", lstat->last_intr_fail_ip_addr);
 434        spin_unlock(&lstat->lock);
 435
 436        return ret;
 437}
 438ISCSI_STAT_TGT_ATTR_RO(fail_intr_addr);
 439
 440CONFIGFS_EATTR_OPS(iscsi_stat_tgt_attr, iscsi_wwn_stat_grps,
 441                iscsi_tgt_attr_group);
 442
 443static struct configfs_attribute *iscsi_stat_tgt_attr_attrs[] = {
 444        &iscsi_stat_tgt_attr_inst.attr,
 445        &iscsi_stat_tgt_attr_indx.attr,
 446        &iscsi_stat_tgt_attr_login_fails.attr,
 447        &iscsi_stat_tgt_attr_last_fail_time.attr,
 448        &iscsi_stat_tgt_attr_last_fail_type.attr,
 449        &iscsi_stat_tgt_attr_fail_intr_name.attr,
 450        &iscsi_stat_tgt_attr_fail_intr_addr_type.attr,
 451        &iscsi_stat_tgt_attr_fail_intr_addr.attr,
 452        NULL,
 453};
 454
 455static struct configfs_item_operations iscsi_stat_tgt_attr_item_ops = {
 456        .show_attribute         = iscsi_stat_tgt_attr_attr_show,
 457        .store_attribute        = iscsi_stat_tgt_attr_attr_store,
 458};
 459
 460struct config_item_type iscsi_stat_tgt_attr_cit = {
 461        .ct_item_ops            = &iscsi_stat_tgt_attr_item_ops,
 462        .ct_attrs               = iscsi_stat_tgt_attr_attrs,
 463        .ct_owner               = THIS_MODULE,
 464};
 465
 466/*
 467 * Target Login Stats Table
 468 */
 469CONFIGFS_EATTR_STRUCT(iscsi_stat_login, iscsi_wwn_stat_grps);
 470#define ISCSI_STAT_LOGIN(_name, _mode)                          \
 471static struct iscsi_stat_login_attribute                        \
 472                        iscsi_stat_login_##_name =              \
 473        __CONFIGFS_EATTR(_name, _mode,                          \
 474        iscsi_stat_login_show_attr_##_name,                     \
 475        iscsi_stat_login_store_attr_##_name);
 476
 477#define ISCSI_STAT_LOGIN_RO(_name)                              \
 478static struct iscsi_stat_login_attribute                        \
 479                        iscsi_stat_login_##_name =              \
 480        __CONFIGFS_EATTR_RO(_name,                              \
 481        iscsi_stat_login_show_attr_##_name);
 482
 483static ssize_t iscsi_stat_login_show_attr_inst(
 484        struct iscsi_wwn_stat_grps *igrps, char *page)
 485{
 486        struct iscsi_tiqn *tiqn = container_of(igrps,
 487                                struct iscsi_tiqn, tiqn_stat_grps);
 488
 489        return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
 490}
 491ISCSI_STAT_LOGIN_RO(inst);
 492
 493static ssize_t iscsi_stat_login_show_attr_indx(
 494        struct iscsi_wwn_stat_grps *igrps, char *page)
 495{
 496        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_NODE_INDEX);
 497}
 498ISCSI_STAT_LOGIN_RO(indx);
 499
 500static ssize_t iscsi_stat_login_show_attr_accepts(
 501        struct iscsi_wwn_stat_grps *igrps, char *page)
 502{
 503        struct iscsi_tiqn *tiqn = container_of(igrps,
 504                                struct iscsi_tiqn, tiqn_stat_grps);
 505        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 506        ssize_t ret;
 507
 508        spin_lock(&lstat->lock);
 509        ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->accepts);
 510        spin_unlock(&lstat->lock);
 511
 512        return ret;
 513}
 514ISCSI_STAT_LOGIN_RO(accepts);
 515
 516static ssize_t iscsi_stat_login_show_attr_other_fails(
 517        struct iscsi_wwn_stat_grps *igrps, char *page)
 518{
 519        struct iscsi_tiqn *tiqn = container_of(igrps,
 520                                struct iscsi_tiqn, tiqn_stat_grps);
 521        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 522        ssize_t ret;
 523
 524        spin_lock(&lstat->lock);
 525        ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->other_fails);
 526        spin_unlock(&lstat->lock);
 527
 528        return ret;
 529}
 530ISCSI_STAT_LOGIN_RO(other_fails);
 531
 532static ssize_t iscsi_stat_login_show_attr_redirects(
 533        struct iscsi_wwn_stat_grps *igrps, char *page)
 534{
 535        struct iscsi_tiqn *tiqn = container_of(igrps,
 536                                struct iscsi_tiqn, tiqn_stat_grps);
 537        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 538        ssize_t ret;
 539
 540        spin_lock(&lstat->lock);
 541        ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->redirects);
 542        spin_unlock(&lstat->lock);
 543
 544        return ret;
 545}
 546ISCSI_STAT_LOGIN_RO(redirects);
 547
 548static ssize_t iscsi_stat_login_show_attr_authorize_fails(
 549        struct iscsi_wwn_stat_grps *igrps, char *page)
 550{
 551        struct iscsi_tiqn *tiqn = container_of(igrps,
 552                                struct iscsi_tiqn, tiqn_stat_grps);
 553        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 554        ssize_t ret;
 555
 556        spin_lock(&lstat->lock);
 557        ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->authorize_fails);
 558        spin_unlock(&lstat->lock);
 559
 560        return ret;
 561}
 562ISCSI_STAT_LOGIN_RO(authorize_fails);
 563
 564static ssize_t iscsi_stat_login_show_attr_authenticate_fails(
 565        struct iscsi_wwn_stat_grps *igrps, char *page)
 566{
 567        struct iscsi_tiqn *tiqn = container_of(igrps,
 568                                struct iscsi_tiqn, tiqn_stat_grps);
 569        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 570        ssize_t ret;
 571
 572        spin_lock(&lstat->lock);
 573        ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->authenticate_fails);
 574        spin_unlock(&lstat->lock);
 575
 576        return ret;
 577}
 578ISCSI_STAT_LOGIN_RO(authenticate_fails);
 579
 580static ssize_t iscsi_stat_login_show_attr_negotiate_fails(
 581        struct iscsi_wwn_stat_grps *igrps, char *page)
 582{
 583        struct iscsi_tiqn *tiqn = container_of(igrps,
 584                                struct iscsi_tiqn, tiqn_stat_grps);
 585        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 586        ssize_t ret;
 587
 588        spin_lock(&lstat->lock);
 589        ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->negotiate_fails);
 590        spin_unlock(&lstat->lock);
 591
 592        return ret;
 593}
 594ISCSI_STAT_LOGIN_RO(negotiate_fails);
 595
 596CONFIGFS_EATTR_OPS(iscsi_stat_login, iscsi_wwn_stat_grps,
 597                iscsi_login_stats_group);
 598
 599static struct configfs_attribute *iscsi_stat_login_stats_attrs[] = {
 600        &iscsi_stat_login_inst.attr,
 601        &iscsi_stat_login_indx.attr,
 602        &iscsi_stat_login_accepts.attr,
 603        &iscsi_stat_login_other_fails.attr,
 604        &iscsi_stat_login_redirects.attr,
 605        &iscsi_stat_login_authorize_fails.attr,
 606        &iscsi_stat_login_authenticate_fails.attr,
 607        &iscsi_stat_login_negotiate_fails.attr,
 608        NULL,
 609};
 610
 611static struct configfs_item_operations iscsi_stat_login_stats_item_ops = {
 612        .show_attribute         = iscsi_stat_login_attr_show,
 613        .store_attribute        = iscsi_stat_login_attr_store,
 614};
 615
 616struct config_item_type iscsi_stat_login_cit = {
 617        .ct_item_ops            = &iscsi_stat_login_stats_item_ops,
 618        .ct_attrs               = iscsi_stat_login_stats_attrs,
 619        .ct_owner               = THIS_MODULE,
 620};
 621
 622/*
 623 * Target Logout Stats Table
 624 */
 625
 626CONFIGFS_EATTR_STRUCT(iscsi_stat_logout, iscsi_wwn_stat_grps);
 627#define ISCSI_STAT_LOGOUT(_name, _mode)                         \
 628static struct iscsi_stat_logout_attribute                       \
 629                        iscsi_stat_logout_##_name =             \
 630        __CONFIGFS_EATTR(_name, _mode,                          \
 631        iscsi_stat_logout_show_attr_##_name,                    \
 632        iscsi_stat_logout_store_attr_##_name);
 633
 634#define ISCSI_STAT_LOGOUT_RO(_name)                             \
 635static struct iscsi_stat_logout_attribute                       \
 636                        iscsi_stat_logout_##_name =             \
 637        __CONFIGFS_EATTR_RO(_name,                              \
 638        iscsi_stat_logout_show_attr_##_name);
 639
 640static ssize_t iscsi_stat_logout_show_attr_inst(
 641        struct iscsi_wwn_stat_grps *igrps, char *page)
 642{
 643        struct iscsi_tiqn *tiqn = container_of(igrps,
 644                        struct iscsi_tiqn, tiqn_stat_grps);
 645
 646        return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
 647}
 648ISCSI_STAT_LOGOUT_RO(inst);
 649
 650static ssize_t iscsi_stat_logout_show_attr_indx(
 651        struct iscsi_wwn_stat_grps *igrps, char *page)
 652{
 653        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_NODE_INDEX);
 654}
 655ISCSI_STAT_LOGOUT_RO(indx);
 656
 657static ssize_t iscsi_stat_logout_show_attr_normal_logouts(
 658        struct iscsi_wwn_stat_grps *igrps, char *page)
 659{
 660        struct iscsi_tiqn *tiqn = container_of(igrps,
 661                        struct iscsi_tiqn, tiqn_stat_grps);
 662        struct iscsi_logout_stats *lstats = &tiqn->logout_stats;
 663
 664        return snprintf(page, PAGE_SIZE, "%u\n", lstats->normal_logouts);
 665}
 666ISCSI_STAT_LOGOUT_RO(normal_logouts);
 667
 668static ssize_t iscsi_stat_logout_show_attr_abnormal_logouts(
 669        struct iscsi_wwn_stat_grps *igrps, char *page)
 670{
 671        struct iscsi_tiqn *tiqn = container_of(igrps,
 672                        struct iscsi_tiqn, tiqn_stat_grps);
 673        struct iscsi_logout_stats *lstats = &tiqn->logout_stats;
 674
 675        return snprintf(page, PAGE_SIZE, "%u\n", lstats->abnormal_logouts);
 676}
 677ISCSI_STAT_LOGOUT_RO(abnormal_logouts);
 678
 679CONFIGFS_EATTR_OPS(iscsi_stat_logout, iscsi_wwn_stat_grps,
 680                iscsi_logout_stats_group);
 681
 682static struct configfs_attribute *iscsi_stat_logout_stats_attrs[] = {
 683        &iscsi_stat_logout_inst.attr,
 684        &iscsi_stat_logout_indx.attr,
 685        &iscsi_stat_logout_normal_logouts.attr,
 686        &iscsi_stat_logout_abnormal_logouts.attr,
 687        NULL,
 688};
 689
 690static struct configfs_item_operations iscsi_stat_logout_stats_item_ops = {
 691        .show_attribute         = iscsi_stat_logout_attr_show,
 692        .store_attribute        = iscsi_stat_logout_attr_store,
 693};
 694
 695struct config_item_type iscsi_stat_logout_cit = {
 696        .ct_item_ops            = &iscsi_stat_logout_stats_item_ops,
 697        .ct_attrs               = iscsi_stat_logout_stats_attrs,
 698        .ct_owner               = THIS_MODULE,
 699};
 700
 701/*
 702 * Session Stats Table
 703 */
 704
 705CONFIGFS_EATTR_STRUCT(iscsi_stat_sess, iscsi_node_stat_grps);
 706#define ISCSI_STAT_SESS(_name, _mode)                           \
 707static struct iscsi_stat_sess_attribute                         \
 708                        iscsi_stat_sess_##_name =               \
 709        __CONFIGFS_EATTR(_name, _mode,                          \
 710        iscsi_stat_sess_show_attr_##_name,                      \
 711        iscsi_stat_sess_store_attr_##_name);
 712
 713#define ISCSI_STAT_SESS_RO(_name)                               \
 714static struct iscsi_stat_sess_attribute                         \
 715                        iscsi_stat_sess_##_name =               \
 716        __CONFIGFS_EATTR_RO(_name,                              \
 717        iscsi_stat_sess_show_attr_##_name);
 718
 719static ssize_t iscsi_stat_sess_show_attr_inst(
 720        struct iscsi_node_stat_grps *igrps, char *page)
 721{
 722        struct iscsi_node_acl *acl = container_of(igrps,
 723                        struct iscsi_node_acl, node_stat_grps);
 724        struct se_wwn *wwn = acl->se_node_acl.se_tpg->se_tpg_wwn;
 725        struct iscsi_tiqn *tiqn = container_of(wwn,
 726                        struct iscsi_tiqn, tiqn_wwn);
 727
 728        return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
 729}
 730ISCSI_STAT_SESS_RO(inst);
 731
 732static ssize_t iscsi_stat_sess_show_attr_node(
 733        struct iscsi_node_stat_grps *igrps, char *page)
 734{
 735        struct iscsi_node_acl *acl = container_of(igrps,
 736                        struct iscsi_node_acl, node_stat_grps);
 737        struct se_node_acl *se_nacl = &acl->se_node_acl;
 738        struct iscsi_session *sess;
 739        struct se_session *se_sess;
 740        ssize_t ret = 0;
 741
 742        spin_lock_bh(&se_nacl->nacl_sess_lock);
 743        se_sess = se_nacl->nacl_sess;
 744        if (se_sess) {
 745                sess = se_sess->fabric_sess_ptr;
 746                if (sess)
 747                        ret = snprintf(page, PAGE_SIZE, "%u\n",
 748                                sess->sess_ops->SessionType ? 0 : ISCSI_NODE_INDEX);
 749        }
 750        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 751
 752        return ret;
 753}
 754ISCSI_STAT_SESS_RO(node);
 755
 756static ssize_t iscsi_stat_sess_show_attr_indx(
 757        struct iscsi_node_stat_grps *igrps, char *page)
 758{
 759        struct iscsi_node_acl *acl = container_of(igrps,
 760                        struct iscsi_node_acl, node_stat_grps);
 761        struct se_node_acl *se_nacl = &acl->se_node_acl;
 762        struct iscsi_session *sess;
 763        struct se_session *se_sess;
 764        ssize_t ret = 0;
 765
 766        spin_lock_bh(&se_nacl->nacl_sess_lock);
 767        se_sess = se_nacl->nacl_sess;
 768        if (se_sess) {
 769                sess = se_sess->fabric_sess_ptr;
 770                if (sess)
 771                        ret = snprintf(page, PAGE_SIZE, "%u\n",
 772                                        sess->session_index);
 773        }
 774        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 775
 776        return ret;
 777}
 778ISCSI_STAT_SESS_RO(indx);
 779
 780static ssize_t iscsi_stat_sess_show_attr_cmd_pdus(
 781        struct iscsi_node_stat_grps *igrps, char *page)
 782{
 783        struct iscsi_node_acl *acl = container_of(igrps,
 784                        struct iscsi_node_acl, node_stat_grps);
 785        struct se_node_acl *se_nacl = &acl->se_node_acl;
 786        struct iscsi_session *sess;
 787        struct se_session *se_sess;
 788        ssize_t ret = 0;
 789
 790        spin_lock_bh(&se_nacl->nacl_sess_lock);
 791        se_sess = se_nacl->nacl_sess;
 792        if (se_sess) {
 793                sess = se_sess->fabric_sess_ptr;
 794                if (sess)
 795                        ret = snprintf(page, PAGE_SIZE, "%lu\n",
 796                                       atomic_long_read(&sess->cmd_pdus));
 797        }
 798        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 799
 800        return ret;
 801}
 802ISCSI_STAT_SESS_RO(cmd_pdus);
 803
 804static ssize_t iscsi_stat_sess_show_attr_rsp_pdus(
 805        struct iscsi_node_stat_grps *igrps, char *page)
 806{
 807        struct iscsi_node_acl *acl = container_of(igrps,
 808                        struct iscsi_node_acl, node_stat_grps);
 809        struct se_node_acl *se_nacl = &acl->se_node_acl;
 810        struct iscsi_session *sess;
 811        struct se_session *se_sess;
 812        ssize_t ret = 0;
 813
 814        spin_lock_bh(&se_nacl->nacl_sess_lock);
 815        se_sess = se_nacl->nacl_sess;
 816        if (se_sess) {
 817                sess = se_sess->fabric_sess_ptr;
 818                if (sess)
 819                        ret = snprintf(page, PAGE_SIZE, "%lu\n",
 820                                       atomic_long_read(&sess->rsp_pdus));
 821        }
 822        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 823
 824        return ret;
 825}
 826ISCSI_STAT_SESS_RO(rsp_pdus);
 827
 828static ssize_t iscsi_stat_sess_show_attr_txdata_octs(
 829        struct iscsi_node_stat_grps *igrps, char *page)
 830{
 831        struct iscsi_node_acl *acl = container_of(igrps,
 832                        struct iscsi_node_acl, node_stat_grps);
 833        struct se_node_acl *se_nacl = &acl->se_node_acl;
 834        struct iscsi_session *sess;
 835        struct se_session *se_sess;
 836        ssize_t ret = 0;
 837
 838        spin_lock_bh(&se_nacl->nacl_sess_lock);
 839        se_sess = se_nacl->nacl_sess;
 840        if (se_sess) {
 841                sess = se_sess->fabric_sess_ptr;
 842                if (sess)
 843                        ret = snprintf(page, PAGE_SIZE, "%lu\n",
 844                                       atomic_long_read(&sess->tx_data_octets));
 845        }
 846        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 847
 848        return ret;
 849}
 850ISCSI_STAT_SESS_RO(txdata_octs);
 851
 852static ssize_t iscsi_stat_sess_show_attr_rxdata_octs(
 853        struct iscsi_node_stat_grps *igrps, char *page)
 854{
 855        struct iscsi_node_acl *acl = container_of(igrps,
 856                        struct iscsi_node_acl, node_stat_grps);
 857        struct se_node_acl *se_nacl = &acl->se_node_acl;
 858        struct iscsi_session *sess;
 859        struct se_session *se_sess;
 860        ssize_t ret = 0;
 861
 862        spin_lock_bh(&se_nacl->nacl_sess_lock);
 863        se_sess = se_nacl->nacl_sess;
 864        if (se_sess) {
 865                sess = se_sess->fabric_sess_ptr;
 866                if (sess)
 867                        ret = snprintf(page, PAGE_SIZE, "%lu\n",
 868                                       atomic_long_read(&sess->rx_data_octets));
 869        }
 870        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 871
 872        return ret;
 873}
 874ISCSI_STAT_SESS_RO(rxdata_octs);
 875
 876static ssize_t iscsi_stat_sess_show_attr_conn_digest_errors(
 877        struct iscsi_node_stat_grps *igrps, char *page)
 878{
 879        struct iscsi_node_acl *acl = container_of(igrps,
 880                        struct iscsi_node_acl, node_stat_grps);
 881        struct se_node_acl *se_nacl = &acl->se_node_acl;
 882        struct iscsi_session *sess;
 883        struct se_session *se_sess;
 884        ssize_t ret = 0;
 885
 886        spin_lock_bh(&se_nacl->nacl_sess_lock);
 887        se_sess = se_nacl->nacl_sess;
 888        if (se_sess) {
 889                sess = se_sess->fabric_sess_ptr;
 890                if (sess)
 891                        ret = snprintf(page, PAGE_SIZE, "%lu\n",
 892                                       atomic_long_read(&sess->conn_digest_errors));
 893        }
 894        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 895
 896        return ret;
 897}
 898ISCSI_STAT_SESS_RO(conn_digest_errors);
 899
 900static ssize_t iscsi_stat_sess_show_attr_conn_timeout_errors(
 901        struct iscsi_node_stat_grps *igrps, char *page)
 902{
 903        struct iscsi_node_acl *acl = container_of(igrps,
 904                        struct iscsi_node_acl, node_stat_grps);
 905        struct se_node_acl *se_nacl = &acl->se_node_acl;
 906        struct iscsi_session *sess;
 907        struct se_session *se_sess;
 908        ssize_t ret = 0;
 909
 910        spin_lock_bh(&se_nacl->nacl_sess_lock);
 911        se_sess = se_nacl->nacl_sess;
 912        if (se_sess) {
 913                sess = se_sess->fabric_sess_ptr;
 914                if (sess)
 915                        ret = snprintf(page, PAGE_SIZE, "%lu\n",
 916                                       atomic_long_read(&sess->conn_timeout_errors));
 917        }
 918        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 919
 920        return ret;
 921}
 922ISCSI_STAT_SESS_RO(conn_timeout_errors);
 923
 924CONFIGFS_EATTR_OPS(iscsi_stat_sess, iscsi_node_stat_grps,
 925                iscsi_sess_stats_group);
 926
 927static struct configfs_attribute *iscsi_stat_sess_stats_attrs[] = {
 928        &iscsi_stat_sess_inst.attr,
 929        &iscsi_stat_sess_node.attr,
 930        &iscsi_stat_sess_indx.attr,
 931        &iscsi_stat_sess_cmd_pdus.attr,
 932        &iscsi_stat_sess_rsp_pdus.attr,
 933        &iscsi_stat_sess_txdata_octs.attr,
 934        &iscsi_stat_sess_rxdata_octs.attr,
 935        &iscsi_stat_sess_conn_digest_errors.attr,
 936        &iscsi_stat_sess_conn_timeout_errors.attr,
 937        NULL,
 938};
 939
 940static struct configfs_item_operations iscsi_stat_sess_stats_item_ops = {
 941        .show_attribute         = iscsi_stat_sess_attr_show,
 942        .store_attribute        = iscsi_stat_sess_attr_store,
 943};
 944
 945struct config_item_type iscsi_stat_sess_cit = {
 946        .ct_item_ops            = &iscsi_stat_sess_stats_item_ops,
 947        .ct_attrs               = iscsi_stat_sess_stats_attrs,
 948        .ct_owner               = THIS_MODULE,
 949};
 950