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