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