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