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