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