xref: /openbmc/linux/fs/orangefs/orangefs-sysfs.c (revision 110e6f26)
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 
113 struct 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 
122 struct 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 
130 struct 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 
138 struct 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 
146 struct 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 
154 struct pc_orangefs_obj {
155 	struct kobject kobj;
156 	char *acache;
157 	char *capcache;
158 	char *ncache;
159 };
160 
161 struct stats_orangefs_obj {
162 	struct kobject kobj;
163 	int reads;
164 	int writes;
165 };
166 
167 struct 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 
178 struct 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 
189 struct 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 
200 struct 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 
211 struct 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 
222 struct 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 
233 struct 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 
244 static 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 
262 out:
263 	return rc;
264 }
265 
266 static 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 
288 out:
289 	return rc;
290 }
291 
292 static const struct sysfs_ops orangefs_sysfs_ops = {
293 	.show = orangefs_attr_show,
294 	.store = orangefs_attr_store,
295 };
296 
297 static 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 
316 out:
317 	return rc;
318 }
319 
320 static 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 
343 out:
344 	return rc;
345 }
346 
347 static const struct sysfs_ops acache_orangefs_sysfs_ops = {
348 	.show = acache_orangefs_attr_show,
349 	.store = acache_orangefs_attr_store,
350 };
351 
352 static 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 
372 out:
373 	return rc;
374 }
375 
376 static 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 
400 out:
401 	return rc;
402 }
403 
404 static const struct sysfs_ops capcache_orangefs_sysfs_ops = {
405 	.show = capcache_orangefs_attr_show,
406 	.store = capcache_orangefs_attr_store,
407 };
408 
409 static 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 
429 out:
430 	return rc;
431 }
432 
433 static 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 
457 out:
458 	return rc;
459 }
460 
461 static const struct sysfs_ops ccache_orangefs_sysfs_ops = {
462 	.show = ccache_orangefs_attr_show,
463 	.store = ccache_orangefs_attr_store,
464 };
465 
466 static 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 
485 out:
486 	return rc;
487 }
488 
489 static 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 
512 out:
513 	return rc;
514 }
515 
516 static const struct sysfs_ops ncache_orangefs_sysfs_ops = {
517 	.show = ncache_orangefs_attr_show,
518 	.store = ncache_orangefs_attr_store,
519 };
520 
521 static 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 
540 out:
541 	return rc;
542 }
543 
544 static const struct sysfs_ops pc_orangefs_sysfs_ops = {
545 	.show = pc_orangefs_attr_show,
546 };
547 
548 static 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 
567 out:
568 	return rc;
569 }
570 
571 static const struct sysfs_ops stats_orangefs_sysfs_ops = {
572 	.show = stats_orangefs_attr_show,
573 };
574 
575 static 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 
583 static 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 
592 static 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 
601 static 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 
610 static 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 
619 static 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 
628 static 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 
637 static 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 
685 out:
686 
687 	return rc;
688 }
689 
690 static 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 
705 static 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 
720 static 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 
741 out:
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  */
753 static 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 
916 out:
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 
938 static 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 
949 static 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 
961 static 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 
973 static 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 
985 static 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 
997 static 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  */
1020 static 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 
1263 out:
1264 	op_release(new_op);
1265 
1266 	if (rc == -ENOMEM || rc == 0)
1267 		rc = -EINVAL;
1268 
1269 	return rc;
1270 }
1271 
1272 static 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 
1289 static 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 
1306 static 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 
1324 static 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 
1341 static 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 
1358 static struct orangefs_attribute op_timeout_secs_attribute =
1359 	__ATTR(op_timeout_secs, 0664, int_orangefs_show, int_store);
1360 
1361 static struct orangefs_attribute slot_timeout_secs_attribute =
1362 	__ATTR(slot_timeout_secs, 0664, int_orangefs_show, int_store);
1363 
1364 static struct orangefs_attribute perf_counter_reset_attribute =
1365 	__ATTR(perf_counter_reset,
1366 	       0664,
1367 	       service_orangefs_show,
1368 	       service_orangefs_store);
1369 
1370 static struct orangefs_attribute perf_history_size_attribute =
1371 	__ATTR(perf_history_size,
1372 	       0664,
1373 	       service_orangefs_show,
1374 	       service_orangefs_store);
1375 
1376 static 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 
1382 static 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 
1391 static struct kobj_type orangefs_ktype = {
1392 	.sysfs_ops = &orangefs_sysfs_ops,
1393 	.release = orangefs_release,
1394 	.default_attrs = orangefs_default_attrs,
1395 };
1396 
1397 static struct acache_orangefs_attribute acache_hard_limit_attribute =
1398 	__ATTR(hard_limit,
1399 	       0664,
1400 	       service_acache_show,
1401 	       service_acache_store);
1402 
1403 static struct acache_orangefs_attribute acache_reclaim_percent_attribute =
1404 	__ATTR(reclaim_percentage,
1405 	       0664,
1406 	       service_acache_show,
1407 	       service_acache_store);
1408 
1409 static struct acache_orangefs_attribute acache_soft_limit_attribute =
1410 	__ATTR(soft_limit,
1411 	       0664,
1412 	       service_acache_show,
1413 	       service_acache_store);
1414 
1415 static struct acache_orangefs_attribute acache_timeout_msecs_attribute =
1416 	__ATTR(timeout_msecs,
1417 	       0664,
1418 	       service_acache_show,
1419 	       service_acache_store);
1420 
1421 static 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 
1429 static 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 
1435 static struct capcache_orangefs_attribute capcache_hard_limit_attribute =
1436 	__ATTR(hard_limit,
1437 	       0664,
1438 	       service_capcache_show,
1439 	       service_capcache_store);
1440 
1441 static struct capcache_orangefs_attribute capcache_reclaim_percent_attribute =
1442 	__ATTR(reclaim_percentage,
1443 	       0664,
1444 	       service_capcache_show,
1445 	       service_capcache_store);
1446 
1447 static struct capcache_orangefs_attribute capcache_soft_limit_attribute =
1448 	__ATTR(soft_limit,
1449 	       0664,
1450 	       service_capcache_show,
1451 	       service_capcache_store);
1452 
1453 static struct capcache_orangefs_attribute capcache_timeout_secs_attribute =
1454 	__ATTR(timeout_secs,
1455 	       0664,
1456 	       service_capcache_show,
1457 	       service_capcache_store);
1458 
1459 static 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 
1467 static 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 
1473 static struct ccache_orangefs_attribute ccache_hard_limit_attribute =
1474 	__ATTR(hard_limit,
1475 	       0664,
1476 	       service_ccache_show,
1477 	       service_ccache_store);
1478 
1479 static struct ccache_orangefs_attribute ccache_reclaim_percent_attribute =
1480 	__ATTR(reclaim_percentage,
1481 	       0664,
1482 	       service_ccache_show,
1483 	       service_ccache_store);
1484 
1485 static struct ccache_orangefs_attribute ccache_soft_limit_attribute =
1486 	__ATTR(soft_limit,
1487 	       0664,
1488 	       service_ccache_show,
1489 	       service_ccache_store);
1490 
1491 static struct ccache_orangefs_attribute ccache_timeout_secs_attribute =
1492 	__ATTR(timeout_secs,
1493 	       0664,
1494 	       service_ccache_show,
1495 	       service_ccache_store);
1496 
1497 static 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 
1505 static 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 
1511 static struct ncache_orangefs_attribute ncache_hard_limit_attribute =
1512 	__ATTR(hard_limit,
1513 	       0664,
1514 	       service_ncache_show,
1515 	       service_ncache_store);
1516 
1517 static struct ncache_orangefs_attribute ncache_reclaim_percent_attribute =
1518 	__ATTR(reclaim_percentage,
1519 	       0664,
1520 	       service_ncache_show,
1521 	       service_ncache_store);
1522 
1523 static struct ncache_orangefs_attribute ncache_soft_limit_attribute =
1524 	__ATTR(soft_limit,
1525 	       0664,
1526 	       service_ncache_show,
1527 	       service_ncache_store);
1528 
1529 static struct ncache_orangefs_attribute ncache_timeout_msecs_attribute =
1530 	__ATTR(timeout_msecs,
1531 	       0664,
1532 	       service_ncache_show,
1533 	       service_ncache_store);
1534 
1535 static 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 
1543 static 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 
1549 static struct pc_orangefs_attribute pc_acache_attribute =
1550 	__ATTR(acache,
1551 	       0664,
1552 	       service_pc_show,
1553 	       NULL);
1554 
1555 static struct pc_orangefs_attribute pc_capcache_attribute =
1556 	__ATTR(capcache,
1557 	       0664,
1558 	       service_pc_show,
1559 	       NULL);
1560 
1561 static struct pc_orangefs_attribute pc_ncache_attribute =
1562 	__ATTR(ncache,
1563 	       0664,
1564 	       service_pc_show,
1565 	       NULL);
1566 
1567 static 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 
1574 static 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 
1580 static struct stats_orangefs_attribute stats_reads_attribute =
1581 	__ATTR(reads,
1582 	       0664,
1583 	       int_stats_show,
1584 	       NULL);
1585 
1586 static struct stats_orangefs_attribute stats_writes_attribute =
1587 	__ATTR(writes,
1588 	       0664,
1589 	       int_stats_show,
1590 	       NULL);
1591 
1592 static struct attribute *stats_orangefs_default_attrs[] = {
1593 	&stats_reads_attribute.attr,
1594 	&stats_writes_attribute.attr,
1595 	NULL,
1596 };
1597 
1598 static 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 
1604 static struct orangefs_obj *orangefs_obj;
1605 static struct acache_orangefs_obj *acache_orangefs_obj;
1606 static struct capcache_orangefs_obj *capcache_orangefs_obj;
1607 static struct ccache_orangefs_obj *ccache_orangefs_obj;
1608 static struct ncache_orangefs_obj *ncache_orangefs_obj;
1609 static struct pc_orangefs_obj *pc_orangefs_obj;
1610 static struct stats_orangefs_obj *stats_orangefs_obj;
1611 
1612 int 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 
1736 stats_obj_bail:
1737 		kobject_put(&stats_orangefs_obj->kobj);
1738 
1739 pc_obj_bail:
1740 		kobject_put(&pc_orangefs_obj->kobj);
1741 
1742 ncache_obj_bail:
1743 		kobject_put(&ncache_orangefs_obj->kobj);
1744 
1745 ccache_obj_bail:
1746 		kobject_put(&ccache_orangefs_obj->kobj);
1747 
1748 capcache_obj_bail:
1749 		kobject_put(&capcache_orangefs_obj->kobj);
1750 
1751 acache_obj_bail:
1752 		kobject_put(&acache_orangefs_obj->kobj);
1753 
1754 ofs_obj_bail:
1755 		kobject_put(&orangefs_obj->kobj);
1756 out:
1757 	return rc;
1758 }
1759 
1760 void 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 }
1773