iscsi-target: Fix use-after-free during TPG session shutdown
[pandora-kernel.git] / drivers / target / iscsi / iscsi_target_stat.c
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 };