Merge branch 'akpm' (patches from Andrew)
[cascardo/linux.git] / fs / orangefs / orangefs-sysfs.c
1 /*
2  * Documentation/ABI/stable/orangefs-sysfs:
3  *
4  * What:                /sys/fs/orangefs/perf_counter_reset
5  * Date:                June 2015
6  * Contact:             Mike Marshall <hubcap@omnibond.com>
7  * Description:
8  *                      echo a 0 or a 1 into perf_counter_reset to
9  *                      reset all the counters in
10  *                      /sys/fs/orangefs/perf_counters
11  *                      except ones with PINT_PERF_PRESERVE set.
12  *
13  *
14  * What:                /sys/fs/orangefs/perf_counters/...
15  * Date:                Jun 2015
16  * Contact:             Mike Marshall <hubcap@omnibond.com>
17  * Description:
18  *                      Counters and settings for various caches.
19  *                      Read only.
20  *
21  *
22  * What:                /sys/fs/orangefs/perf_time_interval_secs
23  * Date:                Jun 2015
24  * Contact:             Mike Marshall <hubcap@omnibond.com>
25  * Description:
26  *                      Length of perf counter intervals in
27  *                      seconds.
28  *
29  *
30  * What:                /sys/fs/orangefs/perf_history_size
31  * Date:                Jun 2015
32  * Contact:             Mike Marshall <hubcap@omnibond.com>
33  * Description:
34  *                      The perf_counters cache statistics have N, or
35  *                      perf_history_size, samples. The default is
36  *                      one.
37  *
38  *                      Every perf_time_interval_secs the (first)
39  *                      samples are reset.
40  *
41  *                      If N is greater than one, the "current" set
42  *                      of samples is reset, and the samples from the
43  *                      other N-1 intervals remain available.
44  *
45  *
46  * What:                /sys/fs/orangefs/op_timeout_secs
47  * Date:                Jun 2015
48  * Contact:             Mike Marshall <hubcap@omnibond.com>
49  * Description:
50  *                      Service operation timeout in seconds.
51  *
52  *
53  * What:                /sys/fs/orangefs/slot_timeout_secs
54  * Date:                Jun 2015
55  * Contact:             Mike Marshall <hubcap@omnibond.com>
56  * Description:
57  *                      "Slot" timeout in seconds. A "slot"
58  *                      is an indexed buffer in the shared
59  *                      memory segment used for communication
60  *                      between the kernel module and userspace.
61  *                      Slots are requested and waited for,
62  *                      the wait times out after slot_timeout_secs.
63  *
64  * What:                /sys/fs/orangefs/dcache_timeout_msecs
65  * Date:                Jul 2016
66  * Contact:             Martin Brandenburg <martin@omnibond.com>
67  * Description:
68  *                      Time lookup is valid in milliseconds.
69  *
70  * What:                /sys/fs/orangefs/getattr_timeout_msecs
71  * Date:                Jul 2016
72  * Contact:             Martin Brandenburg <martin@omnibond.com>
73  * Description:
74  *                      Time getattr is valid in milliseconds.
75  *
76  * What:                /sys/fs/orangefs/acache/...
77  * Date:                Jun 2015
78  * Contact:             Martin Brandenburg <martin@omnibond.com>
79  * Description:
80  *                      Attribute cache configurable settings.
81  *
82  *
83  * What:                /sys/fs/orangefs/ncache/...
84  * Date:                Jun 2015
85  * Contact:             Mike Marshall <hubcap@omnibond.com>
86  * Description:
87  *                      Name cache configurable settings.
88  *
89  *
90  * What:                /sys/fs/orangefs/capcache/...
91  * Date:                Jun 2015
92  * Contact:             Mike Marshall <hubcap@omnibond.com>
93  * Description:
94  *                      Capability cache configurable settings.
95  *
96  *
97  * What:                /sys/fs/orangefs/ccache/...
98  * Date:                Jun 2015
99  * Contact:             Mike Marshall <hubcap@omnibond.com>
100  * Description:
101  *                      Credential cache configurable settings.
102  *
103  */
104
105 #include <linux/fs.h>
106 #include <linux/kobject.h>
107 #include <linux/string.h>
108 #include <linux/sysfs.h>
109 #include <linux/module.h>
110 #include <linux/init.h>
111
112 #include "protocol.h"
113 #include "orangefs-kernel.h"
114 #include "orangefs-sysfs.h"
115
116 #define ORANGEFS_KOBJ_ID "orangefs"
117 #define ACACHE_KOBJ_ID "acache"
118 #define CAPCACHE_KOBJ_ID "capcache"
119 #define CCACHE_KOBJ_ID "ccache"
120 #define NCACHE_KOBJ_ID "ncache"
121 #define PC_KOBJ_ID "pc"
122 #define STATS_KOBJ_ID "stats"
123
124 struct orangefs_obj {
125         struct kobject kobj;
126         int op_timeout_secs;
127         int perf_counter_reset;
128         int perf_history_size;
129         int perf_time_interval_secs;
130         int slot_timeout_secs;
131         int dcache_timeout_msecs;
132         int getattr_timeout_msecs;
133 };
134
135 struct acache_orangefs_obj {
136         struct kobject kobj;
137         int hard_limit;
138         int reclaim_percentage;
139         int soft_limit;
140         int timeout_msecs;
141 };
142
143 struct capcache_orangefs_obj {
144         struct kobject kobj;
145         int hard_limit;
146         int reclaim_percentage;
147         int soft_limit;
148         int timeout_secs;
149 };
150
151 struct ccache_orangefs_obj {
152         struct kobject kobj;
153         int hard_limit;
154         int reclaim_percentage;
155         int soft_limit;
156         int timeout_secs;
157 };
158
159 struct ncache_orangefs_obj {
160         struct kobject kobj;
161         int hard_limit;
162         int reclaim_percentage;
163         int soft_limit;
164         int timeout_msecs;
165 };
166
167 struct pc_orangefs_obj {
168         struct kobject kobj;
169         char *acache;
170         char *capcache;
171         char *ncache;
172 };
173
174 struct stats_orangefs_obj {
175         struct kobject kobj;
176         int reads;
177         int writes;
178 };
179
180 struct orangefs_attribute {
181         struct attribute attr;
182         ssize_t (*show)(struct orangefs_obj *orangefs_obj,
183                         struct orangefs_attribute *attr,
184                         char *buf);
185         ssize_t (*store)(struct orangefs_obj *orangefs_obj,
186                          struct orangefs_attribute *attr,
187                          const char *buf,
188                          size_t count);
189 };
190
191 struct acache_orangefs_attribute {
192         struct attribute attr;
193         ssize_t (*show)(struct acache_orangefs_obj *acache_orangefs_obj,
194                         struct acache_orangefs_attribute *attr,
195                         char *buf);
196         ssize_t (*store)(struct acache_orangefs_obj *acache_orangefs_obj,
197                          struct acache_orangefs_attribute *attr,
198                          const char *buf,
199                          size_t count);
200 };
201
202 struct capcache_orangefs_attribute {
203         struct attribute attr;
204         ssize_t (*show)(struct capcache_orangefs_obj *capcache_orangefs_obj,
205                         struct capcache_orangefs_attribute *attr,
206                         char *buf);
207         ssize_t (*store)(struct capcache_orangefs_obj *capcache_orangefs_obj,
208                          struct capcache_orangefs_attribute *attr,
209                          const char *buf,
210                          size_t count);
211 };
212
213 struct ccache_orangefs_attribute {
214         struct attribute attr;
215         ssize_t (*show)(struct ccache_orangefs_obj *ccache_orangefs_obj,
216                         struct ccache_orangefs_attribute *attr,
217                         char *buf);
218         ssize_t (*store)(struct ccache_orangefs_obj *ccache_orangefs_obj,
219                          struct ccache_orangefs_attribute *attr,
220                          const char *buf,
221                          size_t count);
222 };
223
224 struct ncache_orangefs_attribute {
225         struct attribute attr;
226         ssize_t (*show)(struct ncache_orangefs_obj *ncache_orangefs_obj,
227                         struct ncache_orangefs_attribute *attr,
228                         char *buf);
229         ssize_t (*store)(struct ncache_orangefs_obj *ncache_orangefs_obj,
230                          struct ncache_orangefs_attribute *attr,
231                          const char *buf,
232                          size_t count);
233 };
234
235 struct pc_orangefs_attribute {
236         struct attribute attr;
237         ssize_t (*show)(struct pc_orangefs_obj *pc_orangefs_obj,
238                         struct pc_orangefs_attribute *attr,
239                         char *buf);
240         ssize_t (*store)(struct pc_orangefs_obj *pc_orangefs_obj,
241                          struct pc_orangefs_attribute *attr,
242                          const char *buf,
243                          size_t count);
244 };
245
246 struct stats_orangefs_attribute {
247         struct attribute attr;
248         ssize_t (*show)(struct stats_orangefs_obj *stats_orangefs_obj,
249                         struct stats_orangefs_attribute *attr,
250                         char *buf);
251         ssize_t (*store)(struct stats_orangefs_obj *stats_orangefs_obj,
252                          struct stats_orangefs_attribute *attr,
253                          const char *buf,
254                          size_t count);
255 };
256
257 static ssize_t orangefs_attr_show(struct kobject *kobj,
258                                   struct attribute *attr,
259                                   char *buf)
260 {
261         struct orangefs_attribute *attribute;
262         struct orangefs_obj *orangefs_obj;
263         int rc;
264
265         attribute = container_of(attr, struct orangefs_attribute, attr);
266         orangefs_obj = container_of(kobj, struct orangefs_obj, kobj);
267
268         if (!attribute->show) {
269                 rc = -EIO;
270                 goto out;
271         }
272
273         rc = attribute->show(orangefs_obj, attribute, buf);
274
275 out:
276         return rc;
277 }
278
279 static ssize_t orangefs_attr_store(struct kobject *kobj,
280                                    struct attribute *attr,
281                                    const char *buf,
282                                    size_t len)
283 {
284         struct orangefs_attribute *attribute;
285         struct orangefs_obj *orangefs_obj;
286         int rc;
287
288         gossip_debug(GOSSIP_SYSFS_DEBUG,
289                      "orangefs_attr_store: start\n");
290
291         attribute = container_of(attr, struct orangefs_attribute, attr);
292         orangefs_obj = container_of(kobj, struct orangefs_obj, kobj);
293
294         if (!attribute->store) {
295                 rc = -EIO;
296                 goto out;
297         }
298
299         rc = attribute->store(orangefs_obj, attribute, buf, len);
300
301 out:
302         return rc;
303 }
304
305 static const struct sysfs_ops orangefs_sysfs_ops = {
306         .show = orangefs_attr_show,
307         .store = orangefs_attr_store,
308 };
309
310 static ssize_t acache_orangefs_attr_show(struct kobject *kobj,
311                                          struct attribute *attr,
312                                          char *buf)
313 {
314         struct acache_orangefs_attribute *attribute;
315         struct acache_orangefs_obj *acache_orangefs_obj;
316         int rc;
317
318         attribute = container_of(attr, struct acache_orangefs_attribute, attr);
319         acache_orangefs_obj =
320                 container_of(kobj, struct acache_orangefs_obj, kobj);
321
322         if (!attribute->show) {
323                 rc = -EIO;
324                 goto out;
325         }
326
327         rc = attribute->show(acache_orangefs_obj, attribute, buf);
328
329 out:
330         return rc;
331 }
332
333 static ssize_t acache_orangefs_attr_store(struct kobject *kobj,
334                                           struct attribute *attr,
335                                           const char *buf,
336                                           size_t len)
337 {
338         struct acache_orangefs_attribute *attribute;
339         struct acache_orangefs_obj *acache_orangefs_obj;
340         int rc;
341
342         gossip_debug(GOSSIP_SYSFS_DEBUG,
343                      "acache_orangefs_attr_store: start\n");
344
345         attribute = container_of(attr, struct acache_orangefs_attribute, attr);
346         acache_orangefs_obj =
347                 container_of(kobj, struct acache_orangefs_obj, kobj);
348
349         if (!attribute->store) {
350                 rc = -EIO;
351                 goto out;
352         }
353
354         rc = attribute->store(acache_orangefs_obj, attribute, buf, len);
355
356 out:
357         return rc;
358 }
359
360 static const struct sysfs_ops acache_orangefs_sysfs_ops = {
361         .show = acache_orangefs_attr_show,
362         .store = acache_orangefs_attr_store,
363 };
364
365 static ssize_t capcache_orangefs_attr_show(struct kobject *kobj,
366                                            struct attribute *attr,
367                                            char *buf)
368 {
369         struct capcache_orangefs_attribute *attribute;
370         struct capcache_orangefs_obj *capcache_orangefs_obj;
371         int rc;
372
373         attribute =
374                 container_of(attr, struct capcache_orangefs_attribute, attr);
375         capcache_orangefs_obj =
376                 container_of(kobj, struct capcache_orangefs_obj, kobj);
377
378         if (!attribute->show) {
379                 rc = -EIO;
380                 goto out;
381         }
382
383         rc = attribute->show(capcache_orangefs_obj, attribute, buf);
384
385 out:
386         return rc;
387 }
388
389 static ssize_t capcache_orangefs_attr_store(struct kobject *kobj,
390                                             struct attribute *attr,
391                                             const char *buf,
392                                             size_t len)
393 {
394         struct capcache_orangefs_attribute *attribute;
395         struct capcache_orangefs_obj *capcache_orangefs_obj;
396         int rc;
397
398         gossip_debug(GOSSIP_SYSFS_DEBUG,
399                      "capcache_orangefs_attr_store: start\n");
400
401         attribute =
402                 container_of(attr, struct capcache_orangefs_attribute, attr);
403         capcache_orangefs_obj =
404                 container_of(kobj, struct capcache_orangefs_obj, kobj);
405
406         if (!attribute->store) {
407                 rc = -EIO;
408                 goto out;
409         }
410
411         rc = attribute->store(capcache_orangefs_obj, attribute, buf, len);
412
413 out:
414         return rc;
415 }
416
417 static const struct sysfs_ops capcache_orangefs_sysfs_ops = {
418         .show = capcache_orangefs_attr_show,
419         .store = capcache_orangefs_attr_store,
420 };
421
422 static ssize_t ccache_orangefs_attr_show(struct kobject *kobj,
423                                          struct attribute *attr,
424                                          char *buf)
425 {
426         struct ccache_orangefs_attribute *attribute;
427         struct ccache_orangefs_obj *ccache_orangefs_obj;
428         int rc;
429
430         attribute =
431                 container_of(attr, struct ccache_orangefs_attribute, attr);
432         ccache_orangefs_obj =
433                 container_of(kobj, struct ccache_orangefs_obj, kobj);
434
435         if (!attribute->show) {
436                 rc = -EIO;
437                 goto out;
438         }
439
440         rc = attribute->show(ccache_orangefs_obj, attribute, buf);
441
442 out:
443         return rc;
444 }
445
446 static ssize_t ccache_orangefs_attr_store(struct kobject *kobj,
447                                           struct attribute *attr,
448                                           const char *buf,
449                                           size_t len)
450 {
451         struct ccache_orangefs_attribute *attribute;
452         struct ccache_orangefs_obj *ccache_orangefs_obj;
453         int rc;
454
455         gossip_debug(GOSSIP_SYSFS_DEBUG,
456                      "ccache_orangefs_attr_store: start\n");
457
458         attribute =
459                 container_of(attr, struct ccache_orangefs_attribute, attr);
460         ccache_orangefs_obj =
461                 container_of(kobj, struct ccache_orangefs_obj, kobj);
462
463         if (!attribute->store) {
464                 rc = -EIO;
465                 goto out;
466         }
467
468         rc = attribute->store(ccache_orangefs_obj, attribute, buf, len);
469
470 out:
471         return rc;
472 }
473
474 static const struct sysfs_ops ccache_orangefs_sysfs_ops = {
475         .show = ccache_orangefs_attr_show,
476         .store = ccache_orangefs_attr_store,
477 };
478
479 static ssize_t ncache_orangefs_attr_show(struct kobject *kobj,
480                                          struct attribute *attr,
481                                          char *buf)
482 {
483         struct ncache_orangefs_attribute *attribute;
484         struct ncache_orangefs_obj *ncache_orangefs_obj;
485         int rc;
486
487         attribute = container_of(attr, struct ncache_orangefs_attribute, attr);
488         ncache_orangefs_obj =
489                 container_of(kobj, struct ncache_orangefs_obj, kobj);
490
491         if (!attribute->show) {
492                 rc = -EIO;
493                 goto out;
494         }
495
496         rc = attribute->show(ncache_orangefs_obj, attribute, buf);
497
498 out:
499         return rc;
500 }
501
502 static ssize_t ncache_orangefs_attr_store(struct kobject *kobj,
503                                           struct attribute *attr,
504                                           const char *buf,
505                                           size_t len)
506 {
507         struct ncache_orangefs_attribute *attribute;
508         struct ncache_orangefs_obj *ncache_orangefs_obj;
509         int rc;
510
511         gossip_debug(GOSSIP_SYSFS_DEBUG,
512                      "ncache_orangefs_attr_store: start\n");
513
514         attribute = container_of(attr, struct ncache_orangefs_attribute, attr);
515         ncache_orangefs_obj =
516                 container_of(kobj, struct ncache_orangefs_obj, kobj);
517
518         if (!attribute->store) {
519                 rc = -EIO;
520                 goto out;
521         }
522
523         rc = attribute->store(ncache_orangefs_obj, attribute, buf, len);
524
525 out:
526         return rc;
527 }
528
529 static const struct sysfs_ops ncache_orangefs_sysfs_ops = {
530         .show = ncache_orangefs_attr_show,
531         .store = ncache_orangefs_attr_store,
532 };
533
534 static ssize_t pc_orangefs_attr_show(struct kobject *kobj,
535                                      struct attribute *attr,
536                                      char *buf)
537 {
538         struct pc_orangefs_attribute *attribute;
539         struct pc_orangefs_obj *pc_orangefs_obj;
540         int rc;
541
542         attribute = container_of(attr, struct pc_orangefs_attribute, attr);
543         pc_orangefs_obj =
544                 container_of(kobj, struct pc_orangefs_obj, kobj);
545
546         if (!attribute->show) {
547                 rc = -EIO;
548                 goto out;
549         }
550
551         rc = attribute->show(pc_orangefs_obj, attribute, buf);
552
553 out:
554         return rc;
555 }
556
557 static const struct sysfs_ops pc_orangefs_sysfs_ops = {
558         .show = pc_orangefs_attr_show,
559 };
560
561 static ssize_t stats_orangefs_attr_show(struct kobject *kobj,
562                                         struct attribute *attr,
563                                         char *buf)
564 {
565         struct stats_orangefs_attribute *attribute;
566         struct stats_orangefs_obj *stats_orangefs_obj;
567         int rc;
568
569         attribute = container_of(attr, struct stats_orangefs_attribute, attr);
570         stats_orangefs_obj =
571                 container_of(kobj, struct stats_orangefs_obj, kobj);
572
573         if (!attribute->show) {
574                 rc = -EIO;
575                 goto out;
576         }
577
578         rc = attribute->show(stats_orangefs_obj, attribute, buf);
579
580 out:
581         return rc;
582 }
583
584 static const struct sysfs_ops stats_orangefs_sysfs_ops = {
585         .show = stats_orangefs_attr_show,
586 };
587
588 static void orangefs_release(struct kobject *kobj)
589 {
590         struct orangefs_obj *orangefs_obj;
591
592         orangefs_obj = container_of(kobj, struct orangefs_obj, kobj);
593         kfree(orangefs_obj);
594 }
595
596 static void acache_orangefs_release(struct kobject *kobj)
597 {
598         struct acache_orangefs_obj *acache_orangefs_obj;
599
600         acache_orangefs_obj =
601                 container_of(kobj, struct acache_orangefs_obj, kobj);
602         kfree(acache_orangefs_obj);
603 }
604
605 static void capcache_orangefs_release(struct kobject *kobj)
606 {
607         struct capcache_orangefs_obj *capcache_orangefs_obj;
608
609         capcache_orangefs_obj =
610                 container_of(kobj, struct capcache_orangefs_obj, kobj);
611         kfree(capcache_orangefs_obj);
612 }
613
614 static void ccache_orangefs_release(struct kobject *kobj)
615 {
616         struct ccache_orangefs_obj *ccache_orangefs_obj;
617
618         ccache_orangefs_obj =
619                 container_of(kobj, struct ccache_orangefs_obj, kobj);
620         kfree(ccache_orangefs_obj);
621 }
622
623 static void ncache_orangefs_release(struct kobject *kobj)
624 {
625         struct ncache_orangefs_obj *ncache_orangefs_obj;
626
627         ncache_orangefs_obj =
628                 container_of(kobj, struct ncache_orangefs_obj, kobj);
629         kfree(ncache_orangefs_obj);
630 }
631
632 static void pc_orangefs_release(struct kobject *kobj)
633 {
634         struct pc_orangefs_obj *pc_orangefs_obj;
635
636         pc_orangefs_obj =
637                 container_of(kobj, struct pc_orangefs_obj, kobj);
638         kfree(pc_orangefs_obj);
639 }
640
641 static void stats_orangefs_release(struct kobject *kobj)
642 {
643         struct stats_orangefs_obj *stats_orangefs_obj;
644
645         stats_orangefs_obj =
646                 container_of(kobj, struct stats_orangefs_obj, kobj);
647         kfree(stats_orangefs_obj);
648 }
649
650 static ssize_t sysfs_int_show(char *kobj_id, char *buf, void *attr)
651 {
652         int rc = -EIO;
653         struct orangefs_attribute *orangefs_attr;
654         struct stats_orangefs_attribute *stats_orangefs_attr;
655
656         gossip_debug(GOSSIP_SYSFS_DEBUG, "sysfs_int_show: id:%s:\n", kobj_id);
657
658         if (!strcmp(kobj_id, ORANGEFS_KOBJ_ID)) {
659                 orangefs_attr = (struct orangefs_attribute *)attr;
660
661                 if (!strcmp(orangefs_attr->attr.name, "op_timeout_secs")) {
662                         rc = scnprintf(buf,
663                                        PAGE_SIZE,
664                                        "%d\n",
665                                        op_timeout_secs);
666                         goto out;
667                 } else if (!strcmp(orangefs_attr->attr.name,
668                                    "slot_timeout_secs")) {
669                         rc = scnprintf(buf,
670                                        PAGE_SIZE,
671                                        "%d\n",
672                                        slot_timeout_secs);
673                         goto out;
674                 } else if (!strcmp(orangefs_attr->attr.name,
675                                    "dcache_timeout_msecs")) {
676                         rc = scnprintf(buf,
677                                        PAGE_SIZE,
678                                        "%d\n",
679                                        dcache_timeout_msecs);
680                         goto out;
681                 } else if (!strcmp(orangefs_attr->attr.name,
682                                    "getattr_timeout_msecs")) {
683                         rc = scnprintf(buf,
684                                        PAGE_SIZE,
685                                        "%d\n",
686                                        getattr_timeout_msecs);
687                         goto out;
688                 } else {
689                         goto out;
690                 }
691
692         } else if (!strcmp(kobj_id, STATS_KOBJ_ID)) {
693                 stats_orangefs_attr = (struct stats_orangefs_attribute *)attr;
694
695                 if (!strcmp(stats_orangefs_attr->attr.name, "reads")) {
696                         rc = scnprintf(buf,
697                                        PAGE_SIZE,
698                                        "%lu\n",
699                                        g_orangefs_stats.reads);
700                         goto out;
701                 } else if (!strcmp(stats_orangefs_attr->attr.name, "writes")) {
702                         rc = scnprintf(buf,
703                                        PAGE_SIZE,
704                                        "%lu\n",
705                                        g_orangefs_stats.writes);
706                         goto out;
707                 } else {
708                         goto out;
709                 }
710         }
711
712 out:
713
714         return rc;
715 }
716
717 static ssize_t int_orangefs_show(struct orangefs_obj *orangefs_obj,
718                                  struct orangefs_attribute *attr,
719                                  char *buf)
720 {
721         int rc;
722
723         gossip_debug(GOSSIP_SYSFS_DEBUG,
724                      "int_orangefs_show:start attr->attr.name:%s:\n",
725                      attr->attr.name);
726
727         rc = sysfs_int_show(ORANGEFS_KOBJ_ID, buf, (void *) attr);
728
729         return rc;
730 }
731
732 static ssize_t int_stats_show(struct stats_orangefs_obj *stats_orangefs_obj,
733                         struct stats_orangefs_attribute *attr,
734                         char *buf)
735 {
736         int rc;
737
738         gossip_debug(GOSSIP_SYSFS_DEBUG,
739                      "int_stats_show:start attr->attr.name:%s:\n",
740                      attr->attr.name);
741
742         rc = sysfs_int_show(STATS_KOBJ_ID, buf, (void *) attr);
743
744         return rc;
745 }
746
747 static ssize_t int_store(struct orangefs_obj *orangefs_obj,
748                          struct orangefs_attribute *attr,
749                          const char *buf,
750                          size_t count)
751 {
752         int rc = 0;
753
754         gossip_debug(GOSSIP_SYSFS_DEBUG,
755                      "int_store: start attr->attr.name:%s: buf:%s:\n",
756                      attr->attr.name, buf);
757
758         if (!strcmp(attr->attr.name, "op_timeout_secs")) {
759                 rc = kstrtoint(buf, 0, &op_timeout_secs);
760                 goto out;
761         } else if (!strcmp(attr->attr.name, "slot_timeout_secs")) {
762                 rc = kstrtoint(buf, 0, &slot_timeout_secs);
763                 goto out;
764         } else if (!strcmp(attr->attr.name, "dcache_timeout_msecs")) {
765                 rc = kstrtoint(buf, 0, &dcache_timeout_msecs);
766                 goto out;
767         } else if (!strcmp(attr->attr.name, "getattr_timeout_msecs")) {
768                 rc = kstrtoint(buf, 0, &getattr_timeout_msecs);
769                 goto out;
770         } else {
771                 goto out;
772         }
773
774 out:
775         if (rc)
776                 rc = -EINVAL;
777         else
778                 rc = count;
779
780         return rc;
781 }
782
783 /*
784  * obtain attribute values from userspace with a service operation.
785  */
786 static int sysfs_service_op_show(char *kobj_id, char *buf, void *attr)
787 {
788         struct orangefs_kernel_op_s *new_op = NULL;
789         int rc = 0;
790         char *ser_op_type = NULL;
791         struct orangefs_attribute *orangefs_attr;
792         struct acache_orangefs_attribute *acache_attr;
793         struct capcache_orangefs_attribute *capcache_attr;
794         struct ccache_orangefs_attribute *ccache_attr;
795         struct ncache_orangefs_attribute *ncache_attr;
796         struct pc_orangefs_attribute *pc_attr;
797         __u32 op_alloc_type;
798
799         gossip_debug(GOSSIP_SYSFS_DEBUG,
800                      "sysfs_service_op_show: id:%s:\n",
801                      kobj_id);
802
803         if (strcmp(kobj_id, PC_KOBJ_ID))
804                 op_alloc_type = ORANGEFS_VFS_OP_PARAM;
805         else
806                 op_alloc_type = ORANGEFS_VFS_OP_PERF_COUNT;
807
808         new_op = op_alloc(op_alloc_type);
809         if (!new_op)
810                 return -ENOMEM;
811
812         /* Can't do a service_operation if the client is not running... */
813         rc = is_daemon_in_service();
814         if (rc) {
815                 pr_info("%s: Client not running :%d:\n",
816                         __func__,
817                         is_daemon_in_service());
818                 goto out;
819         }
820
821         if (strcmp(kobj_id, PC_KOBJ_ID))
822                 new_op->upcall.req.param.type = ORANGEFS_PARAM_REQUEST_GET;
823
824         if (!strcmp(kobj_id, ORANGEFS_KOBJ_ID)) {
825                 orangefs_attr = (struct orangefs_attribute *)attr;
826
827                 if (!strcmp(orangefs_attr->attr.name, "perf_history_size"))
828                         new_op->upcall.req.param.op =
829                                 ORANGEFS_PARAM_REQUEST_OP_PERF_HISTORY_SIZE;
830                 else if (!strcmp(orangefs_attr->attr.name,
831                                  "perf_time_interval_secs"))
832                         new_op->upcall.req.param.op =
833                                 ORANGEFS_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS;
834                 else if (!strcmp(orangefs_attr->attr.name,
835                                  "perf_counter_reset"))
836                         new_op->upcall.req.param.op =
837                                 ORANGEFS_PARAM_REQUEST_OP_PERF_RESET;
838
839         } else if (!strcmp(kobj_id, ACACHE_KOBJ_ID)) {
840                 acache_attr = (struct acache_orangefs_attribute *)attr;
841
842                 if (!strcmp(acache_attr->attr.name, "timeout_msecs"))
843                         new_op->upcall.req.param.op =
844                                 ORANGEFS_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS;
845
846                 if (!strcmp(acache_attr->attr.name, "hard_limit"))
847                         new_op->upcall.req.param.op =
848                                 ORANGEFS_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT;
849
850                 if (!strcmp(acache_attr->attr.name, "soft_limit"))
851                         new_op->upcall.req.param.op =
852                                 ORANGEFS_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT;
853
854                 if (!strcmp(acache_attr->attr.name, "reclaim_percentage"))
855                         new_op->upcall.req.param.op =
856                           ORANGEFS_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE;
857
858         } else if (!strcmp(kobj_id, CAPCACHE_KOBJ_ID)) {
859                 capcache_attr = (struct capcache_orangefs_attribute *)attr;
860
861                 if (!strcmp(capcache_attr->attr.name, "timeout_secs"))
862                         new_op->upcall.req.param.op =
863                                 ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS;
864
865                 if (!strcmp(capcache_attr->attr.name, "hard_limit"))
866                         new_op->upcall.req.param.op =
867                                 ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT;
868
869                 if (!strcmp(capcache_attr->attr.name, "soft_limit"))
870                         new_op->upcall.req.param.op =
871                                 ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT;
872
873                 if (!strcmp(capcache_attr->attr.name, "reclaim_percentage"))
874                         new_op->upcall.req.param.op =
875                           ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE;
876
877         } else if (!strcmp(kobj_id, CCACHE_KOBJ_ID)) {
878                 ccache_attr = (struct ccache_orangefs_attribute *)attr;
879
880                 if (!strcmp(ccache_attr->attr.name, "timeout_secs"))
881                         new_op->upcall.req.param.op =
882                                 ORANGEFS_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS;
883
884                 if (!strcmp(ccache_attr->attr.name, "hard_limit"))
885                         new_op->upcall.req.param.op =
886                                 ORANGEFS_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT;
887
888                 if (!strcmp(ccache_attr->attr.name, "soft_limit"))
889                         new_op->upcall.req.param.op =
890                                 ORANGEFS_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT;
891
892                 if (!strcmp(ccache_attr->attr.name, "reclaim_percentage"))
893                         new_op->upcall.req.param.op =
894                           ORANGEFS_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE;
895
896         } else if (!strcmp(kobj_id, NCACHE_KOBJ_ID)) {
897                 ncache_attr = (struct ncache_orangefs_attribute *)attr;
898
899                 if (!strcmp(ncache_attr->attr.name, "timeout_msecs"))
900                         new_op->upcall.req.param.op =
901                                 ORANGEFS_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS;
902
903                 if (!strcmp(ncache_attr->attr.name, "hard_limit"))
904                         new_op->upcall.req.param.op =
905                                 ORANGEFS_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT;
906
907                 if (!strcmp(ncache_attr->attr.name, "soft_limit"))
908                         new_op->upcall.req.param.op =
909                                 ORANGEFS_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT;
910
911                 if (!strcmp(ncache_attr->attr.name, "reclaim_percentage"))
912                         new_op->upcall.req.param.op =
913                           ORANGEFS_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE;
914
915         } else if (!strcmp(kobj_id, PC_KOBJ_ID)) {
916                 pc_attr = (struct pc_orangefs_attribute *)attr;
917
918                 if (!strcmp(pc_attr->attr.name, ACACHE_KOBJ_ID))
919                         new_op->upcall.req.perf_count.type =
920                                 ORANGEFS_PERF_COUNT_REQUEST_ACACHE;
921
922                 if (!strcmp(pc_attr->attr.name, CAPCACHE_KOBJ_ID))
923                         new_op->upcall.req.perf_count.type =
924                                 ORANGEFS_PERF_COUNT_REQUEST_CAPCACHE;
925
926                 if (!strcmp(pc_attr->attr.name, NCACHE_KOBJ_ID))
927                         new_op->upcall.req.perf_count.type =
928                                 ORANGEFS_PERF_COUNT_REQUEST_NCACHE;
929
930         } else {
931                 gossip_err("sysfs_service_op_show: unknown kobj_id:%s:\n",
932                            kobj_id);
933                 rc = -EINVAL;
934                 goto out;
935         }
936
937
938         if (strcmp(kobj_id, PC_KOBJ_ID))
939                 ser_op_type = "orangefs_param";
940         else
941                 ser_op_type = "orangefs_perf_count";
942
943         /*
944          * The service_operation will return an errno return code on
945          * error, and zero on success.
946          */
947         rc = service_operation(new_op, ser_op_type, ORANGEFS_OP_INTERRUPTIBLE);
948
949 out:
950         if (!rc) {
951                 if (strcmp(kobj_id, PC_KOBJ_ID)) {
952                         rc = scnprintf(buf,
953                                        PAGE_SIZE,
954                                        "%d\n",
955                                        (int)new_op->downcall.resp.param.value);
956                 } else {
957                         rc = scnprintf(
958                                 buf,
959                                 PAGE_SIZE,
960                                 "%s",
961                                 new_op->downcall.resp.perf_count.buffer);
962                 }
963         }
964
965         op_release(new_op);
966
967         return rc;
968
969 }
970
971 static ssize_t service_orangefs_show(struct orangefs_obj *orangefs_obj,
972                                      struct orangefs_attribute *attr,
973                                      char *buf)
974 {
975         int rc = 0;
976
977         rc = sysfs_service_op_show(ORANGEFS_KOBJ_ID, buf, (void *)attr);
978
979         return rc;
980 }
981
982 static ssize_t
983         service_acache_show(struct acache_orangefs_obj *acache_orangefs_obj,
984                             struct acache_orangefs_attribute *attr,
985                             char *buf)
986 {
987         int rc = 0;
988
989         rc = sysfs_service_op_show(ACACHE_KOBJ_ID, buf, (void *)attr);
990
991         return rc;
992 }
993
994 static ssize_t service_capcache_show(struct capcache_orangefs_obj
995                                         *capcache_orangefs_obj,
996                                      struct capcache_orangefs_attribute *attr,
997                                      char *buf)
998 {
999         int rc = 0;
1000
1001         rc = sysfs_service_op_show(CAPCACHE_KOBJ_ID, buf, (void *)attr);
1002
1003         return rc;
1004 }
1005
1006 static ssize_t service_ccache_show(struct ccache_orangefs_obj
1007                                         *ccache_orangefs_obj,
1008                                    struct ccache_orangefs_attribute *attr,
1009                                    char *buf)
1010 {
1011         int rc = 0;
1012
1013         rc = sysfs_service_op_show(CCACHE_KOBJ_ID, buf, (void *)attr);
1014
1015         return rc;
1016 }
1017
1018 static ssize_t
1019         service_ncache_show(struct ncache_orangefs_obj *ncache_orangefs_obj,
1020                             struct ncache_orangefs_attribute *attr,
1021                             char *buf)
1022 {
1023         int rc = 0;
1024
1025         rc = sysfs_service_op_show(NCACHE_KOBJ_ID, buf, (void *)attr);
1026
1027         return rc;
1028 }
1029
1030 static ssize_t
1031         service_pc_show(struct pc_orangefs_obj *pc_orangefs_obj,
1032                             struct pc_orangefs_attribute *attr,
1033                             char *buf)
1034 {
1035         int rc = 0;
1036
1037         rc = sysfs_service_op_show(PC_KOBJ_ID, buf, (void *)attr);
1038
1039         return rc;
1040 }
1041
1042 /*
1043  * pass attribute values back to userspace with a service operation.
1044  *
1045  * We have to do a memory allocation, an sscanf and a service operation.
1046  * And we have to evaluate what the user entered, to make sure the
1047  * value is within the range supported by the attribute. So, there's
1048  * a lot of return code checking and mapping going on here.
1049  *
1050  * We want to return 1 if we think everything went OK, and
1051  * EINVAL if not.
1052  */
1053 static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr)
1054 {
1055         struct orangefs_kernel_op_s *new_op = NULL;
1056         int val = 0;
1057         int rc = 0;
1058         struct orangefs_attribute *orangefs_attr;
1059         struct acache_orangefs_attribute *acache_attr;
1060         struct capcache_orangefs_attribute *capcache_attr;
1061         struct ccache_orangefs_attribute *ccache_attr;
1062         struct ncache_orangefs_attribute *ncache_attr;
1063
1064         gossip_debug(GOSSIP_SYSFS_DEBUG,
1065                      "sysfs_service_op_store: id:%s:\n",
1066                      kobj_id);
1067
1068         new_op = op_alloc(ORANGEFS_VFS_OP_PARAM);
1069         if (!new_op)
1070                 return -EINVAL; /* sic */
1071
1072         /* Can't do a service_operation if the client is not running... */
1073         rc = is_daemon_in_service();
1074         if (rc) {
1075                 pr_info("%s: Client not running :%d:\n",
1076                         __func__,
1077                         is_daemon_in_service());
1078                 goto out;
1079         }
1080
1081         /*
1082          * The value we want to send back to userspace is in buf.
1083          */
1084         rc = kstrtoint(buf, 0, &val);
1085         if (rc)
1086                 goto out;
1087
1088         if (!strcmp(kobj_id, ORANGEFS_KOBJ_ID)) {
1089                 orangefs_attr = (struct orangefs_attribute *)attr;
1090
1091                 if (!strcmp(orangefs_attr->attr.name, "perf_history_size")) {
1092                         if (val > 0) {
1093                                 new_op->upcall.req.param.op =
1094                                   ORANGEFS_PARAM_REQUEST_OP_PERF_HISTORY_SIZE;
1095                         } else {
1096                                 rc = 0;
1097                                 goto out;
1098                         }
1099                 } else if (!strcmp(orangefs_attr->attr.name,
1100                                    "perf_time_interval_secs")) {
1101                         if (val > 0) {
1102                                 new_op->upcall.req.param.op =
1103                                 ORANGEFS_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS;
1104                         } else {
1105                                 rc = 0;
1106                                 goto out;
1107                         }
1108                 } else if (!strcmp(orangefs_attr->attr.name,
1109                                    "perf_counter_reset")) {
1110                         if ((val == 0) || (val == 1)) {
1111                                 new_op->upcall.req.param.op =
1112                                         ORANGEFS_PARAM_REQUEST_OP_PERF_RESET;
1113                         } else {
1114                                 rc = 0;
1115                                 goto out;
1116                         }
1117                 }
1118
1119         } else if (!strcmp(kobj_id, ACACHE_KOBJ_ID)) {
1120                 acache_attr = (struct acache_orangefs_attribute *)attr;
1121
1122                 if (!strcmp(acache_attr->attr.name, "hard_limit")) {
1123                         if (val > -1) {
1124                                 new_op->upcall.req.param.op =
1125                                   ORANGEFS_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT;
1126                         } else {
1127                                 rc = 0;
1128                                 goto out;
1129                         }
1130                 } else if (!strcmp(acache_attr->attr.name, "soft_limit")) {
1131                         if (val > -1) {
1132                                 new_op->upcall.req.param.op =
1133                                   ORANGEFS_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT;
1134                         } else {
1135                                 rc = 0;
1136                                 goto out;
1137                         }
1138                 } else if (!strcmp(acache_attr->attr.name,
1139                                    "reclaim_percentage")) {
1140                         if ((val > -1) && (val < 101)) {
1141                                 new_op->upcall.req.param.op =
1142                                   ORANGEFS_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE;
1143                         } else {
1144                                 rc = 0;
1145                                 goto out;
1146                         }
1147                 } else if (!strcmp(acache_attr->attr.name, "timeout_msecs")) {
1148                         if (val > -1) {
1149                                 new_op->upcall.req.param.op =
1150                                   ORANGEFS_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS;
1151                         } else {
1152                                 rc = 0;
1153                                 goto out;
1154                         }
1155                 }
1156
1157         } else if (!strcmp(kobj_id, CAPCACHE_KOBJ_ID)) {
1158                 capcache_attr = (struct capcache_orangefs_attribute *)attr;
1159
1160                 if (!strcmp(capcache_attr->attr.name, "hard_limit")) {
1161                         if (val > -1) {
1162                                 new_op->upcall.req.param.op =
1163                                   ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT;
1164                         } else {
1165                                 rc = 0;
1166                                 goto out;
1167                         }
1168                 } else if (!strcmp(capcache_attr->attr.name, "soft_limit")) {
1169                         if (val > -1) {
1170                                 new_op->upcall.req.param.op =
1171                                   ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT;
1172                         } else {
1173                                 rc = 0;
1174                                 goto out;
1175                         }
1176                 } else if (!strcmp(capcache_attr->attr.name,
1177                                    "reclaim_percentage")) {
1178                         if ((val > -1) && (val < 101)) {
1179                                 new_op->upcall.req.param.op =
1180                                   ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE;
1181                         } else {
1182                                 rc = 0;
1183                                 goto out;
1184                         }
1185                 } else if (!strcmp(capcache_attr->attr.name, "timeout_secs")) {
1186                         if (val > -1) {
1187                                 new_op->upcall.req.param.op =
1188                                   ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS;
1189                         } else {
1190                                 rc = 0;
1191                                 goto out;
1192                         }
1193                 }
1194
1195         } else if (!strcmp(kobj_id, CCACHE_KOBJ_ID)) {
1196                 ccache_attr = (struct ccache_orangefs_attribute *)attr;
1197
1198                 if (!strcmp(ccache_attr->attr.name, "hard_limit")) {
1199                         if (val > -1) {
1200                                 new_op->upcall.req.param.op =
1201                                   ORANGEFS_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT;
1202                         } else {
1203                                 rc = 0;
1204                                 goto out;
1205                         }
1206                 } else if (!strcmp(ccache_attr->attr.name, "soft_limit")) {
1207                         if (val > -1) {
1208                                 new_op->upcall.req.param.op =
1209                                   ORANGEFS_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT;
1210                         } else {
1211                                 rc = 0;
1212                                 goto out;
1213                         }
1214                 } else if (!strcmp(ccache_attr->attr.name,
1215                                    "reclaim_percentage")) {
1216                         if ((val > -1) && (val < 101)) {
1217                                 new_op->upcall.req.param.op =
1218                                   ORANGEFS_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE;
1219                         } else {
1220                                 rc = 0;
1221                                 goto out;
1222                         }
1223                 } else if (!strcmp(ccache_attr->attr.name, "timeout_secs")) {
1224                         if (val > -1) {
1225                                 new_op->upcall.req.param.op =
1226                                   ORANGEFS_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS;
1227                         } else {
1228                                 rc = 0;
1229                                 goto out;
1230                         }
1231                 }
1232
1233         } else if (!strcmp(kobj_id, NCACHE_KOBJ_ID)) {
1234                 ncache_attr = (struct ncache_orangefs_attribute *)attr;
1235
1236                 if (!strcmp(ncache_attr->attr.name, "hard_limit")) {
1237                         if (val > -1) {
1238                                 new_op->upcall.req.param.op =
1239                                   ORANGEFS_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT;
1240                         } else {
1241                                 rc = 0;
1242                                 goto out;
1243                         }
1244                 } else if (!strcmp(ncache_attr->attr.name, "soft_limit")) {
1245                         if (val > -1) {
1246                                 new_op->upcall.req.param.op =
1247                                   ORANGEFS_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT;
1248                         } else {
1249                                 rc = 0;
1250                                 goto out;
1251                         }
1252                 } else if (!strcmp(ncache_attr->attr.name,
1253                                    "reclaim_percentage")) {
1254                         if ((val > -1) && (val < 101)) {
1255                                 new_op->upcall.req.param.op =
1256                                         ORANGEFS_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE;
1257                         } else {
1258                                 rc = 0;
1259                                 goto out;
1260                         }
1261                 } else if (!strcmp(ncache_attr->attr.name, "timeout_msecs")) {
1262                         if (val > -1) {
1263                                 new_op->upcall.req.param.op =
1264                                   ORANGEFS_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS;
1265                         } else {
1266                                 rc = 0;
1267                                 goto out;
1268                         }
1269                 }
1270
1271         } else {
1272                 gossip_err("sysfs_service_op_store: unknown kobj_id:%s:\n",
1273                            kobj_id);
1274                 rc = -EINVAL;
1275                 goto out;
1276         }
1277
1278         new_op->upcall.req.param.type = ORANGEFS_PARAM_REQUEST_SET;
1279
1280         new_op->upcall.req.param.value = val;
1281
1282         /*
1283          * The service_operation will return a errno return code on
1284          * error, and zero on success.
1285          */
1286         rc = service_operation(new_op, "orangefs_param", ORANGEFS_OP_INTERRUPTIBLE);
1287
1288         if (rc < 0) {
1289                 gossip_err("sysfs_service_op_store: service op returned:%d:\n",
1290                         rc);
1291                 rc = 0;
1292         } else {
1293                 rc = 1;
1294         }
1295
1296 out:
1297         op_release(new_op);
1298
1299         if (rc == -ENOMEM || rc == 0)
1300                 rc = -EINVAL;
1301
1302         return rc;
1303 }
1304
1305 static ssize_t
1306         service_orangefs_store(struct orangefs_obj *orangefs_obj,
1307                                struct orangefs_attribute *attr,
1308                                const char *buf,
1309                                size_t count)
1310 {
1311         int rc = 0;
1312
1313         rc = sysfs_service_op_store(ORANGEFS_KOBJ_ID, buf, (void *) attr);
1314
1315         /* rc should have an errno value if the service_op went bad. */
1316         if (rc == 1)
1317                 rc = count;
1318
1319         return rc;
1320 }
1321
1322 static ssize_t
1323         service_acache_store(struct acache_orangefs_obj *acache_orangefs_obj,
1324                              struct acache_orangefs_attribute *attr,
1325                              const char *buf,
1326                              size_t count)
1327 {
1328         int rc = 0;
1329
1330         rc = sysfs_service_op_store(ACACHE_KOBJ_ID, buf, (void *) attr);
1331
1332         /* rc should have an errno value if the service_op went bad. */
1333         if (rc == 1)
1334                 rc = count;
1335
1336         return rc;
1337 }
1338
1339 static ssize_t
1340         service_capcache_store(struct capcache_orangefs_obj
1341                                 *capcache_orangefs_obj,
1342                                struct capcache_orangefs_attribute *attr,
1343                                const char *buf,
1344                                size_t count)
1345 {
1346         int rc = 0;
1347
1348         rc = sysfs_service_op_store(CAPCACHE_KOBJ_ID, buf, (void *) attr);
1349
1350         /* rc should have an errno value if the service_op went bad. */
1351         if (rc == 1)
1352                 rc = count;
1353
1354         return rc;
1355 }
1356
1357 static ssize_t service_ccache_store(struct ccache_orangefs_obj
1358                                         *ccache_orangefs_obj,
1359                                     struct ccache_orangefs_attribute *attr,
1360                                     const char *buf,
1361                                     size_t count)
1362 {
1363         int rc = 0;
1364
1365         rc = sysfs_service_op_store(CCACHE_KOBJ_ID, buf, (void *) attr);
1366
1367         /* rc should have an errno value if the service_op went bad. */
1368         if (rc == 1)
1369                 rc = count;
1370
1371         return rc;
1372 }
1373
1374 static ssize_t
1375         service_ncache_store(struct ncache_orangefs_obj *ncache_orangefs_obj,
1376                              struct ncache_orangefs_attribute *attr,
1377                              const char *buf,
1378                              size_t count)
1379 {
1380         int rc = 0;
1381
1382         rc = sysfs_service_op_store(NCACHE_KOBJ_ID, buf, (void *) attr);
1383
1384         /* rc should have an errno value if the service_op went bad. */
1385         if (rc == 1)
1386                 rc = count;
1387
1388         return rc;
1389 }
1390
1391 static struct orangefs_attribute op_timeout_secs_attribute =
1392         __ATTR(op_timeout_secs, 0664, int_orangefs_show, int_store);
1393
1394 static struct orangefs_attribute slot_timeout_secs_attribute =
1395         __ATTR(slot_timeout_secs, 0664, int_orangefs_show, int_store);
1396
1397 static struct orangefs_attribute dcache_timeout_msecs_attribute =
1398         __ATTR(dcache_timeout_msecs, 0664, int_orangefs_show, int_store);
1399
1400 static struct orangefs_attribute getattr_timeout_msecs_attribute =
1401         __ATTR(getattr_timeout_msecs, 0664, int_orangefs_show, int_store);
1402
1403 static struct orangefs_attribute perf_counter_reset_attribute =
1404         __ATTR(perf_counter_reset,
1405                0664,
1406                service_orangefs_show,
1407                service_orangefs_store);
1408
1409 static struct orangefs_attribute perf_history_size_attribute =
1410         __ATTR(perf_history_size,
1411                0664,
1412                service_orangefs_show,
1413                service_orangefs_store);
1414
1415 static struct orangefs_attribute perf_time_interval_secs_attribute =
1416         __ATTR(perf_time_interval_secs,
1417                0664,
1418                service_orangefs_show,
1419                service_orangefs_store);
1420
1421 static struct attribute *orangefs_default_attrs[] = {
1422         &op_timeout_secs_attribute.attr,
1423         &slot_timeout_secs_attribute.attr,
1424         &dcache_timeout_msecs_attribute.attr,
1425         &getattr_timeout_msecs_attribute.attr,
1426         &perf_counter_reset_attribute.attr,
1427         &perf_history_size_attribute.attr,
1428         &perf_time_interval_secs_attribute.attr,
1429         NULL,
1430 };
1431
1432 static struct kobj_type orangefs_ktype = {
1433         .sysfs_ops = &orangefs_sysfs_ops,
1434         .release = orangefs_release,
1435         .default_attrs = orangefs_default_attrs,
1436 };
1437
1438 static struct acache_orangefs_attribute acache_hard_limit_attribute =
1439         __ATTR(hard_limit,
1440                0664,
1441                service_acache_show,
1442                service_acache_store);
1443
1444 static struct acache_orangefs_attribute acache_reclaim_percent_attribute =
1445         __ATTR(reclaim_percentage,
1446                0664,
1447                service_acache_show,
1448                service_acache_store);
1449
1450 static struct acache_orangefs_attribute acache_soft_limit_attribute =
1451         __ATTR(soft_limit,
1452                0664,
1453                service_acache_show,
1454                service_acache_store);
1455
1456 static struct acache_orangefs_attribute acache_timeout_msecs_attribute =
1457         __ATTR(timeout_msecs,
1458                0664,
1459                service_acache_show,
1460                service_acache_store);
1461
1462 static struct attribute *acache_orangefs_default_attrs[] = {
1463         &acache_hard_limit_attribute.attr,
1464         &acache_reclaim_percent_attribute.attr,
1465         &acache_soft_limit_attribute.attr,
1466         &acache_timeout_msecs_attribute.attr,
1467         NULL,
1468 };
1469
1470 static struct kobj_type acache_orangefs_ktype = {
1471         .sysfs_ops = &acache_orangefs_sysfs_ops,
1472         .release = acache_orangefs_release,
1473         .default_attrs = acache_orangefs_default_attrs,
1474 };
1475
1476 static struct capcache_orangefs_attribute capcache_hard_limit_attribute =
1477         __ATTR(hard_limit,
1478                0664,
1479                service_capcache_show,
1480                service_capcache_store);
1481
1482 static struct capcache_orangefs_attribute capcache_reclaim_percent_attribute =
1483         __ATTR(reclaim_percentage,
1484                0664,
1485                service_capcache_show,
1486                service_capcache_store);
1487
1488 static struct capcache_orangefs_attribute capcache_soft_limit_attribute =
1489         __ATTR(soft_limit,
1490                0664,
1491                service_capcache_show,
1492                service_capcache_store);
1493
1494 static struct capcache_orangefs_attribute capcache_timeout_secs_attribute =
1495         __ATTR(timeout_secs,
1496                0664,
1497                service_capcache_show,
1498                service_capcache_store);
1499
1500 static struct attribute *capcache_orangefs_default_attrs[] = {
1501         &capcache_hard_limit_attribute.attr,
1502         &capcache_reclaim_percent_attribute.attr,
1503         &capcache_soft_limit_attribute.attr,
1504         &capcache_timeout_secs_attribute.attr,
1505         NULL,
1506 };
1507
1508 static struct kobj_type capcache_orangefs_ktype = {
1509         .sysfs_ops = &capcache_orangefs_sysfs_ops,
1510         .release = capcache_orangefs_release,
1511         .default_attrs = capcache_orangefs_default_attrs,
1512 };
1513
1514 static struct ccache_orangefs_attribute ccache_hard_limit_attribute =
1515         __ATTR(hard_limit,
1516                0664,
1517                service_ccache_show,
1518                service_ccache_store);
1519
1520 static struct ccache_orangefs_attribute ccache_reclaim_percent_attribute =
1521         __ATTR(reclaim_percentage,
1522                0664,
1523                service_ccache_show,
1524                service_ccache_store);
1525
1526 static struct ccache_orangefs_attribute ccache_soft_limit_attribute =
1527         __ATTR(soft_limit,
1528                0664,
1529                service_ccache_show,
1530                service_ccache_store);
1531
1532 static struct ccache_orangefs_attribute ccache_timeout_secs_attribute =
1533         __ATTR(timeout_secs,
1534                0664,
1535                service_ccache_show,
1536                service_ccache_store);
1537
1538 static struct attribute *ccache_orangefs_default_attrs[] = {
1539         &ccache_hard_limit_attribute.attr,
1540         &ccache_reclaim_percent_attribute.attr,
1541         &ccache_soft_limit_attribute.attr,
1542         &ccache_timeout_secs_attribute.attr,
1543         NULL,
1544 };
1545
1546 static struct kobj_type ccache_orangefs_ktype = {
1547         .sysfs_ops = &ccache_orangefs_sysfs_ops,
1548         .release = ccache_orangefs_release,
1549         .default_attrs = ccache_orangefs_default_attrs,
1550 };
1551
1552 static struct ncache_orangefs_attribute ncache_hard_limit_attribute =
1553         __ATTR(hard_limit,
1554                0664,
1555                service_ncache_show,
1556                service_ncache_store);
1557
1558 static struct ncache_orangefs_attribute ncache_reclaim_percent_attribute =
1559         __ATTR(reclaim_percentage,
1560                0664,
1561                service_ncache_show,
1562                service_ncache_store);
1563
1564 static struct ncache_orangefs_attribute ncache_soft_limit_attribute =
1565         __ATTR(soft_limit,
1566                0664,
1567                service_ncache_show,
1568                service_ncache_store);
1569
1570 static struct ncache_orangefs_attribute ncache_timeout_msecs_attribute =
1571         __ATTR(timeout_msecs,
1572                0664,
1573                service_ncache_show,
1574                service_ncache_store);
1575
1576 static struct attribute *ncache_orangefs_default_attrs[] = {
1577         &ncache_hard_limit_attribute.attr,
1578         &ncache_reclaim_percent_attribute.attr,
1579         &ncache_soft_limit_attribute.attr,
1580         &ncache_timeout_msecs_attribute.attr,
1581         NULL,
1582 };
1583
1584 static struct kobj_type ncache_orangefs_ktype = {
1585         .sysfs_ops = &ncache_orangefs_sysfs_ops,
1586         .release = ncache_orangefs_release,
1587         .default_attrs = ncache_orangefs_default_attrs,
1588 };
1589
1590 static struct pc_orangefs_attribute pc_acache_attribute =
1591         __ATTR(acache,
1592                0664,
1593                service_pc_show,
1594                NULL);
1595
1596 static struct pc_orangefs_attribute pc_capcache_attribute =
1597         __ATTR(capcache,
1598                0664,
1599                service_pc_show,
1600                NULL);
1601
1602 static struct pc_orangefs_attribute pc_ncache_attribute =
1603         __ATTR(ncache,
1604                0664,
1605                service_pc_show,
1606                NULL);
1607
1608 static struct attribute *pc_orangefs_default_attrs[] = {
1609         &pc_acache_attribute.attr,
1610         &pc_capcache_attribute.attr,
1611         &pc_ncache_attribute.attr,
1612         NULL,
1613 };
1614
1615 static struct kobj_type pc_orangefs_ktype = {
1616         .sysfs_ops = &pc_orangefs_sysfs_ops,
1617         .release = pc_orangefs_release,
1618         .default_attrs = pc_orangefs_default_attrs,
1619 };
1620
1621 static struct stats_orangefs_attribute stats_reads_attribute =
1622         __ATTR(reads,
1623                0664,
1624                int_stats_show,
1625                NULL);
1626
1627 static struct stats_orangefs_attribute stats_writes_attribute =
1628         __ATTR(writes,
1629                0664,
1630                int_stats_show,
1631                NULL);
1632
1633 static struct attribute *stats_orangefs_default_attrs[] = {
1634         &stats_reads_attribute.attr,
1635         &stats_writes_attribute.attr,
1636         NULL,
1637 };
1638
1639 static struct kobj_type stats_orangefs_ktype = {
1640         .sysfs_ops = &stats_orangefs_sysfs_ops,
1641         .release = stats_orangefs_release,
1642         .default_attrs = stats_orangefs_default_attrs,
1643 };
1644
1645 static struct orangefs_obj *orangefs_obj;
1646 static struct acache_orangefs_obj *acache_orangefs_obj;
1647 static struct capcache_orangefs_obj *capcache_orangefs_obj;
1648 static struct ccache_orangefs_obj *ccache_orangefs_obj;
1649 static struct ncache_orangefs_obj *ncache_orangefs_obj;
1650 static struct pc_orangefs_obj *pc_orangefs_obj;
1651 static struct stats_orangefs_obj *stats_orangefs_obj;
1652
1653 int orangefs_sysfs_init(void)
1654 {
1655         int rc = -EINVAL;
1656
1657         gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_init: start\n");
1658
1659         /* create /sys/fs/orangefs. */
1660         orangefs_obj = kzalloc(sizeof(*orangefs_obj), GFP_KERNEL);
1661         if (!orangefs_obj)
1662                 goto out;
1663
1664         rc = kobject_init_and_add(&orangefs_obj->kobj,
1665                                   &orangefs_ktype,
1666                                   fs_kobj,
1667                                   ORANGEFS_KOBJ_ID);
1668
1669         if (rc)
1670                 goto ofs_obj_bail;
1671
1672         kobject_uevent(&orangefs_obj->kobj, KOBJ_ADD);
1673
1674         /* create /sys/fs/orangefs/acache. */
1675         acache_orangefs_obj = kzalloc(sizeof(*acache_orangefs_obj), GFP_KERNEL);
1676         if (!acache_orangefs_obj) {
1677                 rc = -EINVAL;
1678                 goto ofs_obj_bail;
1679         }
1680
1681         rc = kobject_init_and_add(&acache_orangefs_obj->kobj,
1682                                   &acache_orangefs_ktype,
1683                                   &orangefs_obj->kobj,
1684                                   ACACHE_KOBJ_ID);
1685
1686         if (rc)
1687                 goto acache_obj_bail;
1688
1689         kobject_uevent(&acache_orangefs_obj->kobj, KOBJ_ADD);
1690
1691         /* create /sys/fs/orangefs/capcache. */
1692         capcache_orangefs_obj =
1693                 kzalloc(sizeof(*capcache_orangefs_obj), GFP_KERNEL);
1694         if (!capcache_orangefs_obj) {
1695                 rc = -EINVAL;
1696                 goto acache_obj_bail;
1697         }
1698
1699         rc = kobject_init_and_add(&capcache_orangefs_obj->kobj,
1700                                   &capcache_orangefs_ktype,
1701                                   &orangefs_obj->kobj,
1702                                   CAPCACHE_KOBJ_ID);
1703         if (rc)
1704                 goto capcache_obj_bail;
1705
1706         kobject_uevent(&capcache_orangefs_obj->kobj, KOBJ_ADD);
1707
1708         /* create /sys/fs/orangefs/ccache. */
1709         ccache_orangefs_obj =
1710                 kzalloc(sizeof(*ccache_orangefs_obj), GFP_KERNEL);
1711         if (!ccache_orangefs_obj) {
1712                 rc = -EINVAL;
1713                 goto capcache_obj_bail;
1714         }
1715
1716         rc = kobject_init_and_add(&ccache_orangefs_obj->kobj,
1717                                   &ccache_orangefs_ktype,
1718                                   &orangefs_obj->kobj,
1719                                   CCACHE_KOBJ_ID);
1720         if (rc)
1721                 goto ccache_obj_bail;
1722
1723         kobject_uevent(&ccache_orangefs_obj->kobj, KOBJ_ADD);
1724
1725         /* create /sys/fs/orangefs/ncache. */
1726         ncache_orangefs_obj = kzalloc(sizeof(*ncache_orangefs_obj), GFP_KERNEL);
1727         if (!ncache_orangefs_obj) {
1728                 rc = -EINVAL;
1729                 goto ccache_obj_bail;
1730         }
1731
1732         rc = kobject_init_and_add(&ncache_orangefs_obj->kobj,
1733                                   &ncache_orangefs_ktype,
1734                                   &orangefs_obj->kobj,
1735                                   NCACHE_KOBJ_ID);
1736
1737         if (rc)
1738                 goto ncache_obj_bail;
1739
1740         kobject_uevent(&ncache_orangefs_obj->kobj, KOBJ_ADD);
1741
1742         /* create /sys/fs/orangefs/perf_counters. */
1743         pc_orangefs_obj = kzalloc(sizeof(*pc_orangefs_obj), GFP_KERNEL);
1744         if (!pc_orangefs_obj) {
1745                 rc = -EINVAL;
1746                 goto ncache_obj_bail;
1747         }
1748
1749         rc = kobject_init_and_add(&pc_orangefs_obj->kobj,
1750                                   &pc_orangefs_ktype,
1751                                   &orangefs_obj->kobj,
1752                                   "perf_counters");
1753
1754         if (rc)
1755                 goto pc_obj_bail;
1756
1757         kobject_uevent(&pc_orangefs_obj->kobj, KOBJ_ADD);
1758
1759         /* create /sys/fs/orangefs/stats. */
1760         stats_orangefs_obj = kzalloc(sizeof(*stats_orangefs_obj), GFP_KERNEL);
1761         if (!stats_orangefs_obj) {
1762                 rc = -EINVAL;
1763                 goto pc_obj_bail;
1764         }
1765
1766         rc = kobject_init_and_add(&stats_orangefs_obj->kobj,
1767                                   &stats_orangefs_ktype,
1768                                   &orangefs_obj->kobj,
1769                                   STATS_KOBJ_ID);
1770
1771         if (rc)
1772                 goto stats_obj_bail;
1773
1774         kobject_uevent(&stats_orangefs_obj->kobj, KOBJ_ADD);
1775         goto out;
1776
1777 stats_obj_bail:
1778                 kobject_put(&stats_orangefs_obj->kobj);
1779
1780 pc_obj_bail:
1781                 kobject_put(&pc_orangefs_obj->kobj);
1782
1783 ncache_obj_bail:
1784                 kobject_put(&ncache_orangefs_obj->kobj);
1785
1786 ccache_obj_bail:
1787                 kobject_put(&ccache_orangefs_obj->kobj);
1788
1789 capcache_obj_bail:
1790                 kobject_put(&capcache_orangefs_obj->kobj);
1791
1792 acache_obj_bail:
1793                 kobject_put(&acache_orangefs_obj->kobj);
1794
1795 ofs_obj_bail:
1796                 kobject_put(&orangefs_obj->kobj);
1797 out:
1798         return rc;
1799 }
1800
1801 void orangefs_sysfs_exit(void)
1802 {
1803         gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_exit: start\n");
1804
1805         kobject_put(&acache_orangefs_obj->kobj);
1806         kobject_put(&capcache_orangefs_obj->kobj);
1807         kobject_put(&ccache_orangefs_obj->kobj);
1808         kobject_put(&ncache_orangefs_obj->kobj);
1809         kobject_put(&pc_orangefs_obj->kobj);
1810         kobject_put(&stats_orangefs_obj->kobj);
1811
1812         kobject_put(&orangefs_obj->kobj);
1813 }