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