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  */
43 static 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 
50 static 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 
57 static 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 
63 static 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 
69 static 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 
76 static 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 
82 static 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 
89 static 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 
105 static 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 
115 static 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 
126 static 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 
132 static 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 
138 static 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 
144 static 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 
150 CONFIGFS_ATTR_RO(iscsi_stat_instance_, inst);
151 CONFIGFS_ATTR_RO(iscsi_stat_instance_, min_ver);
152 CONFIGFS_ATTR_RO(iscsi_stat_instance_, max_ver);
153 CONFIGFS_ATTR_RO(iscsi_stat_instance_, portals);
154 CONFIGFS_ATTR_RO(iscsi_stat_instance_, nodes);
155 CONFIGFS_ATTR_RO(iscsi_stat_instance_, sessions);
156 CONFIGFS_ATTR_RO(iscsi_stat_instance_, fail_sess);
157 CONFIGFS_ATTR_RO(iscsi_stat_instance_, fail_type);
158 CONFIGFS_ATTR_RO(iscsi_stat_instance_, fail_rem_name);
159 CONFIGFS_ATTR_RO(iscsi_stat_instance_, disc_time);
160 CONFIGFS_ATTR_RO(iscsi_stat_instance_, description);
161 CONFIGFS_ATTR_RO(iscsi_stat_instance_, vendor);
162 CONFIGFS_ATTR_RO(iscsi_stat_instance_, version);
163 
164 static 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 
181 const 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  */
189 static 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 
196 static 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 
203 static 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 
212 static 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 
221 static 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 
230 CONFIGFS_ATTR_RO(iscsi_stat_sess_err_, inst);
231 CONFIGFS_ATTR_RO(iscsi_stat_sess_err_, digest_errors);
232 CONFIGFS_ATTR_RO(iscsi_stat_sess_err_, cxn_errors);
233 CONFIGFS_ATTR_RO(iscsi_stat_sess_err_, format_errors);
234 
235 static 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 
243 const 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  */
251 static 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 
258 static 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 
265 static 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 
271 static 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 
287 static 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 
303 static 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 
317 static 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 
332 static 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 
349 static 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 
363 CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, inst);
364 CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, indx);
365 CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, login_fails);
366 CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, last_fail_time);
367 CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, last_fail_type);
368 CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, fail_intr_name);
369 CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, fail_intr_addr_type);
370 CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, fail_intr_addr);
371 
372 static 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 
384 const 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  */
392 static 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 
399 static 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 
405 static 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 
411 static 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 
425 static 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 
439 static 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 
453 static 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 
467 static 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 
481 static 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 
495 CONFIGFS_ATTR_RO(iscsi_stat_login_, inst);
496 CONFIGFS_ATTR_RO(iscsi_stat_login_, indx);
497 CONFIGFS_ATTR_RO(iscsi_stat_login_, accepts);
498 CONFIGFS_ATTR_RO(iscsi_stat_login_, other_fails);
499 CONFIGFS_ATTR_RO(iscsi_stat_login_, redirects);
500 CONFIGFS_ATTR_RO(iscsi_stat_login_, authorize_fails);
501 CONFIGFS_ATTR_RO(iscsi_stat_login_, authenticate_fails);
502 CONFIGFS_ATTR_RO(iscsi_stat_login_, negotiate_fails);
503 
504 static 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 
516 const 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  */
524 static 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 
531 static 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 
537 static 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 
542 static 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 
551 static 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 
560 CONFIGFS_ATTR_RO(iscsi_stat_logout_, inst);
561 CONFIGFS_ATTR_RO(iscsi_stat_logout_, indx);
562 CONFIGFS_ATTR_RO(iscsi_stat_logout_, normal_logouts);
563 CONFIGFS_ATTR_RO(iscsi_stat_logout_, abnormal_logouts);
564 
565 static 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 
573 const 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  */
581 static 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 
588 static 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 
598 static 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 
619 static 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 
640 static 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 
662 static 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 
684 static 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 
706 static 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 
728 static 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 
750 static 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 
772 CONFIGFS_ATTR_RO(iscsi_stat_sess_, inst);
773 CONFIGFS_ATTR_RO(iscsi_stat_sess_, node);
774 CONFIGFS_ATTR_RO(iscsi_stat_sess_, indx);
775 CONFIGFS_ATTR_RO(iscsi_stat_sess_, cmd_pdus);
776 CONFIGFS_ATTR_RO(iscsi_stat_sess_, rsp_pdus);
777 CONFIGFS_ATTR_RO(iscsi_stat_sess_, txdata_octs);
778 CONFIGFS_ATTR_RO(iscsi_stat_sess_, rxdata_octs);
779 CONFIGFS_ATTR_RO(iscsi_stat_sess_, conn_digest_errors);
780 CONFIGFS_ATTR_RO(iscsi_stat_sess_, conn_timeout_errors);
781 
782 static 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 
795 const struct config_item_type iscsi_stat_sess_cit = {
796 	.ct_attrs		= iscsi_stat_sess_stats_attrs,
797 	.ct_owner		= THIS_MODULE,
798 };
799