6cbc2468f5ba42851d3b84c77a6c898d5ad69236
[linux-block.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/readahead_count
77  * Date:                Aug 2016
78  * Contact:             Martin Brandenburg <martin@omnibond.com>
79  * Description:
80  *                      Readahead cache buffer count.
81  *
82  * What:                /sys/fs/orangefs/readahead_size
83  * Date:                Aug 2016
84  * Contact:             Martin Brandenburg <martin@omnibond.com>
85  * Description:
86  *                      Readahead cache buffer size.
87  *
88  * What:                /sys/fs/orangefs/readahead_count_size
89  * Date:                Aug 2016
90  * Contact:             Martin Brandenburg <martin@omnibond.com>
91  * Description:
92  *                      Readahead cache buffer count and size.
93  *
94  * What:                /sys/fs/orangefs/acache/...
95  * Date:                Jun 2015
96  * Contact:             Martin Brandenburg <martin@omnibond.com>
97  * Description:
98  *                      Attribute cache configurable settings.
99  *
100  *
101  * What:                /sys/fs/orangefs/ncache/...
102  * Date:                Jun 2015
103  * Contact:             Mike Marshall <hubcap@omnibond.com>
104  * Description:
105  *                      Name cache configurable settings.
106  *
107  *
108  * What:                /sys/fs/orangefs/capcache/...
109  * Date:                Jun 2015
110  * Contact:             Mike Marshall <hubcap@omnibond.com>
111  * Description:
112  *                      Capability cache configurable settings.
113  *
114  *
115  * What:                /sys/fs/orangefs/ccache/...
116  * Date:                Jun 2015
117  * Contact:             Mike Marshall <hubcap@omnibond.com>
118  * Description:
119  *                      Credential cache configurable settings.
120  *
121  */
122
123 #include <linux/fs.h>
124 #include <linux/kobject.h>
125 #include <linux/string.h>
126 #include <linux/sysfs.h>
127 #include <linux/module.h>
128 #include <linux/init.h>
129
130 #include "protocol.h"
131 #include "orangefs-kernel.h"
132 #include "orangefs-sysfs.h"
133
134 #define ORANGEFS_KOBJ_ID "orangefs"
135 #define ACACHE_KOBJ_ID "acache"
136 #define CAPCACHE_KOBJ_ID "capcache"
137 #define CCACHE_KOBJ_ID "ccache"
138 #define NCACHE_KOBJ_ID "ncache"
139 #define PC_KOBJ_ID "pc"
140 #define STATS_KOBJ_ID "stats"
141
142 struct orangefs_attribute {
143         struct attribute attr;
144         ssize_t (*show)(struct orangefs_attribute *attr,
145                         char *buf);
146         ssize_t (*store)(struct orangefs_attribute *attr,
147                          const char *buf,
148                          size_t count);
149 };
150
151 static ssize_t orangefs_attr_show(struct kobject *kobj,
152                                   struct attribute *attr,
153                                   char *buf)
154 {
155         struct orangefs_attribute *attribute;
156         int rc;
157
158         attribute = container_of(attr, struct orangefs_attribute, attr);
159
160         if (!attribute->show) {
161                 rc = -EIO;
162                 goto out;
163         }
164
165         rc = attribute->show(attribute, buf);
166
167 out:
168         return rc;
169 }
170
171 static ssize_t orangefs_attr_store(struct kobject *kobj,
172                                    struct attribute *attr,
173                                    const char *buf,
174                                    size_t len)
175 {
176         struct orangefs_attribute *attribute;
177         int rc;
178
179         gossip_debug(GOSSIP_SYSFS_DEBUG,
180                      "orangefs_attr_store: start\n");
181
182         attribute = container_of(attr, struct orangefs_attribute, attr);
183
184         if (!attribute->store) {
185                 rc = -EIO;
186                 goto out;
187         }
188
189         rc = attribute->store(attribute, buf, len);
190
191 out:
192         return rc;
193 }
194
195 static const struct sysfs_ops orangefs_sysfs_ops = {
196         .show = orangefs_attr_show,
197         .store = orangefs_attr_store,
198 };
199
200 static const struct sysfs_ops acache_orangefs_sysfs_ops = {
201         .show = orangefs_attr_show,
202         .store = orangefs_attr_store,
203 };
204
205 static const struct sysfs_ops capcache_orangefs_sysfs_ops = {
206         .show = orangefs_attr_show,
207         .store = orangefs_attr_store,
208 };
209
210 static const struct sysfs_ops ccache_orangefs_sysfs_ops = {
211         .show = orangefs_attr_show,
212         .store = orangefs_attr_store,
213 };
214
215 static const struct sysfs_ops ncache_orangefs_sysfs_ops = {
216         .show = orangefs_attr_show,
217         .store = orangefs_attr_store,
218 };
219
220 static const struct sysfs_ops pc_orangefs_sysfs_ops = {
221         .show = orangefs_attr_show,
222 };
223
224 static const struct sysfs_ops stats_orangefs_sysfs_ops = {
225         .show = orangefs_attr_show,
226 };
227
228 static ssize_t sysfs_int_show(char *kobj_id, char *buf, void *attr)
229 {
230         int rc = -EIO;
231         struct orangefs_attribute *orangefs_attr = attr;
232
233         gossip_debug(GOSSIP_SYSFS_DEBUG, "sysfs_int_show: id:%s:\n", kobj_id);
234
235         if (!strcmp(kobj_id, ORANGEFS_KOBJ_ID)) {
236                 if (!strcmp(orangefs_attr->attr.name, "op_timeout_secs")) {
237                         rc = scnprintf(buf,
238                                        PAGE_SIZE,
239                                        "%d\n",
240                                        op_timeout_secs);
241                         goto out;
242                 } else if (!strcmp(orangefs_attr->attr.name,
243                                    "slot_timeout_secs")) {
244                         rc = scnprintf(buf,
245                                        PAGE_SIZE,
246                                        "%d\n",
247                                        slot_timeout_secs);
248                         goto out;
249                 } else if (!strcmp(orangefs_attr->attr.name,
250                                    "dcache_timeout_msecs")) {
251                         rc = scnprintf(buf,
252                                        PAGE_SIZE,
253                                        "%d\n",
254                                        dcache_timeout_msecs);
255                         goto out;
256                 } else if (!strcmp(orangefs_attr->attr.name,
257                                    "getattr_timeout_msecs")) {
258                         rc = scnprintf(buf,
259                                        PAGE_SIZE,
260                                        "%d\n",
261                                        getattr_timeout_msecs);
262                         goto out;
263                 } else {
264                         goto out;
265                 }
266
267         } else if (!strcmp(kobj_id, STATS_KOBJ_ID)) {
268                 if (!strcmp(orangefs_attr->attr.name, "reads")) {
269                         rc = scnprintf(buf,
270                                        PAGE_SIZE,
271                                        "%lu\n",
272                                        g_orangefs_stats.reads);
273                         goto out;
274                 } else if (!strcmp(orangefs_attr->attr.name, "writes")) {
275                         rc = scnprintf(buf,
276                                        PAGE_SIZE,
277                                        "%lu\n",
278                                        g_orangefs_stats.writes);
279                         goto out;
280                 } else {
281                         goto out;
282                 }
283         }
284
285 out:
286
287         return rc;
288 }
289
290 static ssize_t int_orangefs_show(struct orangefs_attribute *attr,
291                                  char *buf)
292 {
293         int rc;
294
295         gossip_debug(GOSSIP_SYSFS_DEBUG,
296                      "int_orangefs_show:start attr->attr.name:%s:\n",
297                      attr->attr.name);
298
299         rc = sysfs_int_show(ORANGEFS_KOBJ_ID, buf, (void *) attr);
300
301         return rc;
302 }
303
304 static ssize_t int_stats_show(struct orangefs_attribute *attr,
305                         char *buf)
306 {
307         int rc;
308
309         gossip_debug(GOSSIP_SYSFS_DEBUG,
310                      "int_stats_show:start attr->attr.name:%s:\n",
311                      attr->attr.name);
312
313         rc = sysfs_int_show(STATS_KOBJ_ID, buf, (void *) attr);
314
315         return rc;
316 }
317
318 static ssize_t int_store(struct orangefs_attribute *attr,
319                          const char *buf,
320                          size_t count)
321 {
322         int rc = 0;
323
324         gossip_debug(GOSSIP_SYSFS_DEBUG,
325                      "int_store: start attr->attr.name:%s: buf:%s:\n",
326                      attr->attr.name, buf);
327
328         if (!strcmp(attr->attr.name, "op_timeout_secs")) {
329                 rc = kstrtoint(buf, 0, &op_timeout_secs);
330                 goto out;
331         } else if (!strcmp(attr->attr.name, "slot_timeout_secs")) {
332                 rc = kstrtoint(buf, 0, &slot_timeout_secs);
333                 goto out;
334         } else if (!strcmp(attr->attr.name, "dcache_timeout_msecs")) {
335                 rc = kstrtoint(buf, 0, &dcache_timeout_msecs);
336                 goto out;
337         } else if (!strcmp(attr->attr.name, "getattr_timeout_msecs")) {
338                 rc = kstrtoint(buf, 0, &getattr_timeout_msecs);
339                 goto out;
340         } else {
341                 goto out;
342         }
343
344 out:
345         if (rc)
346                 rc = -EINVAL;
347         else
348                 rc = count;
349
350         return rc;
351 }
352
353 /*
354  * obtain attribute values from userspace with a service operation.
355  */
356 static int sysfs_service_op_show(char *kobj_id, char *buf, void *attr)
357 {
358         struct orangefs_kernel_op_s *new_op = NULL;
359         int rc = 0;
360         char *ser_op_type = NULL;
361         struct orangefs_attribute *orangefs_attr = attr;
362         __u32 op_alloc_type;
363
364         gossip_debug(GOSSIP_SYSFS_DEBUG,
365                      "sysfs_service_op_show: id:%s:\n",
366                      kobj_id);
367
368         if (strcmp(kobj_id, PC_KOBJ_ID))
369                 op_alloc_type = ORANGEFS_VFS_OP_PARAM;
370         else
371                 op_alloc_type = ORANGEFS_VFS_OP_PERF_COUNT;
372
373         new_op = op_alloc(op_alloc_type);
374         if (!new_op)
375                 return -ENOMEM;
376
377         /* Can't do a service_operation if the client is not running... */
378         rc = is_daemon_in_service();
379         if (rc) {
380                 pr_info("%s: Client not running :%d:\n",
381                         __func__,
382                         is_daemon_in_service());
383                 goto out;
384         }
385
386         if (strcmp(kobj_id, PC_KOBJ_ID))
387                 new_op->upcall.req.param.type = ORANGEFS_PARAM_REQUEST_GET;
388
389         if (!strcmp(kobj_id, ORANGEFS_KOBJ_ID)) {
390                 if (!strcmp(orangefs_attr->attr.name, "perf_history_size"))
391                         new_op->upcall.req.param.op =
392                                 ORANGEFS_PARAM_REQUEST_OP_PERF_HISTORY_SIZE;
393                 else if (!strcmp(orangefs_attr->attr.name,
394                                  "perf_time_interval_secs"))
395                         new_op->upcall.req.param.op =
396                                 ORANGEFS_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS;
397                 else if (!strcmp(orangefs_attr->attr.name,
398                                  "perf_counter_reset"))
399                         new_op->upcall.req.param.op =
400                                 ORANGEFS_PARAM_REQUEST_OP_PERF_RESET;
401
402                 else if (!strcmp(orangefs_attr->attr.name,
403                                  "readahead_count"))
404                         new_op->upcall.req.param.op =
405                                 ORANGEFS_PARAM_REQUEST_OP_READAHEAD_COUNT;
406
407                 else if (!strcmp(orangefs_attr->attr.name,
408                                  "readahead_size"))
409                         new_op->upcall.req.param.op =
410                                 ORANGEFS_PARAM_REQUEST_OP_READAHEAD_SIZE;
411
412                 else if (!strcmp(orangefs_attr->attr.name,
413                                  "readahead_count_size"))
414                         new_op->upcall.req.param.op =
415                                 ORANGEFS_PARAM_REQUEST_OP_READAHEAD_COUNT_SIZE;
416         } else if (!strcmp(kobj_id, ACACHE_KOBJ_ID)) {
417                 if (!strcmp(orangefs_attr->attr.name, "timeout_msecs"))
418                         new_op->upcall.req.param.op =
419                                 ORANGEFS_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS;
420
421                 if (!strcmp(orangefs_attr->attr.name, "hard_limit"))
422                         new_op->upcall.req.param.op =
423                                 ORANGEFS_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT;
424
425                 if (!strcmp(orangefs_attr->attr.name, "soft_limit"))
426                         new_op->upcall.req.param.op =
427                                 ORANGEFS_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT;
428
429                 if (!strcmp(orangefs_attr->attr.name, "reclaim_percentage"))
430                         new_op->upcall.req.param.op =
431                           ORANGEFS_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE;
432
433         } else if (!strcmp(kobj_id, CAPCACHE_KOBJ_ID)) {
434                 if (!strcmp(orangefs_attr->attr.name, "timeout_secs"))
435                         new_op->upcall.req.param.op =
436                                 ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS;
437
438                 if (!strcmp(orangefs_attr->attr.name, "hard_limit"))
439                         new_op->upcall.req.param.op =
440                                 ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT;
441
442                 if (!strcmp(orangefs_attr->attr.name, "soft_limit"))
443                         new_op->upcall.req.param.op =
444                                 ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT;
445
446                 if (!strcmp(orangefs_attr->attr.name, "reclaim_percentage"))
447                         new_op->upcall.req.param.op =
448                           ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE;
449
450         } else if (!strcmp(kobj_id, CCACHE_KOBJ_ID)) {
451                 if (!strcmp(orangefs_attr->attr.name, "timeout_secs"))
452                         new_op->upcall.req.param.op =
453                                 ORANGEFS_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS;
454
455                 if (!strcmp(orangefs_attr->attr.name, "hard_limit"))
456                         new_op->upcall.req.param.op =
457                                 ORANGEFS_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT;
458
459                 if (!strcmp(orangefs_attr->attr.name, "soft_limit"))
460                         new_op->upcall.req.param.op =
461                                 ORANGEFS_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT;
462
463                 if (!strcmp(orangefs_attr->attr.name, "reclaim_percentage"))
464                         new_op->upcall.req.param.op =
465                           ORANGEFS_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE;
466
467         } else if (!strcmp(kobj_id, NCACHE_KOBJ_ID)) {
468                 if (!strcmp(orangefs_attr->attr.name, "timeout_msecs"))
469                         new_op->upcall.req.param.op =
470                                 ORANGEFS_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS;
471
472                 if (!strcmp(orangefs_attr->attr.name, "hard_limit"))
473                         new_op->upcall.req.param.op =
474                                 ORANGEFS_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT;
475
476                 if (!strcmp(orangefs_attr->attr.name, "soft_limit"))
477                         new_op->upcall.req.param.op =
478                                 ORANGEFS_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT;
479
480                 if (!strcmp(orangefs_attr->attr.name, "reclaim_percentage"))
481                         new_op->upcall.req.param.op =
482                           ORANGEFS_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE;
483
484         } else if (!strcmp(kobj_id, PC_KOBJ_ID)) {
485                 if (!strcmp(orangefs_attr->attr.name, ACACHE_KOBJ_ID))
486                         new_op->upcall.req.perf_count.type =
487                                 ORANGEFS_PERF_COUNT_REQUEST_ACACHE;
488
489                 if (!strcmp(orangefs_attr->attr.name, CAPCACHE_KOBJ_ID))
490                         new_op->upcall.req.perf_count.type =
491                                 ORANGEFS_PERF_COUNT_REQUEST_CAPCACHE;
492
493                 if (!strcmp(orangefs_attr->attr.name, NCACHE_KOBJ_ID))
494                         new_op->upcall.req.perf_count.type =
495                                 ORANGEFS_PERF_COUNT_REQUEST_NCACHE;
496
497         } else {
498                 gossip_err("sysfs_service_op_show: unknown kobj_id:%s:\n",
499                            kobj_id);
500                 rc = -EINVAL;
501                 goto out;
502         }
503
504
505         if (strcmp(kobj_id, PC_KOBJ_ID))
506                 ser_op_type = "orangefs_param";
507         else
508                 ser_op_type = "orangefs_perf_count";
509
510         /*
511          * The service_operation will return an errno return code on
512          * error, and zero on success.
513          */
514         rc = service_operation(new_op, ser_op_type, ORANGEFS_OP_INTERRUPTIBLE);
515
516 out:
517         if (!rc) {
518                 if (strcmp(kobj_id, PC_KOBJ_ID)) {
519                         if (new_op->upcall.req.param.op ==
520                             ORANGEFS_PARAM_REQUEST_OP_READAHEAD_COUNT_SIZE) {
521                                 rc = scnprintf(buf, PAGE_SIZE, "%d %d\n",
522                                     (int)new_op->downcall.resp.param.u.
523                                     value32[0],
524                                     (int)new_op->downcall.resp.param.u.
525                                     value32[1]);
526                         } else {
527                                 rc = scnprintf(buf, PAGE_SIZE, "%d\n",
528                                     (int)new_op->downcall.resp.param.u.value64);
529                         }
530                 } else {
531                         rc = scnprintf(
532                                 buf,
533                                 PAGE_SIZE,
534                                 "%s",
535                                 new_op->downcall.resp.perf_count.buffer);
536                 }
537         }
538
539         op_release(new_op);
540
541         return rc;
542
543 }
544
545 static ssize_t service_orangefs_show(struct orangefs_attribute *attr,
546                                      char *buf)
547 {
548         int rc = 0;
549
550         rc = sysfs_service_op_show(ORANGEFS_KOBJ_ID, buf, (void *)attr);
551
552         return rc;
553 }
554
555 static ssize_t
556         service_acache_show(struct orangefs_attribute *attr,
557                             char *buf)
558 {
559         int rc = 0;
560
561         rc = sysfs_service_op_show(ACACHE_KOBJ_ID, buf, (void *)attr);
562
563         return rc;
564 }
565
566 static ssize_t service_capcache_show(struct orangefs_attribute *attr,
567                                      char *buf)
568 {
569         int rc = 0;
570
571         rc = sysfs_service_op_show(CAPCACHE_KOBJ_ID, buf, (void *)attr);
572
573         return rc;
574 }
575
576 static ssize_t service_ccache_show(struct orangefs_attribute *attr,
577                                    char *buf)
578 {
579         int rc = 0;
580
581         rc = sysfs_service_op_show(CCACHE_KOBJ_ID, buf, (void *)attr);
582
583         return rc;
584 }
585
586 static ssize_t
587         service_ncache_show(struct orangefs_attribute *attr,
588                             char *buf)
589 {
590         int rc = 0;
591
592         rc = sysfs_service_op_show(NCACHE_KOBJ_ID, buf, (void *)attr);
593
594         return rc;
595 }
596
597 static ssize_t
598         service_pc_show(struct orangefs_attribute *attr,
599                             char *buf)
600 {
601         int rc = 0;
602
603         rc = sysfs_service_op_show(PC_KOBJ_ID, buf, (void *)attr);
604
605         return rc;
606 }
607
608 /*
609  * pass attribute values back to userspace with a service operation.
610  *
611  * We have to do a memory allocation, an sscanf and a service operation.
612  * And we have to evaluate what the user entered, to make sure the
613  * value is within the range supported by the attribute. So, there's
614  * a lot of return code checking and mapping going on here.
615  *
616  * We want to return 1 if we think everything went OK, and
617  * EINVAL if not.
618  */
619 static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr)
620 {
621         struct orangefs_kernel_op_s *new_op = NULL;
622         int val = 0;
623         int rc = 0;
624         struct orangefs_attribute *orangefs_attr = attr;
625
626         gossip_debug(GOSSIP_SYSFS_DEBUG,
627                      "sysfs_service_op_store: id:%s:\n",
628                      kobj_id);
629
630         new_op = op_alloc(ORANGEFS_VFS_OP_PARAM);
631         if (!new_op)
632                 return -EINVAL; /* sic */
633
634         /* Can't do a service_operation if the client is not running... */
635         rc = is_daemon_in_service();
636         if (rc) {
637                 pr_info("%s: Client not running :%d:\n",
638                         __func__,
639                         is_daemon_in_service());
640                 goto out;
641         }
642
643         /*
644          * The value we want to send back to userspace is in buf, unless this
645          * there are two parameters, which is specially handled below.
646          */
647         if (strcmp(kobj_id, ORANGEFS_KOBJ_ID) ||
648             strcmp(((struct orangefs_attribute *)attr)->attr.name,
649             "readahead_count_size")) {
650                 rc = kstrtoint(buf, 0, &val);
651                 if (rc)
652                         goto out;
653         }
654
655         new_op->upcall.req.param.type = ORANGEFS_PARAM_REQUEST_SET;
656
657         if (!strcmp(kobj_id, ORANGEFS_KOBJ_ID)) {
658                 if (!strcmp(orangefs_attr->attr.name, "perf_history_size")) {
659                         if (val > 0) {
660                                 new_op->upcall.req.param.op =
661                                   ORANGEFS_PARAM_REQUEST_OP_PERF_HISTORY_SIZE;
662                         } else {
663                                 rc = 0;
664                                 goto out;
665                         }
666                 } else if (!strcmp(orangefs_attr->attr.name,
667                                    "perf_time_interval_secs")) {
668                         if (val > 0) {
669                                 new_op->upcall.req.param.op =
670                                 ORANGEFS_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS;
671                         } else {
672                                 rc = 0;
673                                 goto out;
674                         }
675                 } else if (!strcmp(orangefs_attr->attr.name,
676                                    "perf_counter_reset")) {
677                         if ((val == 0) || (val == 1)) {
678                                 new_op->upcall.req.param.op =
679                                         ORANGEFS_PARAM_REQUEST_OP_PERF_RESET;
680                         } else {
681                                 rc = 0;
682                                 goto out;
683                         }
684                 } else if (!strcmp(orangefs_attr->attr.name,
685                                    "readahead_count")) {
686                         if ((val >= 0)) {
687                                 new_op->upcall.req.param.op =
688                                 ORANGEFS_PARAM_REQUEST_OP_READAHEAD_COUNT;
689                         } else {
690                                 rc = 0;
691                                 goto out;
692                         }
693                 } else if (!strcmp(orangefs_attr->attr.name,
694                                    "readahead_size")) {
695                         if ((val >= 0)) {
696                                 new_op->upcall.req.param.op =
697                                 ORANGEFS_PARAM_REQUEST_OP_READAHEAD_SIZE;
698                         } else {
699                                 rc = 0;
700                                 goto out;
701                         }
702                 } else if (!strcmp(orangefs_attr->attr.name,
703                                    "readahead_count_size")) {
704                         int val1, val2;
705                         rc = sscanf(buf, "%d %d", &val1, &val2);
706                         if (rc < 2) {
707                                 rc = 0;
708                                 goto out;
709                         }
710                         if ((val1 >= 0) && (val2 >= 0)) {
711                                 new_op->upcall.req.param.op =
712                                 ORANGEFS_PARAM_REQUEST_OP_READAHEAD_COUNT_SIZE;
713                         } else {
714                                 rc = 0;
715                                 goto out;
716                         }
717                         new_op->upcall.req.param.u.value32[0] = val1;
718                         new_op->upcall.req.param.u.value32[1] = val2;
719                         goto value_set;
720                 } else if (!strcmp(orangefs_attr->attr.name,
721                                    "perf_counter_reset")) {
722                         if ((val > 0)) {
723                                 new_op->upcall.req.param.op =
724                                 ORANGEFS_PARAM_REQUEST_OP_READAHEAD_COUNT_SIZE;
725                         } else {
726                                 rc = 0;
727                                 goto out;
728                         }
729                 }
730
731         } else if (!strcmp(kobj_id, ACACHE_KOBJ_ID)) {
732                 if (!strcmp(orangefs_attr->attr.name, "hard_limit")) {
733                         if (val > -1) {
734                                 new_op->upcall.req.param.op =
735                                   ORANGEFS_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT;
736                         } else {
737                                 rc = 0;
738                                 goto out;
739                         }
740                 } else if (!strcmp(orangefs_attr->attr.name, "soft_limit")) {
741                         if (val > -1) {
742                                 new_op->upcall.req.param.op =
743                                   ORANGEFS_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT;
744                         } else {
745                                 rc = 0;
746                                 goto out;
747                         }
748                 } else if (!strcmp(orangefs_attr->attr.name,
749                                    "reclaim_percentage")) {
750                         if ((val > -1) && (val < 101)) {
751                                 new_op->upcall.req.param.op =
752                                   ORANGEFS_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE;
753                         } else {
754                                 rc = 0;
755                                 goto out;
756                         }
757                 } else if (!strcmp(orangefs_attr->attr.name, "timeout_msecs")) {
758                         if (val > -1) {
759                                 new_op->upcall.req.param.op =
760                                   ORANGEFS_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS;
761                         } else {
762                                 rc = 0;
763                                 goto out;
764                         }
765                 }
766
767         } else if (!strcmp(kobj_id, CAPCACHE_KOBJ_ID)) {
768                 if (!strcmp(orangefs_attr->attr.name, "hard_limit")) {
769                         if (val > -1) {
770                                 new_op->upcall.req.param.op =
771                                   ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT;
772                         } else {
773                                 rc = 0;
774                                 goto out;
775                         }
776                 } else if (!strcmp(orangefs_attr->attr.name, "soft_limit")) {
777                         if (val > -1) {
778                                 new_op->upcall.req.param.op =
779                                   ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT;
780                         } else {
781                                 rc = 0;
782                                 goto out;
783                         }
784                 } else if (!strcmp(orangefs_attr->attr.name,
785                                    "reclaim_percentage")) {
786                         if ((val > -1) && (val < 101)) {
787                                 new_op->upcall.req.param.op =
788                                   ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE;
789                         } else {
790                                 rc = 0;
791                                 goto out;
792                         }
793                 } else if (!strcmp(orangefs_attr->attr.name, "timeout_secs")) {
794                         if (val > -1) {
795                                 new_op->upcall.req.param.op =
796                                   ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS;
797                         } else {
798                                 rc = 0;
799                                 goto out;
800                         }
801                 }
802
803         } else if (!strcmp(kobj_id, CCACHE_KOBJ_ID)) {
804                 if (!strcmp(orangefs_attr->attr.name, "hard_limit")) {
805                         if (val > -1) {
806                                 new_op->upcall.req.param.op =
807                                   ORANGEFS_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT;
808                         } else {
809                                 rc = 0;
810                                 goto out;
811                         }
812                 } else if (!strcmp(orangefs_attr->attr.name, "soft_limit")) {
813                         if (val > -1) {
814                                 new_op->upcall.req.param.op =
815                                   ORANGEFS_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT;
816                         } else {
817                                 rc = 0;
818                                 goto out;
819                         }
820                 } else if (!strcmp(orangefs_attr->attr.name,
821                                    "reclaim_percentage")) {
822                         if ((val > -1) && (val < 101)) {
823                                 new_op->upcall.req.param.op =
824                                   ORANGEFS_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE;
825                         } else {
826                                 rc = 0;
827                                 goto out;
828                         }
829                 } else if (!strcmp(orangefs_attr->attr.name, "timeout_secs")) {
830                         if (val > -1) {
831                                 new_op->upcall.req.param.op =
832                                   ORANGEFS_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS;
833                         } else {
834                                 rc = 0;
835                                 goto out;
836                         }
837                 }
838
839         } else if (!strcmp(kobj_id, NCACHE_KOBJ_ID)) {
840                 if (!strcmp(orangefs_attr->attr.name, "hard_limit")) {
841                         if (val > -1) {
842                                 new_op->upcall.req.param.op =
843                                   ORANGEFS_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT;
844                         } else {
845                                 rc = 0;
846                                 goto out;
847                         }
848                 } else if (!strcmp(orangefs_attr->attr.name, "soft_limit")) {
849                         if (val > -1) {
850                                 new_op->upcall.req.param.op =
851                                   ORANGEFS_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT;
852                         } else {
853                                 rc = 0;
854                                 goto out;
855                         }
856                 } else if (!strcmp(orangefs_attr->attr.name,
857                                    "reclaim_percentage")) {
858                         if ((val > -1) && (val < 101)) {
859                                 new_op->upcall.req.param.op =
860                                         ORANGEFS_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE;
861                         } else {
862                                 rc = 0;
863                                 goto out;
864                         }
865                 } else if (!strcmp(orangefs_attr->attr.name, "timeout_msecs")) {
866                         if (val > -1) {
867                                 new_op->upcall.req.param.op =
868                                   ORANGEFS_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS;
869                         } else {
870                                 rc = 0;
871                                 goto out;
872                         }
873                 }
874
875         } else {
876                 gossip_err("sysfs_service_op_store: unknown kobj_id:%s:\n",
877                            kobj_id);
878                 rc = -EINVAL;
879                 goto out;
880         }
881
882         new_op->upcall.req.param.u.value64 = val;
883 value_set:
884
885         /*
886          * The service_operation will return a errno return code on
887          * error, and zero on success.
888          */
889         rc = service_operation(new_op, "orangefs_param", ORANGEFS_OP_INTERRUPTIBLE);
890
891         if (rc < 0) {
892                 gossip_err("sysfs_service_op_store: service op returned:%d:\n",
893                         rc);
894                 rc = 0;
895         } else {
896                 rc = 1;
897         }
898
899 out:
900         op_release(new_op);
901
902         if (rc == -ENOMEM || rc == 0)
903                 rc = -EINVAL;
904
905         return rc;
906 }
907
908 static ssize_t
909         service_orangefs_store(struct orangefs_attribute *attr,
910                                const char *buf,
911                                size_t count)
912 {
913         int rc = 0;
914
915         rc = sysfs_service_op_store(ORANGEFS_KOBJ_ID, buf, (void *) attr);
916
917         /* rc should have an errno value if the service_op went bad. */
918         if (rc == 1)
919                 rc = count;
920
921         return rc;
922 }
923
924 static ssize_t
925         service_acache_store(struct orangefs_attribute *attr,
926                              const char *buf,
927                              size_t count)
928 {
929         int rc = 0;
930
931         rc = sysfs_service_op_store(ACACHE_KOBJ_ID, buf, (void *) attr);
932
933         /* rc should have an errno value if the service_op went bad. */
934         if (rc == 1)
935                 rc = count;
936
937         return rc;
938 }
939
940 static ssize_t
941         service_capcache_store(struct orangefs_attribute *attr,
942                                const char *buf,
943                                size_t count)
944 {
945         int rc = 0;
946
947         rc = sysfs_service_op_store(CAPCACHE_KOBJ_ID, buf, (void *) attr);
948
949         /* rc should have an errno value if the service_op went bad. */
950         if (rc == 1)
951                 rc = count;
952
953         return rc;
954 }
955
956 static ssize_t service_ccache_store(struct orangefs_attribute *attr,
957                                     const char *buf,
958                                     size_t count)
959 {
960         int rc = 0;
961
962         rc = sysfs_service_op_store(CCACHE_KOBJ_ID, buf, (void *) attr);
963
964         /* rc should have an errno value if the service_op went bad. */
965         if (rc == 1)
966                 rc = count;
967
968         return rc;
969 }
970
971 static ssize_t
972         service_ncache_store(struct orangefs_attribute *attr,
973                              const char *buf,
974                              size_t count)
975 {
976         int rc = 0;
977
978         rc = sysfs_service_op_store(NCACHE_KOBJ_ID, buf, (void *) attr);
979
980         /* rc should have an errno value if the service_op went bad. */
981         if (rc == 1)
982                 rc = count;
983
984         return rc;
985 }
986
987 static struct orangefs_attribute op_timeout_secs_attribute =
988         __ATTR(op_timeout_secs, 0664, int_orangefs_show, int_store);
989
990 static struct orangefs_attribute slot_timeout_secs_attribute =
991         __ATTR(slot_timeout_secs, 0664, int_orangefs_show, int_store);
992
993 static struct orangefs_attribute dcache_timeout_msecs_attribute =
994         __ATTR(dcache_timeout_msecs, 0664, int_orangefs_show, int_store);
995
996 static struct orangefs_attribute getattr_timeout_msecs_attribute =
997         __ATTR(getattr_timeout_msecs, 0664, int_orangefs_show, int_store);
998
999 static struct orangefs_attribute readahead_count_attribute =
1000         __ATTR(readahead_count, 0664, service_orangefs_show,
1001                service_orangefs_store);
1002
1003 static struct orangefs_attribute readahead_size_attribute =
1004         __ATTR(readahead_size, 0664, service_orangefs_show,
1005                service_orangefs_store);
1006
1007 static struct orangefs_attribute readahead_count_size_attribute =
1008         __ATTR(readahead_count_size, 0664, service_orangefs_show,
1009                service_orangefs_store);
1010
1011 static struct orangefs_attribute perf_counter_reset_attribute =
1012         __ATTR(perf_counter_reset,
1013                0664,
1014                service_orangefs_show,
1015                service_orangefs_store);
1016
1017 static struct orangefs_attribute perf_history_size_attribute =
1018         __ATTR(perf_history_size,
1019                0664,
1020                service_orangefs_show,
1021                service_orangefs_store);
1022
1023 static struct orangefs_attribute perf_time_interval_secs_attribute =
1024         __ATTR(perf_time_interval_secs,
1025                0664,
1026                service_orangefs_show,
1027                service_orangefs_store);
1028
1029 static struct attribute *orangefs_default_attrs[] = {
1030         &op_timeout_secs_attribute.attr,
1031         &slot_timeout_secs_attribute.attr,
1032         &dcache_timeout_msecs_attribute.attr,
1033         &getattr_timeout_msecs_attribute.attr,
1034         &readahead_count_attribute.attr,
1035         &readahead_size_attribute.attr,
1036         &readahead_count_size_attribute.attr,
1037         &perf_counter_reset_attribute.attr,
1038         &perf_history_size_attribute.attr,
1039         &perf_time_interval_secs_attribute.attr,
1040         NULL,
1041 };
1042
1043 static struct kobj_type orangefs_ktype = {
1044         .sysfs_ops = &orangefs_sysfs_ops,
1045         .default_attrs = orangefs_default_attrs,
1046 };
1047
1048 static struct orangefs_attribute acache_hard_limit_attribute =
1049         __ATTR(hard_limit,
1050                0664,
1051                service_acache_show,
1052                service_acache_store);
1053
1054 static struct orangefs_attribute acache_reclaim_percent_attribute =
1055         __ATTR(reclaim_percentage,
1056                0664,
1057                service_acache_show,
1058                service_acache_store);
1059
1060 static struct orangefs_attribute acache_soft_limit_attribute =
1061         __ATTR(soft_limit,
1062                0664,
1063                service_acache_show,
1064                service_acache_store);
1065
1066 static struct orangefs_attribute acache_timeout_msecs_attribute =
1067         __ATTR(timeout_msecs,
1068                0664,
1069                service_acache_show,
1070                service_acache_store);
1071
1072 static struct attribute *acache_orangefs_default_attrs[] = {
1073         &acache_hard_limit_attribute.attr,
1074         &acache_reclaim_percent_attribute.attr,
1075         &acache_soft_limit_attribute.attr,
1076         &acache_timeout_msecs_attribute.attr,
1077         NULL,
1078 };
1079
1080 static struct kobj_type acache_orangefs_ktype = {
1081         .sysfs_ops = &acache_orangefs_sysfs_ops,
1082         .default_attrs = acache_orangefs_default_attrs,
1083 };
1084
1085 static struct orangefs_attribute capcache_hard_limit_attribute =
1086         __ATTR(hard_limit,
1087                0664,
1088                service_capcache_show,
1089                service_capcache_store);
1090
1091 static struct orangefs_attribute capcache_reclaim_percent_attribute =
1092         __ATTR(reclaim_percentage,
1093                0664,
1094                service_capcache_show,
1095                service_capcache_store);
1096
1097 static struct orangefs_attribute capcache_soft_limit_attribute =
1098         __ATTR(soft_limit,
1099                0664,
1100                service_capcache_show,
1101                service_capcache_store);
1102
1103 static struct orangefs_attribute capcache_timeout_secs_attribute =
1104         __ATTR(timeout_secs,
1105                0664,
1106                service_capcache_show,
1107                service_capcache_store);
1108
1109 static struct attribute *capcache_orangefs_default_attrs[] = {
1110         &capcache_hard_limit_attribute.attr,
1111         &capcache_reclaim_percent_attribute.attr,
1112         &capcache_soft_limit_attribute.attr,
1113         &capcache_timeout_secs_attribute.attr,
1114         NULL,
1115 };
1116
1117 static struct kobj_type capcache_orangefs_ktype = {
1118         .sysfs_ops = &capcache_orangefs_sysfs_ops,
1119         .default_attrs = capcache_orangefs_default_attrs,
1120 };
1121
1122 static struct orangefs_attribute ccache_hard_limit_attribute =
1123         __ATTR(hard_limit,
1124                0664,
1125                service_ccache_show,
1126                service_ccache_store);
1127
1128 static struct orangefs_attribute ccache_reclaim_percent_attribute =
1129         __ATTR(reclaim_percentage,
1130                0664,
1131                service_ccache_show,
1132                service_ccache_store);
1133
1134 static struct orangefs_attribute ccache_soft_limit_attribute =
1135         __ATTR(soft_limit,
1136                0664,
1137                service_ccache_show,
1138                service_ccache_store);
1139
1140 static struct orangefs_attribute ccache_timeout_secs_attribute =
1141         __ATTR(timeout_secs,
1142                0664,
1143                service_ccache_show,
1144                service_ccache_store);
1145
1146 static struct attribute *ccache_orangefs_default_attrs[] = {
1147         &ccache_hard_limit_attribute.attr,
1148         &ccache_reclaim_percent_attribute.attr,
1149         &ccache_soft_limit_attribute.attr,
1150         &ccache_timeout_secs_attribute.attr,
1151         NULL,
1152 };
1153
1154 static struct kobj_type ccache_orangefs_ktype = {
1155         .sysfs_ops = &ccache_orangefs_sysfs_ops,
1156         .default_attrs = ccache_orangefs_default_attrs,
1157 };
1158
1159 static struct orangefs_attribute ncache_hard_limit_attribute =
1160         __ATTR(hard_limit,
1161                0664,
1162                service_ncache_show,
1163                service_ncache_store);
1164
1165 static struct orangefs_attribute ncache_reclaim_percent_attribute =
1166         __ATTR(reclaim_percentage,
1167                0664,
1168                service_ncache_show,
1169                service_ncache_store);
1170
1171 static struct orangefs_attribute ncache_soft_limit_attribute =
1172         __ATTR(soft_limit,
1173                0664,
1174                service_ncache_show,
1175                service_ncache_store);
1176
1177 static struct orangefs_attribute ncache_timeout_msecs_attribute =
1178         __ATTR(timeout_msecs,
1179                0664,
1180                service_ncache_show,
1181                service_ncache_store);
1182
1183 static struct attribute *ncache_orangefs_default_attrs[] = {
1184         &ncache_hard_limit_attribute.attr,
1185         &ncache_reclaim_percent_attribute.attr,
1186         &ncache_soft_limit_attribute.attr,
1187         &ncache_timeout_msecs_attribute.attr,
1188         NULL,
1189 };
1190
1191 static struct kobj_type ncache_orangefs_ktype = {
1192         .sysfs_ops = &ncache_orangefs_sysfs_ops,
1193         .default_attrs = ncache_orangefs_default_attrs,
1194 };
1195
1196 static struct orangefs_attribute pc_acache_attribute =
1197         __ATTR(acache,
1198                0664,
1199                service_pc_show,
1200                NULL);
1201
1202 static struct orangefs_attribute pc_capcache_attribute =
1203         __ATTR(capcache,
1204                0664,
1205                service_pc_show,
1206                NULL);
1207
1208 static struct orangefs_attribute pc_ncache_attribute =
1209         __ATTR(ncache,
1210                0664,
1211                service_pc_show,
1212                NULL);
1213
1214 static struct attribute *pc_orangefs_default_attrs[] = {
1215         &pc_acache_attribute.attr,
1216         &pc_capcache_attribute.attr,
1217         &pc_ncache_attribute.attr,
1218         NULL,
1219 };
1220
1221 static struct kobj_type pc_orangefs_ktype = {
1222         .sysfs_ops = &pc_orangefs_sysfs_ops,
1223         .default_attrs = pc_orangefs_default_attrs,
1224 };
1225
1226 static struct orangefs_attribute stats_reads_attribute =
1227         __ATTR(reads,
1228                0664,
1229                int_stats_show,
1230                NULL);
1231
1232 static struct orangefs_attribute stats_writes_attribute =
1233         __ATTR(writes,
1234                0664,
1235                int_stats_show,
1236                NULL);
1237
1238 static struct attribute *stats_orangefs_default_attrs[] = {
1239         &stats_reads_attribute.attr,
1240         &stats_writes_attribute.attr,
1241         NULL,
1242 };
1243
1244 static struct kobj_type stats_orangefs_ktype = {
1245         .sysfs_ops = &stats_orangefs_sysfs_ops,
1246         .default_attrs = stats_orangefs_default_attrs,
1247 };
1248
1249 static struct kobject *orangefs_obj;
1250 static struct kobject *acache_orangefs_obj;
1251 static struct kobject *capcache_orangefs_obj;
1252 static struct kobject *ccache_orangefs_obj;
1253 static struct kobject *ncache_orangefs_obj;
1254 static struct kobject *pc_orangefs_obj;
1255 static struct kobject *stats_orangefs_obj;
1256
1257 int orangefs_sysfs_init(void)
1258 {
1259         int rc = -EINVAL;
1260
1261         gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_init: start\n");
1262
1263         /* create /sys/fs/orangefs. */
1264         orangefs_obj = kzalloc(sizeof(*orangefs_obj), GFP_KERNEL);
1265         if (!orangefs_obj)
1266                 goto out;
1267
1268         rc = kobject_init_and_add(orangefs_obj,
1269                                   &orangefs_ktype,
1270                                   fs_kobj,
1271                                   ORANGEFS_KOBJ_ID);
1272
1273         if (rc)
1274                 goto ofs_obj_bail;
1275
1276         kobject_uevent(orangefs_obj, KOBJ_ADD);
1277
1278         /* create /sys/fs/orangefs/acache. */
1279         acache_orangefs_obj = kzalloc(sizeof(*acache_orangefs_obj), GFP_KERNEL);
1280         if (!acache_orangefs_obj) {
1281                 rc = -EINVAL;
1282                 goto ofs_obj_bail;
1283         }
1284
1285         rc = kobject_init_and_add(acache_orangefs_obj,
1286                                   &acache_orangefs_ktype,
1287                                   orangefs_obj,
1288                                   ACACHE_KOBJ_ID);
1289
1290         if (rc)
1291                 goto acache_obj_bail;
1292
1293         kobject_uevent(acache_orangefs_obj, KOBJ_ADD);
1294
1295         /* create /sys/fs/orangefs/capcache. */
1296         capcache_orangefs_obj =
1297                 kzalloc(sizeof(*capcache_orangefs_obj), GFP_KERNEL);
1298         if (!capcache_orangefs_obj) {
1299                 rc = -EINVAL;
1300                 goto acache_obj_bail;
1301         }
1302
1303         rc = kobject_init_and_add(capcache_orangefs_obj,
1304                                   &capcache_orangefs_ktype,
1305                                   orangefs_obj,
1306                                   CAPCACHE_KOBJ_ID);
1307         if (rc)
1308                 goto capcache_obj_bail;
1309
1310         kobject_uevent(capcache_orangefs_obj, KOBJ_ADD);
1311
1312         /* create /sys/fs/orangefs/ccache. */
1313         ccache_orangefs_obj =
1314                 kzalloc(sizeof(*ccache_orangefs_obj), GFP_KERNEL);
1315         if (!ccache_orangefs_obj) {
1316                 rc = -EINVAL;
1317                 goto capcache_obj_bail;
1318         }
1319
1320         rc = kobject_init_and_add(ccache_orangefs_obj,
1321                                   &ccache_orangefs_ktype,
1322                                   orangefs_obj,
1323                                   CCACHE_KOBJ_ID);
1324         if (rc)
1325                 goto ccache_obj_bail;
1326
1327         kobject_uevent(ccache_orangefs_obj, KOBJ_ADD);
1328
1329         /* create /sys/fs/orangefs/ncache. */
1330         ncache_orangefs_obj = kzalloc(sizeof(*ncache_orangefs_obj), GFP_KERNEL);
1331         if (!ncache_orangefs_obj) {
1332                 rc = -EINVAL;
1333                 goto ccache_obj_bail;
1334         }
1335
1336         rc = kobject_init_and_add(ncache_orangefs_obj,
1337                                   &ncache_orangefs_ktype,
1338                                   orangefs_obj,
1339                                   NCACHE_KOBJ_ID);
1340
1341         if (rc)
1342                 goto ncache_obj_bail;
1343
1344         kobject_uevent(ncache_orangefs_obj, KOBJ_ADD);
1345
1346         /* create /sys/fs/orangefs/perf_counters. */
1347         pc_orangefs_obj = kzalloc(sizeof(*pc_orangefs_obj), GFP_KERNEL);
1348         if (!pc_orangefs_obj) {
1349                 rc = -EINVAL;
1350                 goto ncache_obj_bail;
1351         }
1352
1353         rc = kobject_init_and_add(pc_orangefs_obj,
1354                                   &pc_orangefs_ktype,
1355                                   orangefs_obj,
1356                                   "perf_counters");
1357
1358         if (rc)
1359                 goto pc_obj_bail;
1360
1361         kobject_uevent(pc_orangefs_obj, KOBJ_ADD);
1362
1363         /* create /sys/fs/orangefs/stats. */
1364         stats_orangefs_obj = kzalloc(sizeof(*stats_orangefs_obj), GFP_KERNEL);
1365         if (!stats_orangefs_obj) {
1366                 rc = -EINVAL;
1367                 goto pc_obj_bail;
1368         }
1369
1370         rc = kobject_init_and_add(stats_orangefs_obj,
1371                                   &stats_orangefs_ktype,
1372                                   orangefs_obj,
1373                                   STATS_KOBJ_ID);
1374
1375         if (rc)
1376                 goto stats_obj_bail;
1377
1378         kobject_uevent(stats_orangefs_obj, KOBJ_ADD);
1379         goto out;
1380
1381 stats_obj_bail:
1382                 kobject_put(stats_orangefs_obj);
1383 pc_obj_bail:
1384                 kobject_put(pc_orangefs_obj);
1385 ncache_obj_bail:
1386                 kobject_put(ncache_orangefs_obj);
1387 ccache_obj_bail:
1388                 kobject_put(ccache_orangefs_obj);
1389 capcache_obj_bail:
1390                 kobject_put(capcache_orangefs_obj);
1391 acache_obj_bail:
1392                 kobject_put(acache_orangefs_obj);
1393 ofs_obj_bail:
1394                 kobject_put(orangefs_obj);
1395 out:
1396         return rc;
1397 }
1398
1399 void orangefs_sysfs_exit(void)
1400 {
1401         gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_exit: start\n");
1402         kobject_put(acache_orangefs_obj);
1403         kobject_put(capcache_orangefs_obj);
1404         kobject_put(ccache_orangefs_obj);
1405         kobject_put(ncache_orangefs_obj);
1406         kobject_put(pc_orangefs_obj);
1407         kobject_put(stats_orangefs_obj);
1408         kobject_put(orangefs_obj);
1409 }