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