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