linux/drivers/target/iscsi/iscsi_target_stat.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*******************************************************************************
   3 * Modern ConfigFS group context specific iSCSI statistics based on original
   4 * iscsi_target_mib.c code
   5 *
   6 * Copyright (c) 2011-2013 Datera, Inc.
   7 *
   8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
   9 *
  10 ******************************************************************************/
  11
  12#include <linux/configfs.h>
  13#include <linux/export.h>
  14#include <scsi/iscsi_proto.h>
  15#include <target/target_core_base.h>
  16
  17#include <target/iscsi/iscsi_target_core.h>
  18#include "iscsi_target_parameters.h"
  19#include "iscsi_target_device.h"
  20#include "iscsi_target_tpg.h"
  21#include "iscsi_target_util.h"
  22#include <target/iscsi/iscsi_target_stat.h>
  23
  24#ifndef INITIAL_JIFFIES
  25#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
  26#endif
  27
  28/* Instance Attributes Table */
  29#define ISCSI_INST_NUM_NODES            1
  30#define ISCSI_INST_DESCR                "Storage Engine Target"
  31#define ISCSI_DISCONTINUITY_TIME        0
  32
  33#define ISCSI_NODE_INDEX                1
  34
  35#define ISPRINT(a)   ((a >= ' ') && (a <= '~'))
  36
  37/****************************************************************************
  38 * iSCSI MIB Tables
  39 ****************************************************************************/
  40/*
  41 * Instance Attributes Table
  42 */
  43static struct iscsi_tiqn *iscsi_instance_tiqn(struct config_item *item)
  44{
  45        struct iscsi_wwn_stat_grps *igrps = container_of(to_config_group(item),
  46                        struct iscsi_wwn_stat_grps, iscsi_instance_group);
  47        return container_of(igrps, struct iscsi_tiqn, tiqn_stat_grps);
  48}
  49
  50static ssize_t iscsi_stat_instance_inst_show(struct config_item *item,
  51                char *page)
  52{
  53        return snprintf(page, PAGE_SIZE, "%u\n",
  54                        iscsi_instance_tiqn(item)->tiqn_index);
  55}
  56
  57static ssize_t iscsi_stat_instance_min_ver_show(struct config_item *item,
  58                char *page)
  59{
  60        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_DRAFT20_VERSION);
  61}
  62
  63static ssize_t iscsi_stat_instance_max_ver_show(struct config_item *item,
  64                char *page)
  65{
  66        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_DRAFT20_VERSION);
  67}
  68
  69static ssize_t iscsi_stat_instance_portals_show(struct config_item *item,
  70                char *page)
  71{
  72        return snprintf(page, PAGE_SIZE, "%u\n",
  73                        iscsi_instance_tiqn(item)->tiqn_num_tpg_nps);
  74}
  75
  76static ssize_t iscsi_stat_instance_nodes_show(struct config_item *item,
  77                char *page)
  78{
  79        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_INST_NUM_NODES);
  80}
  81
  82static ssize_t iscsi_stat_instance_sessions_show(struct config_item *item,
  83                char *page)
  84{
  85        return snprintf(page, PAGE_SIZE, "%u\n",
  86                iscsi_instance_tiqn(item)->tiqn_nsessions);
  87}
  88
  89static ssize_t iscsi_stat_instance_fail_sess_show(struct config_item *item,
  90                char *page)
  91{
  92        struct iscsi_tiqn *tiqn = iscsi_instance_tiqn(item);
  93        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
  94        u32 sess_err_count;
  95
  96        spin_lock_bh(&sess_err->lock);
  97        sess_err_count = (sess_err->digest_errors +
  98                          sess_err->cxn_timeout_errors +
  99                          sess_err->pdu_format_errors);
 100        spin_unlock_bh(&sess_err->lock);
 101
 102        return snprintf(page, PAGE_SIZE, "%u\n", sess_err_count);
 103}
 104
 105static ssize_t iscsi_stat_instance_fail_type_show(struct config_item *item,
 106                char *page)
 107{
 108        struct iscsi_tiqn *tiqn = iscsi_instance_tiqn(item);
 109        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 110
 111        return snprintf(page, PAGE_SIZE, "%u\n",
 112                        sess_err->last_sess_failure_type);
 113}
 114
 115static ssize_t iscsi_stat_instance_fail_rem_name_show(struct config_item *item,
 116                char *page)
 117{
 118        struct iscsi_tiqn *tiqn = iscsi_instance_tiqn(item);
 119        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 120
 121        return snprintf(page, PAGE_SIZE, "%s\n",
 122                        sess_err->last_sess_fail_rem_name[0] ?
 123                        sess_err->last_sess_fail_rem_name : NONE);
 124}
 125
 126static ssize_t iscsi_stat_instance_disc_time_show(struct config_item *item,
 127                char *page)
 128{
 129        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_DISCONTINUITY_TIME);
 130}
 131
 132static ssize_t iscsi_stat_instance_description_show(struct config_item *item,
 133                char *page)
 134{
 135        return snprintf(page, PAGE_SIZE, "%s\n", ISCSI_INST_DESCR);
 136}
 137
 138static ssize_t iscsi_stat_instance_vendor_show(struct config_item *item,
 139                char *page)
 140{
 141        return snprintf(page, PAGE_SIZE, "Datera, Inc. iSCSI-Target\n");
 142}
 143
 144static ssize_t iscsi_stat_instance_version_show(struct config_item *item,
 145                char *page)
 146{
 147        return snprintf(page, PAGE_SIZE, "%s\n", ISCSIT_VERSION);
 148}
 149
 150CONFIGFS_ATTR_RO(iscsi_stat_instance_, inst);
 151CONFIGFS_ATTR_RO(iscsi_stat_instance_, min_ver);
 152CONFIGFS_ATTR_RO(iscsi_stat_instance_, max_ver);
 153CONFIGFS_ATTR_RO(iscsi_stat_instance_, portals);
 154CONFIGFS_ATTR_RO(iscsi_stat_instance_, nodes);
 155CONFIGFS_ATTR_RO(iscsi_stat_instance_, sessions);
 156CONFIGFS_ATTR_RO(iscsi_stat_instance_, fail_sess);
 157CONFIGFS_ATTR_RO(iscsi_stat_instance_, fail_type);
 158CONFIGFS_ATTR_RO(iscsi_stat_instance_, fail_rem_name);
 159CONFIGFS_ATTR_RO(iscsi_stat_instance_, disc_time);
 160CONFIGFS_ATTR_RO(iscsi_stat_instance_, description);
 161CONFIGFS_ATTR_RO(iscsi_stat_instance_, vendor);
 162CONFIGFS_ATTR_RO(iscsi_stat_instance_, version);
 163
 164static struct configfs_attribute *iscsi_stat_instance_attrs[] = {
 165        &iscsi_stat_instance_attr_inst,
 166        &iscsi_stat_instance_attr_min_ver,
 167        &iscsi_stat_instance_attr_max_ver,
 168        &iscsi_stat_instance_attr_portals,
 169        &iscsi_stat_instance_attr_nodes,
 170        &iscsi_stat_instance_attr_sessions,
 171        &iscsi_stat_instance_attr_fail_sess,
 172        &iscsi_stat_instance_attr_fail_type,
 173        &iscsi_stat_instance_attr_fail_rem_name,
 174        &iscsi_stat_instance_attr_disc_time,
 175        &iscsi_stat_instance_attr_description,
 176        &iscsi_stat_instance_attr_vendor,
 177        &iscsi_stat_instance_attr_version,
 178        NULL,
 179};
 180
 181const struct config_item_type iscsi_stat_instance_cit = {
 182        .ct_attrs               = iscsi_stat_instance_attrs,
 183        .ct_owner               = THIS_MODULE,
 184};
 185
 186/*
 187 * Instance Session Failure Stats Table
 188 */
 189static struct iscsi_tiqn *iscsi_sess_err_tiqn(struct config_item *item)
 190{
 191        struct iscsi_wwn_stat_grps *igrps = container_of(to_config_group(item),
 192                        struct iscsi_wwn_stat_grps, iscsi_sess_err_group);
 193        return container_of(igrps, struct iscsi_tiqn, tiqn_stat_grps);
 194}
 195
 196static ssize_t iscsi_stat_sess_err_inst_show(struct config_item *item,
 197                char *page)
 198{
 199        return snprintf(page, PAGE_SIZE, "%u\n",
 200                iscsi_sess_err_tiqn(item)->tiqn_index);
 201}
 202
 203static ssize_t iscsi_stat_sess_err_digest_errors_show(struct config_item *item,
 204                char *page)
 205{
 206        struct iscsi_tiqn *tiqn = iscsi_sess_err_tiqn(item);
 207        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 208
 209        return snprintf(page, PAGE_SIZE, "%u\n", sess_err->digest_errors);
 210}
 211
 212static ssize_t iscsi_stat_sess_err_cxn_errors_show(struct config_item *item,
 213                char *page)
 214{
 215        struct iscsi_tiqn *tiqn = iscsi_sess_err_tiqn(item);
 216        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 217
 218        return snprintf(page, PAGE_SIZE, "%u\n", sess_err->cxn_timeout_errors);
 219}
 220
 221static ssize_t iscsi_stat_sess_err_format_errors_show(struct config_item *item,
 222                char *page)
 223{
 224        struct iscsi_tiqn *tiqn = iscsi_sess_err_tiqn(item);
 225        struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
 226
 227        return snprintf(page, PAGE_SIZE, "%u\n", sess_err->pdu_format_errors);
 228}
 229
 230CONFIGFS_ATTR_RO(iscsi_stat_sess_err_, inst);
 231CONFIGFS_ATTR_RO(iscsi_stat_sess_err_, digest_errors);
 232CONFIGFS_ATTR_RO(iscsi_stat_sess_err_, cxn_errors);
 233CONFIGFS_ATTR_RO(iscsi_stat_sess_err_, format_errors);
 234
 235static struct configfs_attribute *iscsi_stat_sess_err_attrs[] = {
 236        &iscsi_stat_sess_err_attr_inst,
 237        &iscsi_stat_sess_err_attr_digest_errors,
 238        &iscsi_stat_sess_err_attr_cxn_errors,
 239        &iscsi_stat_sess_err_attr_format_errors,
 240        NULL,
 241};
 242
 243const struct config_item_type iscsi_stat_sess_err_cit = {
 244        .ct_attrs               = iscsi_stat_sess_err_attrs,
 245        .ct_owner               = THIS_MODULE,
 246};
 247
 248/*
 249 * Target Attributes Table
 250 */
 251static struct iscsi_tiqn *iscsi_tgt_attr_tiqn(struct config_item *item)
 252{
 253        struct iscsi_wwn_stat_grps *igrps = container_of(to_config_group(item),
 254                        struct iscsi_wwn_stat_grps, iscsi_tgt_attr_group);
 255        return container_of(igrps, struct iscsi_tiqn, tiqn_stat_grps);
 256}
 257
 258static ssize_t iscsi_stat_tgt_attr_inst_show(struct config_item *item,
 259                char *page)
 260{
 261        return snprintf(page, PAGE_SIZE, "%u\n",
 262                        iscsi_tgt_attr_tiqn(item)->tiqn_index);
 263}
 264
 265static ssize_t iscsi_stat_tgt_attr_indx_show(struct config_item *item,
 266                char *page)
 267{
 268        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_NODE_INDEX);
 269}
 270
 271static ssize_t iscsi_stat_tgt_attr_login_fails_show(struct config_item *item,
 272                char *page)
 273{
 274        struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item);
 275        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 276        u32 fail_count;
 277
 278        spin_lock(&lstat->lock);
 279        fail_count = (lstat->redirects + lstat->authorize_fails +
 280                        lstat->authenticate_fails + lstat->negotiate_fails +
 281                        lstat->other_fails);
 282        spin_unlock(&lstat->lock);
 283
 284        return snprintf(page, PAGE_SIZE, "%u\n", fail_count);
 285}
 286
 287static ssize_t iscsi_stat_tgt_attr_last_fail_time_show(struct config_item *item,
 288                char *page)
 289{
 290        struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item);
 291        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 292        u32 last_fail_time;
 293
 294        spin_lock(&lstat->lock);
 295        last_fail_time = lstat->last_fail_time ?
 296                        (u32)(((u32)lstat->last_fail_time -
 297                                INITIAL_JIFFIES) * 100 / HZ) : 0;
 298        spin_unlock(&lstat->lock);
 299
 300        return snprintf(page, PAGE_SIZE, "%u\n", last_fail_time);
 301}
 302
 303static ssize_t iscsi_stat_tgt_attr_last_fail_type_show(struct config_item *item,
 304                char *page)
 305{
 306        struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item);
 307        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 308        u32 last_fail_type;
 309
 310        spin_lock(&lstat->lock);
 311        last_fail_type = lstat->last_fail_type;
 312        spin_unlock(&lstat->lock);
 313
 314        return snprintf(page, PAGE_SIZE, "%u\n", last_fail_type);
 315}
 316
 317static ssize_t iscsi_stat_tgt_attr_fail_intr_name_show(struct config_item *item,
 318                char *page)
 319{
 320        struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item);
 321        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 322        unsigned char buf[ISCSI_IQN_LEN];
 323
 324        spin_lock(&lstat->lock);
 325        snprintf(buf, ISCSI_IQN_LEN, "%s", lstat->last_intr_fail_name[0] ?
 326                                lstat->last_intr_fail_name : NONE);
 327        spin_unlock(&lstat->lock);
 328
 329        return snprintf(page, PAGE_SIZE, "%s\n", buf);
 330}
 331
 332static ssize_t iscsi_stat_tgt_attr_fail_intr_addr_type_show(struct config_item *item,
 333                char *page)
 334{
 335        struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item);
 336        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 337        int ret;
 338
 339        spin_lock(&lstat->lock);
 340        if (lstat->last_intr_fail_ip_family == AF_INET6)
 341                ret = snprintf(page, PAGE_SIZE, "ipv6\n");
 342        else
 343                ret = snprintf(page, PAGE_SIZE, "ipv4\n");
 344        spin_unlock(&lstat->lock);
 345
 346        return ret;
 347}
 348
 349static ssize_t iscsi_stat_tgt_attr_fail_intr_addr_show(struct config_item *item,
 350                char *page)
 351{
 352        struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item);
 353        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 354        int ret;
 355
 356        spin_lock(&lstat->lock);
 357        ret = snprintf(page, PAGE_SIZE, "%pISc\n", &lstat->last_intr_fail_sockaddr);
 358        spin_unlock(&lstat->lock);
 359
 360        return ret;
 361}
 362
 363CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, inst);
 364CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, indx);
 365CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, login_fails);
 366CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, last_fail_time);
 367CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, last_fail_type);
 368CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, fail_intr_name);
 369CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, fail_intr_addr_type);
 370CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, fail_intr_addr);
 371
 372static struct configfs_attribute *iscsi_stat_tgt_attr_attrs[] = {
 373        &iscsi_stat_tgt_attr_attr_inst,
 374        &iscsi_stat_tgt_attr_attr_indx,
 375        &iscsi_stat_tgt_attr_attr_login_fails,
 376        &iscsi_stat_tgt_attr_attr_last_fail_time,
 377        &iscsi_stat_tgt_attr_attr_last_fail_type,
 378        &iscsi_stat_tgt_attr_attr_fail_intr_name,
 379        &iscsi_stat_tgt_attr_attr_fail_intr_addr_type,
 380        &iscsi_stat_tgt_attr_attr_fail_intr_addr,
 381        NULL,
 382};
 383
 384const struct config_item_type iscsi_stat_tgt_attr_cit = {
 385        .ct_attrs               = iscsi_stat_tgt_attr_attrs,
 386        .ct_owner               = THIS_MODULE,
 387};
 388
 389/*
 390 * Target Login Stats Table
 391 */
 392static struct iscsi_tiqn *iscsi_login_stat_tiqn(struct config_item *item)
 393{
 394        struct iscsi_wwn_stat_grps *igrps = container_of(to_config_group(item),
 395                        struct iscsi_wwn_stat_grps, iscsi_login_stats_group);
 396        return container_of(igrps, struct iscsi_tiqn, tiqn_stat_grps);
 397}
 398
 399static ssize_t iscsi_stat_login_inst_show(struct config_item *item, char *page)
 400{
 401        return snprintf(page, PAGE_SIZE, "%u\n",
 402                iscsi_login_stat_tiqn(item)->tiqn_index);
 403}
 404
 405static ssize_t iscsi_stat_login_indx_show(struct config_item *item,
 406                char *page)
 407{
 408        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_NODE_INDEX);
 409}
 410
 411static ssize_t iscsi_stat_login_accepts_show(struct config_item *item,
 412                char *page)
 413{
 414        struct iscsi_tiqn *tiqn = iscsi_login_stat_tiqn(item);
 415        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 416        ssize_t ret;
 417
 418        spin_lock(&lstat->lock);
 419        ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->accepts);
 420        spin_unlock(&lstat->lock);
 421
 422        return ret;
 423}
 424
 425static ssize_t iscsi_stat_login_other_fails_show(struct config_item *item,
 426                char *page)
 427{
 428        struct iscsi_tiqn *tiqn = iscsi_login_stat_tiqn(item);
 429        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 430        ssize_t ret;
 431
 432        spin_lock(&lstat->lock);
 433        ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->other_fails);
 434        spin_unlock(&lstat->lock);
 435
 436        return ret;
 437}
 438
 439static ssize_t iscsi_stat_login_redirects_show(struct config_item *item,
 440                char *page)
 441{
 442        struct iscsi_tiqn *tiqn = iscsi_login_stat_tiqn(item);
 443        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 444        ssize_t ret;
 445
 446        spin_lock(&lstat->lock);
 447        ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->redirects);
 448        spin_unlock(&lstat->lock);
 449
 450        return ret;
 451}
 452
 453static ssize_t iscsi_stat_login_authorize_fails_show(struct config_item *item,
 454                char *page)
 455{
 456        struct iscsi_tiqn *tiqn = iscsi_login_stat_tiqn(item);
 457        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 458        ssize_t ret;
 459
 460        spin_lock(&lstat->lock);
 461        ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->authorize_fails);
 462        spin_unlock(&lstat->lock);
 463
 464        return ret;
 465}
 466
 467static ssize_t iscsi_stat_login_authenticate_fails_show(
 468                struct config_item *item, char *page)
 469{
 470        struct iscsi_tiqn *tiqn = iscsi_login_stat_tiqn(item);
 471        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 472        ssize_t ret;
 473
 474        spin_lock(&lstat->lock);
 475        ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->authenticate_fails);
 476        spin_unlock(&lstat->lock);
 477
 478        return ret;
 479}
 480
 481static ssize_t iscsi_stat_login_negotiate_fails_show(struct config_item *item,
 482                char *page)
 483{
 484        struct iscsi_tiqn *tiqn = iscsi_login_stat_tiqn(item);
 485        struct iscsi_login_stats *lstat = &tiqn->login_stats;
 486        ssize_t ret;
 487
 488        spin_lock(&lstat->lock);
 489        ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->negotiate_fails);
 490        spin_unlock(&lstat->lock);
 491
 492        return ret;
 493}
 494
 495CONFIGFS_ATTR_RO(iscsi_stat_login_, inst);
 496CONFIGFS_ATTR_RO(iscsi_stat_login_, indx);
 497CONFIGFS_ATTR_RO(iscsi_stat_login_, accepts);
 498CONFIGFS_ATTR_RO(iscsi_stat_login_, other_fails);
 499CONFIGFS_ATTR_RO(iscsi_stat_login_, redirects);
 500CONFIGFS_ATTR_RO(iscsi_stat_login_, authorize_fails);
 501CONFIGFS_ATTR_RO(iscsi_stat_login_, authenticate_fails);
 502CONFIGFS_ATTR_RO(iscsi_stat_login_, negotiate_fails);
 503
 504static struct configfs_attribute *iscsi_stat_login_stats_attrs[] = {
 505        &iscsi_stat_login_attr_inst,
 506        &iscsi_stat_login_attr_indx,
 507        &iscsi_stat_login_attr_accepts,
 508        &iscsi_stat_login_attr_other_fails,
 509        &iscsi_stat_login_attr_redirects,
 510        &iscsi_stat_login_attr_authorize_fails,
 511        &iscsi_stat_login_attr_authenticate_fails,
 512        &iscsi_stat_login_attr_negotiate_fails,
 513        NULL,
 514};
 515
 516const struct config_item_type iscsi_stat_login_cit = {
 517        .ct_attrs               = iscsi_stat_login_stats_attrs,
 518        .ct_owner               = THIS_MODULE,
 519};
 520
 521/*
 522 * Target Logout Stats Table
 523 */
 524static struct iscsi_tiqn *iscsi_logout_stat_tiqn(struct config_item *item)
 525{
 526        struct iscsi_wwn_stat_grps *igrps = container_of(to_config_group(item),
 527                        struct iscsi_wwn_stat_grps, iscsi_logout_stats_group);
 528        return container_of(igrps, struct iscsi_tiqn, tiqn_stat_grps);
 529}
 530
 531static ssize_t iscsi_stat_logout_inst_show(struct config_item *item, char *page)
 532{
 533        return snprintf(page, PAGE_SIZE, "%u\n",
 534                iscsi_logout_stat_tiqn(item)->tiqn_index);
 535}
 536
 537static ssize_t iscsi_stat_logout_indx_show(struct config_item *item, char *page)
 538{
 539        return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_NODE_INDEX);
 540}
 541
 542static ssize_t iscsi_stat_logout_normal_logouts_show(struct config_item *item,
 543                char *page)
 544{
 545        struct iscsi_tiqn *tiqn = iscsi_logout_stat_tiqn(item);
 546        struct iscsi_logout_stats *lstats = &tiqn->logout_stats;
 547
 548        return snprintf(page, PAGE_SIZE, "%u\n", lstats->normal_logouts);
 549}
 550
 551static ssize_t iscsi_stat_logout_abnormal_logouts_show(struct config_item *item,
 552                char *page)
 553{
 554        struct iscsi_tiqn *tiqn = iscsi_logout_stat_tiqn(item);
 555        struct iscsi_logout_stats *lstats = &tiqn->logout_stats;
 556
 557        return snprintf(page, PAGE_SIZE, "%u\n", lstats->abnormal_logouts);
 558}
 559
 560CONFIGFS_ATTR_RO(iscsi_stat_logout_, inst);
 561CONFIGFS_ATTR_RO(iscsi_stat_logout_, indx);
 562CONFIGFS_ATTR_RO(iscsi_stat_logout_, normal_logouts);
 563CONFIGFS_ATTR_RO(iscsi_stat_logout_, abnormal_logouts);
 564
 565static struct configfs_attribute *iscsi_stat_logout_stats_attrs[] = {
 566        &iscsi_stat_logout_attr_inst,
 567        &iscsi_stat_logout_attr_indx,
 568        &iscsi_stat_logout_attr_normal_logouts,
 569        &iscsi_stat_logout_attr_abnormal_logouts,
 570        NULL,
 571};
 572
 573const struct config_item_type iscsi_stat_logout_cit = {
 574        .ct_attrs               = iscsi_stat_logout_stats_attrs,
 575        .ct_owner               = THIS_MODULE,
 576};
 577
 578/*
 579 * Session Stats Table
 580 */
 581static struct iscsi_node_acl *iscsi_stat_nacl(struct config_item *item)
 582{
 583        struct iscsi_node_stat_grps *igrps = container_of(to_config_group(item),
 584                        struct iscsi_node_stat_grps, iscsi_sess_stats_group);
 585        return container_of(igrps, struct iscsi_node_acl, node_stat_grps);
 586}
 587
 588static ssize_t iscsi_stat_sess_inst_show(struct config_item *item, char *page)
 589{
 590        struct iscsi_node_acl *acl = iscsi_stat_nacl(item);
 591        struct se_wwn *wwn = acl->se_node_acl.se_tpg->se_tpg_wwn;
 592        struct iscsi_tiqn *tiqn = container_of(wwn,
 593                        struct iscsi_tiqn, tiqn_wwn);
 594
 595        return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
 596}
 597
 598static ssize_t iscsi_stat_sess_node_show(struct config_item *item, char *page)
 599{
 600        struct iscsi_node_acl *acl = iscsi_stat_nacl(item);
 601        struct se_node_acl *se_nacl = &acl->se_node_acl;
 602        struct iscsi_session *sess;
 603        struct se_session *se_sess;
 604        ssize_t ret = 0;
 605
 606        spin_lock_bh(&se_nacl->nacl_sess_lock);
 607        se_sess = se_nacl->nacl_sess;
 608        if (se_sess) {
 609                sess = se_sess->fabric_sess_ptr;
 610                if (sess)
 611                        ret = snprintf(page, PAGE_SIZE, "%u\n",
 612                                sess->sess_ops->SessionType ? 0 : ISCSI_NODE_INDEX);
 613        }
 614        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 615
 616        return ret;
 617}
 618
 619static ssize_t iscsi_stat_sess_indx_show(struct config_item *item, char *page)
 620{
 621        struct iscsi_node_acl *acl = iscsi_stat_nacl(item);
 622        struct se_node_acl *se_nacl = &acl->se_node_acl;
 623        struct iscsi_session *sess;
 624        struct se_session *se_sess;
 625        ssize_t ret = 0;
 626
 627        spin_lock_bh(&se_nacl->nacl_sess_lock);
 628        se_sess = se_nacl->nacl_sess;
 629        if (se_sess) {
 630                sess = se_sess->fabric_sess_ptr;
 631                if (sess)
 632                        ret = snprintf(page, PAGE_SIZE, "%u\n",
 633                                        sess->session_index);
 634        }
 635        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 636
 637        return ret;
 638}
 639
 640static ssize_t iscsi_stat_sess_cmd_pdus_show(struct config_item *item,
 641                char *page)
 642{
 643        struct iscsi_node_acl *acl = iscsi_stat_nacl(item);
 644        struct se_node_acl *se_nacl = &acl->se_node_acl;
 645        struct iscsi_session *sess;
 646        struct se_session *se_sess;
 647        ssize_t ret = 0;
 648
 649        spin_lock_bh(&se_nacl->nacl_sess_lock);
 650        se_sess = se_nacl->nacl_sess;
 651        if (se_sess) {
 652                sess = se_sess->fabric_sess_ptr;
 653                if (sess)
 654                        ret = snprintf(page, PAGE_SIZE, "%lu\n",
 655                                       atomic_long_read(&sess->cmd_pdus));
 656        }
 657        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 658
 659        return ret;
 660}
 661
 662static ssize_t iscsi_stat_sess_rsp_pdus_show(struct config_item *item,
 663                char *page)
 664{
 665        struct iscsi_node_acl *acl = iscsi_stat_nacl(item);
 666        struct se_node_acl *se_nacl = &acl->se_node_acl;
 667        struct iscsi_session *sess;
 668        struct se_session *se_sess;
 669        ssize_t ret = 0;
 670
 671        spin_lock_bh(&se_nacl->nacl_sess_lock);
 672        se_sess = se_nacl->nacl_sess;
 673        if (se_sess) {
 674                sess = se_sess->fabric_sess_ptr;
 675                if (sess)
 676                        ret = snprintf(page, PAGE_SIZE, "%lu\n",
 677                                       atomic_long_read(&sess->rsp_pdus));
 678        }
 679        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 680
 681        return ret;
 682}
 683
 684static ssize_t iscsi_stat_sess_txdata_octs_show(struct config_item *item,
 685                char *page)
 686{
 687        struct iscsi_node_acl *acl = iscsi_stat_nacl(item);
 688        struct se_node_acl *se_nacl = &acl->se_node_acl;
 689        struct iscsi_session *sess;
 690        struct se_session *se_sess;
 691        ssize_t ret = 0;
 692
 693        spin_lock_bh(&se_nacl->nacl_sess_lock);
 694        se_sess = se_nacl->nacl_sess;
 695        if (se_sess) {
 696                sess = se_sess->fabric_sess_ptr;
 697                if (sess)
 698                        ret = snprintf(page, PAGE_SIZE, "%lu\n",
 699                                       atomic_long_read(&sess->tx_data_octets));
 700        }
 701        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 702
 703        return ret;
 704}
 705
 706static ssize_t iscsi_stat_sess_rxdata_octs_show(struct config_item *item,
 707                char *page)
 708{
 709        struct iscsi_node_acl *acl = iscsi_stat_nacl(item);
 710        struct se_node_acl *se_nacl = &acl->se_node_acl;
 711        struct iscsi_session *sess;
 712        struct se_session *se_sess;
 713        ssize_t ret = 0;
 714
 715        spin_lock_bh(&se_nacl->nacl_sess_lock);
 716        se_sess = se_nacl->nacl_sess;
 717        if (se_sess) {
 718                sess = se_sess->fabric_sess_ptr;
 719                if (sess)
 720                        ret = snprintf(page, PAGE_SIZE, "%lu\n",
 721                                       atomic_long_read(&sess->rx_data_octets));
 722        }
 723        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 724
 725        return ret;
 726}
 727
 728static ssize_t iscsi_stat_sess_conn_digest_errors_show(struct config_item *item,
 729                char *page)
 730{
 731        struct iscsi_node_acl *acl = iscsi_stat_nacl(item);
 732        struct se_node_acl *se_nacl = &acl->se_node_acl;
 733        struct iscsi_session *sess;
 734        struct se_session *se_sess;
 735        ssize_t ret = 0;
 736
 737        spin_lock_bh(&se_nacl->nacl_sess_lock);
 738        se_sess = se_nacl->nacl_sess;
 739        if (se_sess) {
 740                sess = se_sess->fabric_sess_ptr;
 741                if (sess)
 742                        ret = snprintf(page, PAGE_SIZE, "%lu\n",
 743                                       atomic_long_read(&sess->conn_digest_errors));
 744        }
 745        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 746
 747        return ret;
 748}
 749
 750static ssize_t iscsi_stat_sess_conn_timeout_errors_show(
 751                struct config_item *item, char *page)
 752{
 753        struct iscsi_node_acl *acl = iscsi_stat_nacl(item);
 754        struct se_node_acl *se_nacl = &acl->se_node_acl;
 755        struct iscsi_session *sess;
 756        struct se_session *se_sess;
 757        ssize_t ret = 0;
 758
 759        spin_lock_bh(&se_nacl->nacl_sess_lock);
 760        se_sess = se_nacl->nacl_sess;
 761        if (se_sess) {
 762                sess = se_sess->fabric_sess_ptr;
 763                if (sess)
 764                        ret = snprintf(page, PAGE_SIZE, "%lu\n",
 765                                       atomic_long_read(&sess->conn_timeout_errors));
 766        }
 767        spin_unlock_bh(&se_nacl->nacl_sess_lock);
 768
 769        return ret;
 770}
 771
 772CONFIGFS_ATTR_RO(iscsi_stat_sess_, inst);
 773CONFIGFS_ATTR_RO(iscsi_stat_sess_, node);
 774CONFIGFS_ATTR_RO(iscsi_stat_sess_, indx);
 775CONFIGFS_ATTR_RO(iscsi_stat_sess_, cmd_pdus);
 776CONFIGFS_ATTR_RO(iscsi_stat_sess_, rsp_pdus);
 777CONFIGFS_ATTR_RO(iscsi_stat_sess_, txdata_octs);
 778CONFIGFS_ATTR_RO(iscsi_stat_sess_, rxdata_octs);
 779CONFIGFS_ATTR_RO(iscsi_stat_sess_, conn_digest_errors);
 780CONFIGFS_ATTR_RO(iscsi_stat_sess_, conn_timeout_errors);
 781
 782static struct configfs_attribute *iscsi_stat_sess_stats_attrs[] = {
 783        &iscsi_stat_sess_attr_inst,
 784        &iscsi_stat_sess_attr_node,
 785        &iscsi_stat_sess_attr_indx,
 786        &iscsi_stat_sess_attr_cmd_pdus,
 787        &iscsi_stat_sess_attr_rsp_pdus,
 788        &iscsi_stat_sess_attr_txdata_octs,
 789        &iscsi_stat_sess_attr_rxdata_octs,
 790        &iscsi_stat_sess_attr_conn_digest_errors,
 791        &iscsi_stat_sess_attr_conn_timeout_errors,
 792        NULL,
 793};
 794
 795const struct config_item_type iscsi_stat_sess_cit = {
 796        .ct_attrs               = iscsi_stat_sess_stats_attrs,
 797        .ct_owner               = THIS_MODULE,
 798};
 799