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