e3b3779f274532a7f5a95dbdd7f571ec3bcc6ea5
[mirror/scst/.git] / scst / src / scst_sysfs.c
1 /*
2  *  scst_sysfs.c
3  *
4  *  Copyright (C) 2009 Daniel Henrique Debonzi <debonzi@linux.vnet.ibm.com>
5  *  Copyright (C) 2009 Vladislav Bolkhovitin <vst@vlnb.net>
6  *  Copyright (C) 2009 ID7 Ltd.
7  *
8  *  This program is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU General Public License
10  *  as published by the Free Software Foundation, version 2
11  *  of the License.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  *  GNU General Public License for more details.
17  */
18
19 #include <linux/kobject.h>
20 #include <linux/string.h>
21 #include <linux/sysfs.h>
22 #include <linux/module.h>
23 #include <linux/init.h>
24 #include <linux/ctype.h>
25
26 #include "scst.h"
27 #include "scst_priv.h"
28 #include "scst_mem.h"
29
30 static DEFINE_MUTEX(scst_sysfs_mutex);
31
32 static DECLARE_COMPLETION(scst_sysfs_root_release_completion);
33
34 static struct kobject scst_sysfs_root_kobj;
35 static struct kobject *scst_targets_kobj;
36 static struct kobject *scst_devices_kobj;
37 static struct kobject *scst_sgv_kobj;
38 static struct kobject *scst_handlers_kobj;
39
40 struct sysfs_ops scst_sysfs_ops;
41 EXPORT_SYMBOL(scst_sysfs_ops);
42
43 static const char *scst_dev_handler_types[] = {
44     "Direct-access device (e.g., magnetic disk)",
45     "Sequential-access device (e.g., magnetic tape)",
46     "Printer device",
47     "Processor device",
48     "Write-once device (e.g., some optical disks)",
49     "CD-ROM device",
50     "Scanner device (obsolete)",
51     "Optical memory device (e.g., some optical disks)",
52     "Medium changer device (e.g., jukeboxes)",
53     "Communications device (obsolete)",
54     "Defined by ASC IT8 (Graphic arts pre-press devices)",
55     "Defined by ASC IT8 (Graphic arts pre-press devices)",
56     "Storage array controller device (e.g., RAID)",
57     "Enclosure services device",
58     "Simplified direct-access device (e.g., magnetic disk)",
59     "Optical card reader/writer device"
60 };
61
62 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
63
64 static DEFINE_MUTEX(scst_log_mutex);
65
66 static struct scst_trace_log scst_trace_tbl[] = {
67     { TRACE_OUT_OF_MEM,         "out_of_mem" },
68     { TRACE_MINOR,              "minor" },
69     { TRACE_SG_OP,              "sg" },
70     { TRACE_MEMORY,             "mem" },
71     { TRACE_BUFF,               "buff" },
72 #ifndef GENERATING_UPSTREAM_PATCH
73     { TRACE_ENTRYEXIT,          "entryexit" },
74 #endif
75     { TRACE_PID,                "pid" },
76     { TRACE_LINE,               "line" },
77     { TRACE_FUNCTION,           "function" },
78     { TRACE_DEBUG,              "debug" },
79     { TRACE_SPECIAL,            "special" },
80     { TRACE_SCSI,               "scsi" },
81     { TRACE_MGMT,               "mgmt" },
82     { TRACE_MGMT_MINOR,         "mgmt_minor" },
83     { TRACE_MGMT_DEBUG,         "mgmt_dbg" },
84     { TRACE_FLOW_CONTROL,       "flow_control" },
85     { 0,                        NULL }
86 };
87
88 static struct scst_trace_log scst_local_trace_tbl[] = {
89     { TRACE_RTRY,               "retry" },
90     { TRACE_SCSI_SERIALIZING,   "scsi_serializing" },
91     { TRACE_RCV_BOT,            "recv_bot" },
92     { TRACE_SND_BOT,            "send_bot" },
93     { TRACE_RCV_TOP,            "recv_top" },
94     { TRACE_SND_TOP,            "send_top" },
95     { 0,                        NULL }
96 };
97
98 static ssize_t scst_trace_level_show(const struct scst_trace_log *local_tbl,
99         unsigned long log_level, char *buf, const char *help);
100 static int scst_write_trace(const char *buf, size_t length,
101         unsigned long *log_level, unsigned long default_level,
102         const char *name, const struct scst_trace_log *tbl);
103
104 #endif /* defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) */
105
106 static ssize_t scst_luns_mgmt_show(struct kobject *kobj,
107                                    struct kobj_attribute *attr,
108                                    char *buf);
109 static ssize_t scst_luns_mgmt_store(struct kobject *kobj,
110                                     struct kobj_attribute *attr,
111                                     const char *buf, size_t count);
112
113 static void scst_sysfs_release(struct kobject *kobj)
114 {
115         kfree(kobj);
116 }
117
118 /*
119  * Target Template
120  */
121
122 static void scst_tgtt_release(struct kobject *kobj)
123 {
124         struct scst_tgt_template *tgtt;
125
126         TRACE_ENTRY();
127
128         tgtt = container_of(kobj, struct scst_tgt_template, tgtt_kobj);
129
130         complete_all(&tgtt->tgtt_kobj_release_cmpl);
131
132         scst_tgtt_cleanup(tgtt);
133
134         TRACE_EXIT();
135         return;
136 }
137
138 static struct kobj_type tgtt_ktype = {
139         .sysfs_ops = &scst_sysfs_ops,
140         .release = scst_tgtt_release,
141 };
142
143 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
144
145 static ssize_t scst_tgtt_trace_level_show(struct kobject *kobj,
146         struct kobj_attribute *attr, char *buf)
147 {
148         struct scst_tgt_template *tgtt;
149
150         tgtt = container_of(kobj, struct scst_tgt_template, tgtt_kobj);
151
152         return scst_trace_level_show(tgtt->trace_tbl,
153                 tgtt->trace_flags ? *tgtt->trace_flags : 0, buf,
154                 tgtt->trace_tbl_help);
155 }
156
157 static ssize_t scst_tgtt_trace_level_store(struct kobject *kobj,
158         struct kobj_attribute *attr, const char *buf, size_t count)
159 {
160         int res;
161         struct scst_tgt_template *tgtt;
162
163         TRACE_ENTRY();
164
165         tgtt = container_of(kobj, struct scst_tgt_template, tgtt_kobj);
166
167         if (mutex_lock_interruptible(&scst_log_mutex) != 0) {
168                 res = -EINTR;
169                 goto out;
170         }
171
172         res = scst_write_trace(buf, count, tgtt->trace_flags,
173                 tgtt->default_trace_flags, tgtt->name, tgtt->trace_tbl);
174
175         mutex_unlock(&scst_log_mutex);
176
177 out:
178         TRACE_EXIT_RES(res);
179         return res;
180 }
181
182 static struct kobj_attribute tgtt_trace_attr =
183         __ATTR(trace_level, S_IRUGO | S_IWUSR,
184                scst_tgtt_trace_level_show, scst_tgtt_trace_level_store);
185
186 #endif /* #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) */
187
188 int scst_create_tgtt_sysfs(struct scst_tgt_template *tgtt)
189 {
190         int retval = 0;
191         const struct attribute **pattr;
192
193         TRACE_ENTRY();
194
195         init_completion(&tgtt->tgtt_kobj_release_cmpl);
196
197         tgtt->tgtt_kobj_initialized = 1;
198
199         retval = kobject_init_and_add(&tgtt->tgtt_kobj, &tgtt_ktype,
200                         scst_targets_kobj, tgtt->name);
201         if (retval != 0) {
202                 PRINT_ERROR("Can't add tgtt %s to sysfs", tgtt->name);
203                 goto out;
204         }
205
206         /*
207          * In case of errors there's no need for additional cleanup, because
208          * it will be done by the _put function() called by the caller.
209          */
210
211         pattr = tgtt->tgtt_attrs;
212         if (pattr != NULL) {
213                 while (*pattr != NULL) {
214                         TRACE_DBG("Creating attr %s for target driver %s",
215                                 (*pattr)->name, tgtt->name);
216                         retval = sysfs_create_file(&tgtt->tgtt_kobj, *pattr);
217                         if (retval != 0) {
218                                 PRINT_ERROR("Can't add attr %s for target "
219                                         "driver %s", (*pattr)->name,
220                                         tgtt->name);
221                                 goto out;
222                         }
223                         pattr++;
224                 }
225         }
226
227 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
228         if (tgtt->trace_flags != NULL) {
229                 retval = sysfs_create_file(&tgtt->tgtt_kobj,
230                                 &tgtt_trace_attr.attr);
231                 if (retval != 0) {
232                         PRINT_ERROR("Can't add trace_flag for target "
233                                 "driver %s", tgtt->name);
234                         goto out;
235                 }
236         }
237 #endif
238
239 out:
240         TRACE_EXIT_RES(retval);
241         return retval;
242 }
243
244 void scst_tgtt_sysfs_put(struct scst_tgt_template *tgtt)
245 {
246         TRACE_ENTRY();
247
248         if (tgtt->tgtt_kobj_initialized) {
249                 int rc;
250
251                 kobject_del(&tgtt->tgtt_kobj);
252                 kobject_put(&tgtt->tgtt_kobj);
253
254                 rc = wait_for_completion_timeout(&tgtt->tgtt_kobj_release_cmpl, HZ);
255                 if (rc == 0) {
256                         PRINT_INFO("Waiting for releasing sysfs entry "
257                                 "for target template %s...", tgtt->name);
258                         wait_for_completion(&tgtt->tgtt_kobj_release_cmpl);
259                         PRINT_INFO("Done waiting for releasing sysfs "
260                                 "entry for target template %s", tgtt->name);
261                 }
262         } else
263                 scst_tgtt_cleanup(tgtt);
264
265         TRACE_EXIT();
266         return;
267 }
268
269 /*
270  * Target directory implementation
271  */
272
273 static void scst_tgt_release(struct kobject *kobj)
274 {
275         struct scst_tgt *tgt;
276
277         TRACE_ENTRY();
278
279         tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
280
281         /* Let's make lockdep happy */
282         up_write(&tgt->tgt_attr_rwsem);
283
284         scst_free_tgt(tgt);
285
286         TRACE_EXIT();
287         return;
288 }
289
290 static ssize_t scst_tgt_attr_show(struct kobject *kobj, struct attribute *attr,
291                          char *buf)
292 {
293         int res;
294         struct kobj_attribute *kobj_attr;
295         struct scst_tgt *tgt;
296
297         tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
298
299         if (down_read_trylock(&tgt->tgt_attr_rwsem) == 0) {
300                 res = -ENOENT;
301                 goto out;
302         }
303
304         kobj_attr = container_of(attr, struct kobj_attribute, attr);
305
306         res = kobj_attr->show(kobj, kobj_attr, buf);
307
308         up_read(&tgt->tgt_attr_rwsem);
309
310 out:
311         return res;
312 }
313
314 static ssize_t scst_tgt_attr_store(struct kobject *kobj, struct attribute *attr,
315                           const char *buf, size_t count)
316 {
317         int res;
318         struct kobj_attribute *kobj_attr;
319         struct scst_tgt *tgt;
320
321         tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
322
323         if (down_read_trylock(&tgt->tgt_attr_rwsem) == 0) {
324                 res = -ENOENT;
325                 goto out;
326         }
327
328         kobj_attr = container_of(attr, struct kobj_attribute, attr);
329
330         res = kobj_attr->store(kobj, kobj_attr, buf, count);
331
332         up_read(&tgt->tgt_attr_rwsem);
333
334 out:
335         return res;
336 }
337
338 static struct sysfs_ops scst_tgt_sysfs_ops = {
339         .show = scst_tgt_attr_show,
340         .store = scst_tgt_attr_store,
341 };
342
343 static struct kobj_type tgt_ktype = {
344         .sysfs_ops = &scst_tgt_sysfs_ops,
345         .release = scst_tgt_release,
346 };
347
348 static struct kobj_attribute scst_luns_mgmt =
349         __ATTR(mgmt, S_IRUGO | S_IWUSR, scst_luns_mgmt_show,
350                scst_luns_mgmt_store);
351
352 static ssize_t scst_tgt_enable_show(struct kobject *kobj,
353         struct kobj_attribute *attr, char *buf)
354 {
355         struct scst_tgt *tgt;
356         int res;
357         bool enabled;
358
359         TRACE_ENTRY();
360
361         tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
362
363         enabled = tgt->tgtt->is_tgt_enabled(tgt);
364
365         res = sprintf(buf, "%d\n", enabled ? 1 : 0);
366
367         TRACE_EXIT_RES(res);
368         return res;
369 }
370
371 static ssize_t scst_tgt_enable_store(struct kobject *kobj,
372         struct kobj_attribute *attr, const char *buf, size_t count)
373 {
374         int res;
375         struct scst_tgt *tgt;
376
377         TRACE_ENTRY();
378
379         if (buf == NULL)
380                 goto out_err;
381
382         tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
383
384         res = tgt->tgtt->enable_tgt(tgt, buf, count);
385
386 out:
387         TRACE_EXIT_RES(res);
388         return res;
389
390 out_err:
391         PRINT_ERROR("%s: Requested action not understood: %s", __func__, buf);
392         res = -EINVAL;
393         goto out;
394 }
395
396 static struct kobj_attribute tgt_enable_attr =
397         __ATTR(enabled, S_IRUGO | S_IWUSR,
398                scst_tgt_enable_show, scst_tgt_enable_store);
399
400 int scst_create_tgt_sysfs(struct scst_tgt *tgt)
401 {
402         int retval;
403         const struct attribute **pattr;
404
405         TRACE_ENTRY();
406
407         init_rwsem(&tgt->tgt_attr_rwsem);
408
409         tgt->tgt_kobj_initialized = 1;
410
411         retval = kobject_init_and_add(&tgt->tgt_kobj, &tgt_ktype,
412                         &tgt->tgtt->tgtt_kobj, tgt->tgt_name);
413         if (retval != 0) {
414                 PRINT_ERROR("Can't add tgt %s to sysfs", tgt->tgt_name);
415                 goto out;
416         }
417
418         /*
419          * In case of errors there's no need for additional cleanup, because
420          * it will be done by the _put function() called by the caller.
421          */
422
423         if ((tgt->tgtt->enable_tgt != NULL) &&
424             (tgt->tgtt->is_tgt_enabled != NULL)) {
425                 retval = sysfs_create_file(&tgt->tgt_kobj,
426                                 &tgt_enable_attr.attr);
427                 if (retval != 0) {
428                         PRINT_ERROR("Can't add attr %s to sysfs",
429                                 tgt_enable_attr.attr.name);
430                         goto out;
431                 }
432         }
433
434         tgt->tgt_sess_kobj = kobject_create_and_add("sessions", &tgt->tgt_kobj);
435         if (tgt->tgt_sess_kobj == NULL) {
436                 PRINT_ERROR("Can't create sess kobj for tgt %s", tgt->tgt_name);
437                 goto out_nomem;
438         }
439
440         tgt->tgt_luns_kobj = kobject_create_and_add("luns", &tgt->tgt_kobj);
441         if (tgt->tgt_luns_kobj == NULL) {
442                 PRINT_ERROR("Can't create luns kobj for tgt %s", tgt->tgt_name);
443                 goto out_nomem;
444         }
445
446         retval = sysfs_create_file(tgt->tgt_luns_kobj, &scst_luns_mgmt.attr);
447         if (retval != 0) {
448                 PRINT_ERROR("Can't add tgt attr %s for tgt %s",
449                         scst_luns_mgmt.attr.name, tgt->tgt_name);
450                 goto out;
451         }
452
453         tgt->tgt_ini_grp_kobj = kobject_create_and_add("ini_group",
454                                         &tgt->tgt_kobj);
455         if (tgt->tgt_ini_grp_kobj == NULL) {
456                 PRINT_ERROR("Can't create ini_grp kobj for tgt %s",
457                         tgt->tgt_name);
458                 goto out_nomem;
459         }
460
461         pattr = tgt->tgtt->tgt_attrs;
462         if (pattr != NULL) {
463                 while (*pattr != NULL) {
464                         TRACE_DBG("Creating attr %s for tgt %s", (*pattr)->name,
465                                 tgt->tgt_name);
466                         retval = sysfs_create_file(&tgt->tgt_kobj, *pattr);
467                         if (retval != 0) {
468                                 PRINT_ERROR("Can't add tgt attr %s for tgt %s",
469                                         (*pattr)->name, tgt->tgt_name);
470                                 goto out;
471                         }
472                         pattr++;
473                 }
474         }
475
476 out:
477         TRACE_EXIT_RES(retval);
478         return retval;
479
480 out_nomem:
481         retval = -ENOMEM;
482         goto out;
483 }
484
485 /*
486  * Must not be called under scst_mutex or there can be a deadlock with
487  * tgt_attr_rwsem
488  */
489 void scst_tgt_sysfs_prepare_put(struct scst_tgt *tgt)
490 {
491         if (tgt->tgt_kobj_initialized) {
492                 down_write(&tgt->tgt_attr_rwsem);
493                 tgt->tgt_kobj_put_prepared = 1;
494         }
495
496         return;
497 }
498
499 /*
500  * Must not be called under scst_mutex or there can be a deadlock with
501  * tgt_attr_rwsem
502  */
503 void scst_tgt_sysfs_put(struct scst_tgt *tgt)
504 {
505         if (tgt->tgt_kobj_initialized) {
506                 kobject_del(tgt->tgt_sess_kobj);
507                 kobject_put(tgt->tgt_sess_kobj);
508
509                 sysfs_remove_file(tgt->tgt_luns_kobj, &scst_luns_mgmt.attr);
510
511                 kobject_del(tgt->tgt_luns_kobj);
512                 kobject_put(tgt->tgt_luns_kobj);
513
514                 kobject_del(tgt->tgt_ini_grp_kobj);
515                 kobject_put(tgt->tgt_ini_grp_kobj);
516
517                 kobject_del(&tgt->tgt_kobj);
518
519                 if (!tgt->tgt_kobj_put_prepared)
520                         down_write(&tgt->tgt_attr_rwsem);
521                 kobject_put(&tgt->tgt_kobj);
522         } else
523                 scst_free_tgt(tgt);
524         return;
525 }
526
527 /*
528  * Devices directory implementation
529  */
530
531 ssize_t scst_device_sysfs_type_show(struct kobject *kobj,
532                             struct kobj_attribute *attr, char *buf)
533 {
534         int pos = 0;
535
536         struct scst_device *dev;
537
538         dev = container_of(kobj, struct scst_device, dev_kobj);
539
540         pos = sprintf(buf, "%d - %s\n", dev->type,
541                 (unsigned)dev->type > ARRAY_SIZE(scst_dev_handler_types) ?
542                       "unknown" : scst_dev_handler_types[dev->type]);
543
544         return pos;
545 }
546
547 static struct kobj_attribute device_type_attr =
548         __ATTR(type, S_IRUGO, scst_device_sysfs_type_show, NULL);
549
550 static struct attribute *scst_device_attrs[] = {
551         &device_type_attr.attr,
552         NULL,
553 };
554
555 static void scst_sysfs_device_release(struct kobject *kobj)
556 {
557         struct scst_device *dev;
558
559         TRACE_ENTRY();
560
561         dev = container_of(kobj, struct scst_device, dev_kobj);
562
563         /* Let's make lockdep happy */
564         up_write(&dev->dev_attr_rwsem);
565
566         scst_free_device(dev);
567
568         TRACE_EXIT();
569         return;
570 }
571
572 int scst_create_devt_dev_sysfs(struct scst_device *dev)
573 {
574         int retval = 0;
575         const struct attribute **pattr;
576
577         TRACE_ENTRY();
578
579         if (dev->handler == &scst_null_devtype)
580                 goto out;
581
582         sBUG_ON(!dev->handler->devt_kobj_initialized);
583
584         /*
585          * In case of errors there's no need for additional cleanup, because
586          * it will be done by the _put function() called by the caller.
587          */
588
589         retval = sysfs_create_link(&dev->dev_kobj,
590                         &dev->handler->devt_kobj, "handler");
591         if (retval != 0) {
592                 PRINT_ERROR("Can't create handler link for dev %s",
593                         dev->virt_name);
594                 goto out;
595         }
596
597         pattr = dev->handler->dev_attrs;
598         if (pattr != NULL) {
599                 while (*pattr != NULL) {
600                         retval = sysfs_create_file(&dev->dev_kobj, *pattr);
601                         if (retval != 0) {
602                                 PRINT_ERROR("Can't add dev attr %s for dev %s",
603                                         (*pattr)->name, dev->virt_name);
604                                 goto out;
605                         }
606                         pattr++;
607                 }
608         }
609
610 out:
611         TRACE_EXIT_RES(retval);
612         return retval;
613 }
614
615 void scst_devt_dev_sysfs_put(struct scst_device *dev)
616 {
617         const struct attribute **pattr;
618
619         TRACE_ENTRY();
620
621         if (dev->handler == &scst_null_devtype)
622                 goto out;
623
624         sBUG_ON(!dev->handler->devt_kobj_initialized);
625
626         pattr = dev->handler->dev_attrs;
627         if (pattr != NULL) {
628                 while (*pattr != NULL) {
629                         sysfs_remove_file(&dev->dev_kobj, *pattr);
630                         pattr++;
631                 }
632         }
633
634         sysfs_remove_link(&dev->dev_kobj, "handler");
635
636 out:
637         TRACE_EXIT();
638         return;
639 }
640
641 static ssize_t scst_dev_attr_show(struct kobject *kobj, struct attribute *attr,
642                          char *buf)
643 {
644         int res;
645         struct kobj_attribute *kobj_attr;
646         struct scst_device *dev;
647
648         dev = container_of(kobj, struct scst_device, dev_kobj);
649
650         if (down_read_trylock(&dev->dev_attr_rwsem) == 0) {
651                 res = -ENOENT;
652                 goto out;
653         }
654
655         kobj_attr = container_of(attr, struct kobj_attribute, attr);
656
657         res = kobj_attr->show(kobj, kobj_attr, buf);
658
659         up_read(&dev->dev_attr_rwsem);
660
661 out:
662         return res;
663 }
664
665 static ssize_t scst_dev_attr_store(struct kobject *kobj, struct attribute *attr,
666                           const char *buf, size_t count)
667 {
668         int res;
669         struct kobj_attribute *kobj_attr;
670         struct scst_device *dev;
671
672         dev = container_of(kobj, struct scst_device, dev_kobj);
673
674         if (down_read_trylock(&dev->dev_attr_rwsem) == 0) {
675                 res = -ENOENT;
676                 goto out;
677         }
678
679         kobj_attr = container_of(attr, struct kobj_attribute, attr);
680
681         res = kobj_attr->store(kobj, kobj_attr, buf, count);
682
683         up_read(&dev->dev_attr_rwsem);
684
685 out:
686         return res;
687 }
688
689 static struct sysfs_ops scst_dev_sysfs_ops = {
690         .show = scst_dev_attr_show,
691         .store = scst_dev_attr_store,
692 };
693
694 static struct kobj_type scst_device_ktype = {
695         .sysfs_ops = &scst_dev_sysfs_ops,
696         .release = scst_sysfs_device_release,
697         .default_attrs = scst_device_attrs,
698 };
699
700 int scst_create_device_sysfs(struct scst_device *dev)
701 {
702         int retval = 0;
703
704         TRACE_ENTRY();
705
706         init_rwsem(&dev->dev_attr_rwsem);
707
708         dev->dev_kobj_initialized = 1;
709
710         retval = kobject_init_and_add(&dev->dev_kobj, &scst_device_ktype,
711                                       scst_devices_kobj, dev->virt_name);
712         if (retval != 0) {
713                 PRINT_ERROR("Can't add device %s to sysfs", dev->virt_name);
714                 goto out;
715         }
716
717         /*
718          * In case of errors there's no need for additional cleanup, because
719          * it will be done by the _put function() called by the caller.
720          */
721
722         dev->dev_exp_kobj = kobject_create_and_add("exported",
723                                                    &dev->dev_kobj);
724         if (dev->dev_exp_kobj == NULL) {
725                 PRINT_ERROR("Can't create exported link for device %s",
726                         dev->virt_name);
727                 retval = -ENOMEM;
728                 goto out;
729         }
730
731         if (dev->scsi_dev != NULL) {
732                 retval = sysfs_create_link(&dev->dev_kobj,
733                         &dev->scsi_dev->sdev_dev.kobj, "scsi_device");
734                 if (retval != 0) {
735                         PRINT_ERROR("Can't create scsi_device link for dev %s",
736                                 dev->virt_name);
737                         goto out;
738                 }
739         }
740
741 out:
742         TRACE_EXIT_RES(retval);
743         return retval;
744 }
745
746 /*
747  * Must not be called under scst_mutex or there can be a deadlock with
748  * dev_attr_rwsem
749  */
750 void scst_device_sysfs_put(struct scst_device *dev)
751 {
752         TRACE_ENTRY();
753
754         if (dev->dev_kobj_initialized) {
755                 if (dev->dev_exp_kobj != NULL) {
756                         kobject_del(dev->dev_exp_kobj);
757                         kobject_put(dev->dev_exp_kobj);
758                 }
759                 kobject_del(&dev->dev_kobj);
760
761                 down_write(&dev->dev_attr_rwsem);
762                 kobject_put(&dev->dev_kobj);
763         } else
764                 scst_free_device(dev);
765
766         TRACE_EXIT();
767         return;
768 }
769
770 /*
771  * Target sessions directory implementation
772  */
773
774 static ssize_t scst_sess_sysfs_commands_show(struct kobject *kobj,
775                             struct kobj_attribute *attr, char *buf)
776 {
777         struct scst_session *sess;
778
779         sess = container_of(kobj, struct scst_session, sess_kobj);
780
781         return sprintf(buf, "%i\n", atomic_read(&sess->sess_cmd_count));
782 }
783
784 static struct kobj_attribute session_commands_attr =
785         __ATTR(commands, S_IRUGO, scst_sess_sysfs_commands_show, NULL);
786
787 static ssize_t scst_sess_sysfs_active_commands_show(struct kobject *kobj,
788                             struct kobj_attribute *attr, char *buf)
789 {
790         int res;
791         struct scst_session *sess;
792         int active_cmds = 0, t;
793
794         if (mutex_lock_interruptible(&scst_mutex) != 0) {
795                 res = -EINTR;
796                 goto out;
797         }
798
799         sess = container_of(kobj, struct scst_session, sess_kobj);
800
801         for (t = TGT_DEV_HASH_SIZE-1; t >= 0; t--) {
802                 struct list_head *sess_tgt_dev_list_head =
803                         &sess->sess_tgt_dev_list_hash[t];
804                 struct scst_tgt_dev *tgt_dev;
805                 list_for_each_entry(tgt_dev, sess_tgt_dev_list_head,
806                                 sess_tgt_dev_list_entry) {
807                         active_cmds += atomic_read(&tgt_dev->tgt_dev_cmd_count);
808                 }
809         }
810
811         mutex_unlock(&scst_mutex);
812
813         res = sprintf(buf, "%i\n", active_cmds);
814
815 out:
816         return res;
817 }
818
819 static struct kobj_attribute session_active_commands_attr =
820         __ATTR(commands, S_IRUGO, scst_sess_sysfs_active_commands_show, NULL);
821
822 static ssize_t scst_sess_sysfs_initiator_name_show(struct kobject *kobj,
823                             struct kobj_attribute *attr, char *buf)
824 {
825         struct scst_session *sess;
826
827         sess = container_of(kobj, struct scst_session, sess_kobj);
828
829         return scnprintf(buf, SCST_SYSFS_BLOCK_SIZE, "%s\n",
830                 sess->initiator_name);
831 }
832
833 static struct kobj_attribute session_initiator_name_attr =
834         __ATTR(initiator_name, S_IRUGO, scst_sess_sysfs_initiator_name_show, NULL);
835
836 static struct attribute *scst_session_attrs[] = {
837         &session_commands_attr.attr,
838         &session_active_commands_attr.attr,
839         &session_initiator_name_attr.attr,
840         NULL,
841 };
842
843 static void scst_sysfs_session_release(struct kobject *kobj)
844 {
845         struct scst_session *sess;
846
847         TRACE_ENTRY();
848
849         sess = container_of(kobj, struct scst_session, sess_kobj);
850
851         /* Let's make lockdep happy */
852         up_write(&sess->sess_attr_rwsem);
853
854         scst_release_session(sess);
855
856         TRACE_EXIT();
857         return;
858 }
859
860 static ssize_t scst_sess_attr_show(struct kobject *kobj, struct attribute *attr,
861                          char *buf)
862 {
863         int res;
864         struct kobj_attribute *kobj_attr;
865         struct scst_session *sess;
866
867         sess = container_of(kobj, struct scst_session, sess_kobj);
868
869         if (down_read_trylock(&sess->sess_attr_rwsem) == 0) {
870                 res = -ENOENT;
871                 goto out;
872         }
873
874         kobj_attr = container_of(attr, struct kobj_attribute, attr);
875
876         res = kobj_attr->show(kobj, kobj_attr, buf);
877
878         up_read(&sess->sess_attr_rwsem);
879
880 out:
881         return res;
882 }
883
884 static ssize_t scst_sess_attr_store(struct kobject *kobj, struct attribute *attr,
885                           const char *buf, size_t count)
886 {
887         int res;
888         struct kobj_attribute *kobj_attr;
889         struct scst_session *sess;
890
891         sess = container_of(kobj, struct scst_session, sess_kobj);
892
893         if (down_read_trylock(&sess->sess_attr_rwsem) == 0) {
894                 res = -ENOENT;
895                 goto out;
896         }
897
898         kobj_attr = container_of(attr, struct kobj_attribute, attr);
899
900         res = kobj_attr->store(kobj, kobj_attr, buf, count);
901
902         up_read(&sess->sess_attr_rwsem);
903
904 out:
905         return res;
906 }
907
908 static struct sysfs_ops scst_sess_sysfs_ops = {
909         .show = scst_sess_attr_show,
910         .store = scst_sess_attr_store,
911 };
912
913 static struct kobj_type scst_session_ktype = {
914         .sysfs_ops = &scst_sess_sysfs_ops,
915         .release = scst_sysfs_session_release,
916         .default_attrs = scst_session_attrs,
917 };
918
919 /* scst_mutex supposed to be locked */
920 int scst_create_sess_sysfs(struct scst_session *sess)
921 {
922         int retval = 0;
923         struct scst_session *s;
924         const struct attribute **pattr;
925         char *name = (char *)sess->initiator_name;
926         int len = strlen(name) + 1, n = 1;
927
928         TRACE_ENTRY();
929
930 restart:
931         list_for_each_entry(s, &sess->tgt->sess_list, sess_list_entry) {
932                 if (!s->sess_kobj_initialized)
933                         continue;
934
935                 if (strcmp(name, kobject_name(&s->sess_kobj)) == 0) {
936                         if (s == sess)
937                                 continue;
938
939                         TRACE_DBG("Dublicated session from the same initiator "
940                                 "%s found", name);
941
942                         if (name == sess->initiator_name) {
943                                 len = strlen(sess->initiator_name);
944                                 len += 20;
945                                 name = kmalloc(len, GFP_KERNEL);
946                                 if (name == NULL) {
947                                         PRINT_ERROR("Unable to allocate a "
948                                                 "replacement name (size %d)",
949                                                 len);
950                                 }
951                         }
952
953                         snprintf(name, len, "%s_%d", sess->initiator_name, n);
954                         n++;
955                         goto restart;
956                 }
957         }
958
959         init_rwsem(&sess->sess_attr_rwsem);
960
961         sess->sess_kobj_initialized = 1;
962
963         retval = kobject_init_and_add(&sess->sess_kobj, &scst_session_ktype,
964                               sess->tgt->tgt_sess_kobj, name);
965         if (retval != 0) {
966                 PRINT_ERROR("Can't add session %s to sysfs", name);
967                 goto out_free;
968         }
969
970         /*
971          * In case of errors there's no need for additional cleanup, because
972          * it will be done by the _put function() called by the caller.
973          */
974
975         pattr = sess->tgt->tgtt->sess_attrs;
976         if (pattr != NULL) {
977                 while (*pattr != NULL) {
978                         retval = sysfs_create_file(&sess->sess_kobj, *pattr);
979                         if (retval != 0) {
980                                 PRINT_ERROR("Can't add sess attr %s for sess "
981                                         "for initiator %s", (*pattr)->name,
982                                         name);
983                                 goto out_free;
984                         }
985                         pattr++;
986                 }
987         }
988
989 out_free:
990         if (name != sess->initiator_name)
991                 kfree(name);
992
993         TRACE_EXIT_RES(retval);
994         return retval;
995 }
996
997 /*
998  * Must not be called under scst_mutex or there can be a deadlock with
999  * sess_attr_rwsem
1000  */
1001 void scst_sess_sysfs_put(struct scst_session *sess)
1002 {
1003         TRACE_ENTRY();
1004
1005         if (sess->sess_kobj_initialized) {
1006                 kobject_del(&sess->sess_kobj);
1007
1008                 down_write(&sess->sess_attr_rwsem);
1009                 kobject_put(&sess->sess_kobj);
1010         } else
1011                 scst_release_session(sess);
1012
1013         TRACE_EXIT();
1014         return;
1015 }
1016
1017 /*
1018  * Target luns directory implementation
1019  */
1020
1021 static void scst_acg_dev_release(struct kobject *kobj)
1022 {
1023         struct scst_acg_dev *acg_dev;
1024
1025         TRACE_ENTRY();
1026
1027         acg_dev = container_of(kobj, struct scst_acg_dev, acg_dev_kobj);
1028
1029         scst_acg_dev_destroy(acg_dev);
1030
1031         TRACE_EXIT();
1032         return;
1033 }
1034
1035 static ssize_t scst_lun_rd_only_show(struct kobject *kobj,
1036                                    struct kobj_attribute *attr,
1037                                    char *buf)
1038 {
1039         struct scst_acg_dev *acg_dev;
1040
1041         acg_dev = container_of(kobj, struct scst_acg_dev, acg_dev_kobj);
1042
1043         return sprintf(buf, "%d\n",
1044                 (acg_dev->rd_only || acg_dev->dev->rd_only) ? 1 : 0);
1045 }
1046
1047 static struct kobj_attribute lun_options_attr =
1048         __ATTR(read_only, S_IRUGO, scst_lun_rd_only_show, NULL);
1049
1050 static struct attribute *lun_attrs[] = {
1051         &lun_options_attr.attr,
1052         NULL,
1053 };
1054
1055 static struct kobj_type acg_dev_ktype = {
1056         .sysfs_ops = &scst_sysfs_ops,
1057         .release = scst_acg_dev_release,
1058         .default_attrs = lun_attrs,
1059 };
1060
1061 int scst_create_acg_dev_sysfs(struct scst_acg *acg, unsigned int virt_lun,
1062         struct kobject *parent)
1063 {
1064         int retval;
1065         struct scst_acg_dev *acg_dev = NULL, *acg_dev_tmp;
1066         char str[20];
1067
1068         TRACE_ENTRY();
1069
1070         list_for_each_entry(acg_dev_tmp, &acg->acg_dev_list,
1071                             acg_dev_list_entry) {
1072                 if (acg_dev_tmp->lun == virt_lun) {
1073                         acg_dev = acg_dev_tmp;
1074                         break;
1075                 }
1076         }
1077         if (acg_dev == NULL) {
1078                 PRINT_ERROR("%s", "acg_dev lookup for kobject creation failed");
1079                 retval = -EINVAL;
1080                 goto out;
1081         }
1082
1083         snprintf(str, sizeof(str), "export%u",
1084                 acg_dev->dev->dev_exported_lun_num++);
1085
1086         acg_dev->acg_dev_kobj_initialized = 1;
1087
1088         retval = kobject_init_and_add(&acg_dev->acg_dev_kobj, &acg_dev_ktype,
1089                                       parent, "%u", virt_lun);
1090         if (retval != 0) {
1091                 PRINT_ERROR("Can't add acg %s to sysfs", acg->acg_name);
1092                 goto out;
1093         }
1094
1095         /*
1096          * In case of errors there's no need for additional cleanup, because
1097          * it will be done by the _put function() called by the caller.
1098          */
1099
1100         retval = sysfs_create_link(acg_dev->dev->dev_exp_kobj,
1101                                    &acg_dev->acg_dev_kobj, str);
1102         if (retval != 0) {
1103                 PRINT_ERROR("Can't create acg %s LUN link", acg->acg_name);
1104                 goto out;
1105         }
1106
1107         retval = sysfs_create_link(&acg_dev->acg_dev_kobj,
1108                         &acg_dev->dev->dev_kobj, "device");
1109         if (retval != 0) {
1110                 PRINT_ERROR("Can't create acg %s device link", acg->acg_name);
1111                 goto out;
1112         }
1113
1114 out:
1115         return retval;
1116 }
1117
1118 static ssize_t scst_luns_mgmt_show(struct kobject *kobj,
1119                                    struct kobj_attribute *attr,
1120                                    char *buf)
1121 {
1122         static char *help = "Usage: echo \"add|del H:C:I:L lun [READ_ONLY]\" "
1123                                         ">mgmt\n"
1124                             "       echo \"add|del VNAME lun [READ_ONLY]\" "
1125                                         ">mgmt\n";
1126
1127         return sprintf(buf, help);
1128 }
1129
1130 static ssize_t scst_luns_mgmt_store(struct kobject *kobj,
1131                                     struct kobj_attribute *attr,
1132                                     const char *buf, size_t count)
1133 {
1134         int res, virt = 0, read_only = 0, action;
1135         char *buffer, *p, *e = NULL;
1136         unsigned int host, channel = 0, id = 0, lun = 0, virt_lun;
1137         struct scst_acg *acg;
1138         struct scst_acg_dev *acg_dev = NULL, *acg_dev_tmp;
1139         struct scst_device *d, *dev = NULL;
1140         struct scst_tgt *tgt;
1141
1142 #define SCST_LUN_ACTION_ADD     1
1143 #define SCST_LUN_ACTION_DEL     2
1144 #define SCST_LUN_ACTION_REPLACE 3
1145
1146         TRACE_ENTRY();
1147
1148         tgt = container_of(kobj->parent, struct scst_tgt, tgt_kobj);
1149         acg = tgt->default_acg;
1150
1151         buffer = kzalloc(count+1, GFP_KERNEL);
1152         if (buffer == NULL) {
1153                 res = -ENOMEM;
1154                 goto out;
1155         }
1156
1157         memcpy(buffer, buf, count);
1158         buffer[count] = '\0';
1159         p = buffer;
1160
1161         p = buffer;
1162         if (p[strlen(p) - 1] == '\n')
1163                 p[strlen(p) - 1] = '\0';
1164         if (strncasecmp("add", p, 3) == 0) {
1165                 p += 3;
1166                 action = SCST_LUN_ACTION_ADD;
1167         } else if (strncasecmp("del", p, 3) == 0) {
1168                 p += 3;
1169                 action = SCST_LUN_ACTION_DEL;
1170         } else if (!strncasecmp("replace", p, 7)) {
1171                 p += 7;
1172                 action = SCST_LUN_ACTION_REPLACE;
1173         } else {
1174                 PRINT_ERROR("Unknown action \"%s\"", p);
1175                 res = -EINVAL;
1176                 goto out_free;
1177         }
1178
1179         if (!isspace(*p)) {
1180                 PRINT_ERROR("%s", "Syntax error");
1181                 res = -EINVAL;
1182                 goto out_free;
1183         }
1184
1185         res = scst_suspend_activity(true);
1186         if (res != 0)
1187                 goto out_free;
1188
1189         if (mutex_lock_interruptible(&scst_mutex) != 0) {
1190                 res = -EINTR;
1191                 goto out_free_resume;
1192         }
1193
1194         while (isspace(*p) && *p != '\0')
1195                 p++;
1196         e = p; /* save p */
1197         host = simple_strtoul(p, &p, 0);
1198         if (*p == ':') {
1199                 channel = simple_strtoul(p + 1, &p, 0);
1200                 id = simple_strtoul(p + 1, &p, 0);
1201                 lun = simple_strtoul(p + 1, &p, 0);
1202                 e = p;
1203         } else {
1204                 virt++;
1205                 p = e; /* restore p */
1206                 while (!isspace(*e) && *e != '\0')
1207                         e++;
1208                 *e = '\0';
1209         }
1210
1211         list_for_each_entry(d, &scst_dev_list, dev_list_entry) {
1212                 if (virt) {
1213                         if (d->virt_id && !strcmp(d->virt_name, p)) {
1214                                 dev = d;
1215                                 TRACE_DBG("Virt device %p (%s) found",
1216                                           dev, p);
1217                                 break;
1218                         }
1219                 } else {
1220                         if (d->scsi_dev &&
1221                             d->scsi_dev->host->host_no == host &&
1222                             d->scsi_dev->channel == channel &&
1223                             d->scsi_dev->id == id &&
1224                             d->scsi_dev->lun == lun) {
1225                                 dev = d;
1226                                 TRACE_DBG("Dev %p (%d:%d:%d:%d) found",
1227                                           dev, host, channel, id, lun);
1228                                 break;
1229                         }
1230                 }
1231         }
1232         if (dev == NULL) {
1233                 if (virt) {
1234                         PRINT_ERROR("Virt device %s not found", p);
1235                 } else {
1236                         PRINT_ERROR("Device %d:%d:%d:%d not found",
1237                                     host, channel, id, lun);
1238                 }
1239                 res = -EINVAL;
1240                 goto out_free_up;
1241         }
1242
1243         switch (action) {
1244         case SCST_LUN_ACTION_ADD:
1245         case SCST_LUN_ACTION_REPLACE:
1246         {
1247                 bool dev_replaced = false;
1248
1249                 e++;
1250                 while (isspace(*e) && *e != '\0')
1251                         e++;
1252                 virt_lun = simple_strtoul(e, &e, 0);
1253
1254                 while (isspace(*e) && *e != '\0')
1255                         e++;
1256
1257                 if (*e != '\0') {
1258                         if ((strncasecmp("READ_ONLY", e, 9) == 0) &&
1259                             (isspace(e[9]) || (e[9] == '\0')))
1260                                 read_only = 1;
1261                         else {
1262                                 PRINT_ERROR("Unknown option \"%s\"", e);
1263                                 res = -EINVAL;
1264                                 goto out_free_up;
1265                         }
1266                 }
1267
1268                 acg_dev = NULL;
1269                 list_for_each_entry(acg_dev_tmp, &acg->acg_dev_list,
1270                                     acg_dev_list_entry) {
1271                         if (acg_dev_tmp->lun == virt_lun) {
1272                                 acg_dev = acg_dev_tmp;
1273                                 break;
1274                         }
1275                 }
1276
1277                 if (acg_dev != NULL) {
1278                         if (action == SCST_LUN_ACTION_ADD) {
1279                                 PRINT_ERROR("virt lun %d already exists in "
1280                                         "group %s", virt_lun, acg->acg_name);
1281                                 res = -EEXIST;
1282                                 goto out_free_up;
1283                         } else {
1284                                 /* Replace */
1285                                 res = scst_acg_remove_dev(acg, acg_dev->dev,
1286                                                 false);
1287                                 if (res != 0)
1288                                         goto out_free_up;
1289
1290                                 dev_replaced = true;
1291                         }
1292                 }
1293
1294                 res = scst_acg_add_dev(acg, dev, virt_lun, read_only,
1295                                         !dev_replaced);
1296                 if (res != 0)
1297                         goto out_free_up;
1298
1299                 res = scst_create_acg_dev_sysfs(acg, virt_lun, kobj);
1300                 if (res != 0) {
1301                         PRINT_ERROR("%s", "Creation of acg_dev kobject failed");
1302                         goto out_remove_acg_dev;
1303                 }
1304
1305                 if (dev_replaced) {
1306                         struct scst_tgt_dev *tgt_dev;
1307
1308                         list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
1309                                         dev_tgt_dev_list_entry) {
1310                                 if ((tgt_dev->acg_dev->acg == acg) &&
1311                                     (tgt_dev->lun == virt_lun)) {
1312                                         TRACE_MGMT_DBG("INQUIRY DATA HAS CHANGED"
1313                                                 " on tgt_dev %p", tgt_dev);
1314                                         scst_gen_aen_or_ua(tgt_dev,
1315                                                 SCST_LOAD_SENSE(scst_sense_inquery_data_changed));
1316                                 }
1317                         }
1318                 }
1319
1320                 break;
1321         }
1322         case SCST_LUN_ACTION_DEL:
1323                 res = scst_acg_remove_dev(acg, dev, true);
1324                 if (res != 0)
1325                         goto out_free_up;
1326                 break;
1327         }
1328
1329         res = count;
1330
1331 out_free_up:
1332         mutex_unlock(&scst_mutex);
1333
1334 out_free_resume:
1335         scst_resume_activity();
1336
1337 out_free:
1338         kfree(buffer);
1339
1340 out:
1341         TRACE_EXIT_RES(res);
1342         return res;
1343
1344 out_remove_acg_dev:
1345         scst_acg_remove_dev(acg, dev, true);
1346         goto out_free_up;
1347
1348 #undef SCST_LUN_ACTION_ADD
1349 #undef SCST_LUN_ACTION_DEL
1350 #undef SCST_LUN_ACTION_REPLACE
1351 }
1352
1353 /*
1354  * SGV directory implementation
1355  */
1356
1357 static struct kobj_attribute sgv_stat_attr =
1358         __ATTR(stats, S_IRUGO | S_IWUSR, sgv_sysfs_stat_show,
1359                 sgv_sysfs_stat_reset);
1360
1361 static struct attribute *sgv_attrs[] = {
1362         &sgv_stat_attr.attr,
1363         NULL,
1364 };
1365
1366 static void sgv_kobj_release(struct kobject *kobj)
1367 {
1368         struct sgv_pool *pool;
1369
1370         TRACE_ENTRY();
1371
1372         pool = container_of(kobj, struct sgv_pool, sgv_kobj);
1373
1374         sgv_pool_destroy(pool);
1375
1376         TRACE_EXIT();
1377         return;
1378 }
1379
1380 static struct kobj_type sgv_pool_ktype = {
1381         .sysfs_ops = &scst_sysfs_ops,
1382         .release = sgv_kobj_release,
1383         .default_attrs = sgv_attrs,
1384 };
1385
1386 int scst_create_sgv_sysfs(struct sgv_pool *pool)
1387 {
1388         int retval;
1389
1390         TRACE_ENTRY();
1391
1392         pool->sgv_kobj_initialized = 1;
1393
1394         retval = kobject_init_and_add(&pool->sgv_kobj, &sgv_pool_ktype,
1395                         scst_sgv_kobj, pool->name);
1396         if (retval != 0) {
1397                 PRINT_ERROR("Can't add sgv pool %s to sysfs", pool->name);
1398                 goto out;
1399         }
1400
1401 out:
1402         TRACE_EXIT_RES(retval);
1403         return retval;
1404 }
1405
1406 /* pool can be dead upon exit from this function! */
1407 void scst_sgv_sysfs_put(struct sgv_pool *pool)
1408 {
1409         if (pool->sgv_kobj_initialized) {
1410                 kobject_del(&pool->sgv_kobj);
1411                 kobject_put(&pool->sgv_kobj);
1412         } else
1413                 sgv_pool_destroy(pool);
1414         return;
1415 }
1416
1417 static struct kobj_attribute sgv_global_stat_attr =
1418         __ATTR(global_stats, S_IRUGO | S_IWUSR, sgv_sysfs_global_stat_show,
1419                 sgv_sysfs_global_stat_reset);
1420
1421 static struct attribute *sgv_default_attrs[] = {
1422         &sgv_global_stat_attr.attr,
1423         NULL,
1424 };
1425
1426 static struct kobj_type sgv_ktype = {
1427         .sysfs_ops = &scst_sysfs_ops,
1428         .release = scst_sysfs_release,
1429         .default_attrs = sgv_default_attrs,
1430 };
1431
1432 /*
1433  * SCST sysfs root directory implementation
1434  */
1435
1436 static ssize_t scst_threads_show(struct kobject *kobj,
1437         struct kobj_attribute *attr, char *buf)
1438 {
1439         int count;
1440
1441         TRACE_ENTRY();
1442
1443         count = sprintf(buf, "%d\n", scst_global_threads_count());
1444
1445         TRACE_EXIT();
1446         return count;
1447 }
1448
1449 static ssize_t scst_threads_store(struct kobject *kobj,
1450         struct kobj_attribute *attr, const char *buf, size_t count)
1451 {
1452         int res = count;
1453         int oldtn, newtn, delta;
1454
1455         TRACE_ENTRY();
1456
1457         if (mutex_lock_interruptible(&scst_sysfs_mutex) != 0) {
1458                 res = -EINTR;
1459                 goto out;
1460         }
1461
1462         mutex_lock(&scst_global_threads_mutex);
1463
1464         oldtn = scst_nr_global_threads;
1465         sscanf(buf, "%du", &newtn);
1466
1467         if (newtn <= 0) {
1468                 PRINT_ERROR("Illegal threads num value %d", newtn);
1469                 res = -EINVAL;
1470                 goto out_up_thr_free;
1471         }
1472         delta = newtn - oldtn;
1473         if (delta < 0)
1474                 __scst_del_global_threads(-delta);
1475         else
1476                 __scst_add_global_threads(delta);
1477
1478         PRINT_INFO("Changed cmd threads num: old %d, new %d", oldtn, newtn);
1479
1480 out_up_thr_free:
1481         mutex_unlock(&scst_global_threads_mutex);
1482
1483         mutex_unlock(&scst_sysfs_mutex);
1484
1485 out:
1486         TRACE_EXIT_RES(res);
1487         return res;
1488 }
1489
1490 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
1491
1492 static void scst_read_trace_tlb(const struct scst_trace_log *tbl, char *buf,
1493         unsigned long log_level, int *pos)
1494 {
1495         const struct scst_trace_log *t = tbl;
1496
1497         if (t == NULL)
1498                 goto out;
1499
1500         while (t->token) {
1501                 if (log_level & t->val) {
1502                         *pos += sprintf(&buf[*pos], "%s%s",
1503                                         (*pos == 0) ? "" : " | ",
1504                                         t->token);
1505                 }
1506                 t++;
1507         }
1508 out:
1509         return;
1510 }
1511
1512 static ssize_t scst_trace_level_show(const struct scst_trace_log *local_tbl,
1513         unsigned long log_level, char *buf, const char *help)
1514 {
1515         int pos = 0;
1516
1517         scst_read_trace_tlb(scst_trace_tbl, buf, log_level, &pos);
1518         scst_read_trace_tlb(local_tbl, buf, log_level, &pos);
1519
1520         pos += sprintf(&buf[pos], "\n\n\nUsage:\n"
1521                 "       echo \"all|none|default\" >trace_level\n"
1522                 "       echo \"value DEC|0xHEX|0OCT\" >trace_level\n"
1523                 "       echo \"add|del TOKEN\" >trace_level\n"
1524                 "\nwhere TOKEN is one of [debug, function, line, pid,\n"
1525 #ifndef GENERATING_UPSTREAM_PATCH
1526                 "                      entryexit, buff, mem, sg, out_of_mem,\n"
1527 #else
1528                 "                      buff, mem, sg, out_of_mem,\n"
1529 #endif
1530                 "                      special, scsi, mgmt, minor,\n"
1531                 "                      mgmt_minor, mgmt_dbg, scsi_serializing,\n"
1532                 "                      retry, recv_bot, send_bot, recv_top,\n"
1533                 "                      send_top%s]", help != NULL ? help : "");
1534
1535         return pos;
1536 }
1537
1538 static ssize_t scst_main_trace_level_show(struct kobject *kobj,
1539         struct kobj_attribute *attr, char *buf)
1540 {
1541         return scst_trace_level_show(scst_local_trace_tbl, trace_flag,
1542                         buf, NULL);
1543 }
1544
1545 static int scst_write_trace(const char *buf, size_t length,
1546         unsigned long *log_level, unsigned long default_level,
1547         const char *name, const struct scst_trace_log *tbl)
1548 {
1549         int res = length;
1550         int action;
1551         unsigned long level = 0, oldlevel;
1552         char *buffer, *p, *e;
1553         const struct scst_trace_log *t;
1554
1555 #define SCST_TRACE_ACTION_ALL           1
1556 #define SCST_TRACE_ACTION_NONE          2
1557 #define SCST_TRACE_ACTION_DEFAULT       3
1558 #define SCST_TRACE_ACTION_ADD           4
1559 #define SCST_TRACE_ACTION_DEL           5
1560 #define SCST_TRACE_ACTION_VALUE         6
1561
1562         TRACE_ENTRY();
1563
1564         if ((buf == NULL) || (length == 0)) {
1565                 res = -EINVAL;
1566                 goto out;
1567         }
1568
1569         buffer = kmalloc(length+1, GFP_KERNEL);
1570         if (buffer == NULL) {
1571                 PRINT_ERROR("Unable to alloc intermediate buffer (size %zd)",
1572                         length+1);
1573                 res = -ENOMEM;
1574                 goto out;
1575         }
1576         memcpy(buffer, buf, length);
1577         buffer[length] = '\0';
1578
1579         p = buffer;
1580         if (!strncasecmp("all", p, 3)) {
1581                 action = SCST_TRACE_ACTION_ALL;
1582         } else if (!strncasecmp("none", p, 4) || !strncasecmp("null", p, 4)) {
1583                 action = SCST_TRACE_ACTION_NONE;
1584         } else if (!strncasecmp("default", p, 7)) {
1585                 action = SCST_TRACE_ACTION_DEFAULT;
1586         } else if (!strncasecmp("add", p, 3)) {
1587                 p += 3;
1588                 action = SCST_TRACE_ACTION_ADD;
1589         } else if (!strncasecmp("del", p, 3)) {
1590                 p += 3;
1591                 action = SCST_TRACE_ACTION_DEL;
1592         } else if (!strncasecmp("value", p, 5)) {
1593                 p += 5;
1594                 action = SCST_TRACE_ACTION_VALUE;
1595         } else {
1596                 if (p[strlen(p) - 1] == '\n')
1597                         p[strlen(p) - 1] = '\0';
1598                 PRINT_ERROR("Unknown action \"%s\"", p);
1599                 res = -EINVAL;
1600                 goto out_free;
1601         }
1602
1603         switch (action) {
1604         case SCST_TRACE_ACTION_ADD:
1605         case SCST_TRACE_ACTION_DEL:
1606         case SCST_TRACE_ACTION_VALUE:
1607                 if (!isspace(*p)) {
1608                         PRINT_ERROR("%s", "Syntax error");
1609                         res = -EINVAL;
1610                         goto out_free;
1611                 }
1612         }
1613
1614         switch (action) {
1615         case SCST_TRACE_ACTION_ALL:
1616                 level = TRACE_ALL;
1617                 break;
1618         case SCST_TRACE_ACTION_DEFAULT:
1619                 level = default_level;
1620                 break;
1621         case SCST_TRACE_ACTION_NONE:
1622                 level = TRACE_NULL;
1623                 break;
1624         case SCST_TRACE_ACTION_ADD:
1625         case SCST_TRACE_ACTION_DEL:
1626                 while (isspace(*p) && *p != '\0')
1627                         p++;
1628                 e = p;
1629                 while (!isspace(*e) && *e != '\0')
1630                         e++;
1631                 *e = 0;
1632                 if (tbl) {
1633                         t = tbl;
1634                         while (t->token) {
1635                                 if (!strcasecmp(p, t->token)) {
1636                                         level = t->val;
1637                                         break;
1638                                 }
1639                                 t++;
1640                         }
1641                 }
1642                 if (level == 0) {
1643                         t = scst_trace_tbl;
1644                         while (t->token) {
1645                                 if (!strcasecmp(p, t->token)) {
1646                                         level = t->val;
1647                                         break;
1648                                 }
1649                                 t++;
1650                         }
1651                 }
1652                 if (level == 0) {
1653                         PRINT_ERROR("Unknown token \"%s\"", p);
1654                         res = -EINVAL;
1655                         goto out_free;
1656                 }
1657                 break;
1658         case SCST_TRACE_ACTION_VALUE:
1659                 while (isspace(*p) && *p != '\0')
1660                         p++;
1661                 res = strict_strtoul(p, 0, &level);
1662                 if (res != 0) {
1663                         PRINT_ERROR("Invalud trace value \"%s\"", p);
1664                         res = -EINVAL;
1665                         goto out_free;
1666                 }
1667                 break;
1668         }
1669
1670         oldlevel = *log_level;
1671
1672         switch (action) {
1673         case SCST_TRACE_ACTION_ADD:
1674                 *log_level |= level;
1675                 break;
1676         case SCST_TRACE_ACTION_DEL:
1677                 *log_level &= ~level;
1678                 break;
1679         default:
1680                 *log_level = level;
1681                 break;
1682         }
1683
1684         PRINT_INFO("Changed trace level for \"%s\": old 0x%08lx, new 0x%08lx",
1685                 name, oldlevel, *log_level);
1686
1687 out_free:
1688         kfree(buffer);
1689 out:
1690         TRACE_EXIT_RES(res);
1691         return res;
1692
1693 #undef SCST_TRACE_ACTION_ALL
1694 #undef SCST_TRACE_ACTION_NONE
1695 #undef SCST_TRACE_ACTION_DEFAULT
1696 #undef SCST_TRACE_ACTION_ADD
1697 #undef SCST_TRACE_ACTION_DEL
1698 #undef SCST_TRACE_ACTION_VALUE
1699 }
1700
1701 static ssize_t scst_main_trace_level_store(struct kobject *kobj,
1702         struct kobj_attribute *attr, const char *buf, size_t count)
1703 {
1704         int res;
1705
1706         TRACE_ENTRY();
1707
1708         if (mutex_lock_interruptible(&scst_log_mutex) != 0) {
1709                 res = -EINTR;
1710                 goto out;
1711         }
1712
1713         res = scst_write_trace(buf, count, &trace_flag,
1714                 SCST_DEFAULT_LOG_FLAGS, "scst", scst_local_trace_tbl);
1715
1716         mutex_unlock(&scst_log_mutex);
1717
1718 out:
1719         TRACE_EXIT_RES(res);
1720         return res;
1721 }
1722
1723 #endif /* defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) */
1724
1725 static ssize_t scst_version_show(struct kobject *kobj,
1726                                  struct kobj_attribute *attr,
1727                                  char *buf)
1728 {
1729         TRACE_ENTRY();
1730
1731         sprintf(buf, "%s\n", SCST_VERSION_STRING);
1732
1733 #ifdef CONFIG_SCST_STRICT_SERIALIZING
1734         strcat(buf, "Strict serializing enabled\n");
1735 #endif
1736
1737 #ifdef CONFIG_SCST_EXTRACHECKS
1738         strcat(buf, "EXTRACHECKS\n");
1739 #endif
1740
1741 #ifdef CONFIG_SCST_TRACING
1742         strcat(buf, "TRACING\n");
1743 #endif
1744
1745 #ifdef CONFIG_SCST_DEBUG
1746         strcat(buf, "DEBUG\n");
1747 #endif
1748
1749 #ifdef CONFIG_SCST_DEBUG_TM
1750         strcat(buf, "DEBUG_TM\n");
1751 #endif
1752
1753 #ifdef CONFIG_SCST_DEBUG_RETRY
1754         strcat(buf, "DEBUG_RETRY\n");
1755 #endif
1756
1757 #ifdef CONFIG_SCST_DEBUG_OOM
1758         strcat(buf, "DEBUG_OOM\n");
1759 #endif
1760
1761 #ifdef CONFIG_SCST_DEBUG_SN
1762         strcat(buf, "DEBUG_SN\n");
1763 #endif
1764
1765 #ifdef CONFIG_SCST_USE_EXPECTED_VALUES
1766         strcat(buf, "USE_EXPECTED_VALUES\n");
1767 #endif
1768
1769 #ifdef CONFIG_SCST_ALLOW_PASSTHROUGH_IO_SUBMIT_IN_SIRQ
1770         strcat(buf, "ALLOW_PASSTHROUGH_IO_SUBMIT_IN_SIRQ\n");
1771 #endif
1772
1773 #ifdef CONFIG_SCST_STRICT_SECURITY
1774         strcat(buf, "SCST_STRICT_SECURITY\n");
1775 #endif
1776
1777         TRACE_EXIT();
1778         return strlen(buf);
1779 }
1780
1781 static struct kobj_attribute scst_threads_attr =
1782         __ATTR(threads, S_IRUGO | S_IWUSR, scst_threads_show,
1783                scst_threads_store);
1784
1785 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
1786 static struct kobj_attribute scst_trace_level_attr =
1787         __ATTR(trace_level, S_IRUGO | S_IWUSR, scst_main_trace_level_show,
1788                scst_main_trace_level_store);
1789 #endif
1790
1791 static struct kobj_attribute scst_version_attr =
1792         __ATTR(version, S_IRUGO, scst_version_show, NULL);
1793
1794 static struct attribute *scst_sysfs_root_default_attrs[] = {
1795         &scst_threads_attr.attr,
1796 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
1797         &scst_trace_level_attr.attr,
1798 #endif
1799         &scst_version_attr.attr,
1800         NULL,
1801 };
1802
1803 static void scst_sysfs_root_release(struct kobject *kobj)
1804 {
1805         complete_all(&scst_sysfs_root_release_completion);
1806 }
1807
1808 static ssize_t scst_show(struct kobject *kobj, struct attribute *attr,
1809                          char *buf)
1810 {
1811         struct kobj_attribute *kobj_attr;
1812         kobj_attr = container_of(attr, struct kobj_attribute, attr);
1813
1814         return kobj_attr->show(kobj, kobj_attr, buf);
1815 }
1816
1817 static ssize_t scst_store(struct kobject *kobj, struct attribute *attr,
1818                           const char *buf, size_t count)
1819 {
1820         struct kobj_attribute *kobj_attr;
1821         kobj_attr = container_of(attr, struct kobj_attribute, attr);
1822
1823         return kobj_attr->store(kobj, kobj_attr, buf, count);
1824 }
1825
1826 struct sysfs_ops scst_sysfs_ops = {
1827         .show = scst_show,
1828         .store = scst_store,
1829 };
1830
1831 static struct kobj_type scst_sysfs_root_ktype = {
1832         .sysfs_ops = &scst_sysfs_ops,
1833         .release = scst_sysfs_root_release,
1834         .default_attrs = scst_sysfs_root_default_attrs,
1835 };
1836
1837 static void scst_devt_free(struct kobject *kobj)
1838 {
1839         struct scst_dev_type *devt;
1840
1841         TRACE_ENTRY();
1842
1843         devt = container_of(kobj, struct scst_dev_type, devt_kobj);
1844
1845         complete_all(&devt->devt_kobj_release_compl);
1846
1847         scst_devt_cleanup(devt);
1848
1849         TRACE_EXIT();
1850         return;
1851 }
1852
1853 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
1854
1855 static ssize_t scst_devt_trace_level_show(struct kobject *kobj,
1856         struct kobj_attribute *attr, char *buf)
1857 {
1858         struct scst_dev_type *devt;
1859
1860         devt = container_of(kobj, struct scst_dev_type, devt_kobj);
1861
1862         return scst_trace_level_show(devt->trace_tbl,
1863                 devt->trace_flags ? *devt->trace_flags : 0, buf,
1864                 devt->trace_tbl_help);
1865 }
1866
1867 static ssize_t scst_devt_trace_level_store(struct kobject *kobj,
1868         struct kobj_attribute *attr, const char *buf, size_t count)
1869 {
1870         int res;
1871         struct scst_dev_type *devt;
1872
1873         TRACE_ENTRY();
1874
1875         devt = container_of(kobj, struct scst_dev_type, devt_kobj);
1876
1877         if (mutex_lock_interruptible(&scst_log_mutex) != 0) {
1878                 res = -EINTR;
1879                 goto out;
1880         }
1881
1882         res = scst_write_trace(buf, count, devt->trace_flags,
1883                 devt->default_trace_flags, devt->name, devt->trace_tbl);
1884
1885         mutex_unlock(&scst_log_mutex);
1886
1887 out:
1888         TRACE_EXIT_RES(res);
1889         return res;
1890 }
1891
1892 static struct kobj_attribute devt_trace_attr =
1893         __ATTR(trace_level, S_IRUGO | S_IWUSR,
1894                scst_devt_trace_level_show, scst_devt_trace_level_store);
1895
1896 #endif /* #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) */
1897
1898 static ssize_t scst_devt_type_show(struct kobject *kobj,
1899         struct kobj_attribute *attr, char *buf)
1900 {
1901         int pos;
1902         struct scst_dev_type *devt;
1903
1904         devt = container_of(kobj, struct scst_dev_type, devt_kobj);
1905
1906         pos = sprintf(buf, "%d - %s\n", devt->type,
1907                 (unsigned)devt->type > ARRAY_SIZE(scst_dev_handler_types) ?
1908                         "unknown" : scst_dev_handler_types[devt->type]);
1909
1910         return pos;
1911 }
1912
1913 static struct kobj_attribute scst_devt_type_attr =
1914         __ATTR(type, S_IRUGO, scst_devt_type_show, NULL);
1915
1916 static struct attribute *scst_devt_default_attrs[] = {
1917         &scst_devt_type_attr.attr,
1918         NULL,
1919 };
1920
1921 static struct kobj_type scst_devt_ktype = {
1922         .sysfs_ops = &scst_sysfs_ops,
1923         .release = scst_devt_free,
1924         .default_attrs = scst_devt_default_attrs,
1925 };
1926
1927 int scst_create_devt_sysfs(struct scst_dev_type *devt)
1928 {
1929         int retval;
1930         struct kobject *parent;
1931         const struct attribute **pattr;
1932
1933         TRACE_ENTRY();
1934
1935         init_completion(&devt->devt_kobj_release_compl);
1936
1937         if (devt->parent != NULL)
1938                 parent = &devt->parent->devt_kobj;
1939         else
1940                 parent = scst_handlers_kobj;
1941
1942         devt->devt_kobj_initialized = 1;
1943
1944         retval = kobject_init_and_add(&devt->devt_kobj, &scst_devt_ktype,
1945                         parent, devt->name);
1946         if (retval != 0) {
1947                 PRINT_ERROR("Can't add devt %s to sysfs", devt->name);
1948                 goto out;
1949         }
1950
1951         /*
1952          * In case of errors there's no need for additional cleanup, because
1953          * it will be done by the _put function() called by the caller.
1954          */
1955
1956         pattr = devt->devt_attrs;
1957         if (pattr != NULL) {
1958                 while (*pattr != NULL) {
1959                         retval = sysfs_create_file(&devt->devt_kobj, *pattr);
1960                         if (retval != 0) {
1961                                 PRINT_ERROR("Can't add devt attr %s for dev "
1962                                         "handler %s", (*pattr)->name,
1963                                         devt->name);
1964                                 goto out;
1965                         }
1966                         pattr++;
1967                 }
1968         }
1969
1970 #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
1971         if (devt->trace_flags != NULL) {
1972                 retval = sysfs_create_file(&devt->devt_kobj,
1973                                 &devt_trace_attr.attr);
1974                 if (retval != 0) {
1975                         PRINT_ERROR("Can't add devt trace_flag for dev "
1976                                 "handler %s", devt->name);
1977                         goto out;
1978                 }
1979         }
1980 #endif
1981
1982 out:
1983         TRACE_EXIT_RES(retval);
1984         return retval;
1985 }
1986
1987 void scst_devt_sysfs_put(struct scst_dev_type *devt)
1988 {
1989         TRACE_ENTRY();
1990
1991         if (devt->devt_kobj_initialized) {
1992                 int rc;
1993
1994                 kobject_del(&devt->devt_kobj);
1995                 kobject_put(&devt->devt_kobj);
1996
1997                 rc = wait_for_completion_timeout(&devt->devt_kobj_release_compl, HZ);
1998                 if (rc == 0) {
1999                         PRINT_INFO("Waiting for releasing sysfs entry "
2000                                 "for dev handler template %s...", devt->name);
2001                         wait_for_completion(&devt->devt_kobj_release_compl);
2002                         PRINT_INFO("Done waiting for releasing sysfs entry "
2003                                 "for dev handler template %s", devt->name);
2004                 }
2005         } else
2006                 scst_devt_cleanup(devt);
2007
2008         TRACE_EXIT();
2009         return;
2010 }
2011
2012 int __init scst_sysfs_init(void)
2013 {
2014         int retval = 0;
2015
2016         TRACE_ENTRY();
2017
2018         retval = kobject_init_and_add(&scst_sysfs_root_kobj,
2019                         &scst_sysfs_root_ktype, kernel_kobj, "%s", "scst_tgt");
2020         if (retval != 0)
2021                 goto sysfs_root_add_error;
2022
2023         scst_targets_kobj = kobject_create_and_add("targets",
2024                                 &scst_sysfs_root_kobj);
2025         if (scst_targets_kobj == NULL)
2026                 goto targets_kobj_error;
2027
2028         scst_devices_kobj = kobject_create_and_add("devices",
2029                                 &scst_sysfs_root_kobj);
2030         if (scst_devices_kobj == NULL)
2031                 goto devices_kobj_error;
2032
2033         scst_sgv_kobj = kzalloc(sizeof(*scst_sgv_kobj), GFP_KERNEL);
2034         if (scst_sgv_kobj == NULL)
2035                 goto sgv_kobj_error;
2036
2037         retval = kobject_init_and_add(scst_sgv_kobj, &sgv_ktype,
2038                         &scst_sysfs_root_kobj, "%s", "sgv");
2039         if (retval != 0)
2040                 goto sgv_kobj_add_error;
2041
2042         scst_handlers_kobj = kobject_create_and_add("handlers",
2043                                         &scst_sysfs_root_kobj);
2044         if (scst_handlers_kobj == NULL)
2045                 goto handlers_kobj_error;
2046
2047 out:
2048         TRACE_EXIT_RES(retval);
2049         return retval;
2050
2051 handlers_kobj_error:
2052         kobject_del(scst_sgv_kobj);
2053
2054 sgv_kobj_add_error:
2055         kobject_put(scst_sgv_kobj);
2056
2057 sgv_kobj_error:
2058         kobject_del(scst_devices_kobj);
2059         kobject_put(scst_devices_kobj);
2060
2061 devices_kobj_error:
2062         kobject_del(scst_targets_kobj);
2063         kobject_put(scst_targets_kobj);
2064
2065 targets_kobj_error:
2066         kobject_del(&scst_sysfs_root_kobj);
2067
2068 sysfs_root_add_error:
2069         kobject_put(&scst_sysfs_root_kobj);
2070
2071         if (retval == 0)
2072                 retval = -EINVAL;
2073         goto out;
2074 }
2075
2076 void scst_sysfs_cleanup(void)
2077 {
2078         TRACE_ENTRY();
2079
2080         PRINT_INFO("%s", "Exiting SCST sysfs hierarchy...");
2081
2082         kobject_del(scst_sgv_kobj);
2083         kobject_put(scst_sgv_kobj);
2084
2085         kobject_del(scst_devices_kobj);
2086         kobject_put(scst_devices_kobj);
2087
2088         kobject_del(scst_targets_kobj);
2089         kobject_put(scst_targets_kobj);
2090
2091         kobject_del(scst_handlers_kobj);
2092         kobject_put(scst_handlers_kobj);
2093
2094         kobject_del(&scst_sysfs_root_kobj);
2095         kobject_put(&scst_sysfs_root_kobj);
2096
2097         wait_for_completion(&scst_sysfs_root_release_completion);
2098         /*
2099          * There is a race, when in the release() schedule happens just after
2100          * calling complete(), so if we exit and unload scst module immediately,
2101          * there will be oops there. So let's give it a chance to quit
2102          * gracefully. Unfortunately, current kobjects implementation
2103          * doesn't allow better ways to handle it.
2104          */
2105         msleep(3000);
2106
2107         PRINT_INFO("%s", "Exiting SCST sysfs hierarchy done");
2108
2109         TRACE_EXIT();
2110         return;
2111 }