xref: /openbmc/linux/fs/orangefs/orangefs-sysfs.c (revision 8dda2eac)
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 
898 static struct kobj_type orangefs_ktype = {
899 	.sysfs_ops = &orangefs_sysfs_ops,
900 	.default_attrs = orangefs_default_attrs,
901 };
902 
903 static struct orangefs_attribute acache_hard_limit_attribute =
904 	__ATTR(hard_limit,
905 	       0664,
906 	       sysfs_service_op_show,
907 	       sysfs_service_op_store);
908 
909 static struct orangefs_attribute acache_reclaim_percent_attribute =
910 	__ATTR(reclaim_percentage,
911 	       0664,
912 	       sysfs_service_op_show,
913 	       sysfs_service_op_store);
914 
915 static struct orangefs_attribute acache_soft_limit_attribute =
916 	__ATTR(soft_limit,
917 	       0664,
918 	       sysfs_service_op_show,
919 	       sysfs_service_op_store);
920 
921 static struct orangefs_attribute acache_timeout_msecs_attribute =
922 	__ATTR(timeout_msecs,
923 	       0664,
924 	       sysfs_service_op_show,
925 	       sysfs_service_op_store);
926 
927 static struct attribute *acache_orangefs_default_attrs[] = {
928 	&acache_hard_limit_attribute.attr,
929 	&acache_reclaim_percent_attribute.attr,
930 	&acache_soft_limit_attribute.attr,
931 	&acache_timeout_msecs_attribute.attr,
932 	NULL,
933 };
934 
935 static struct kobj_type acache_orangefs_ktype = {
936 	.sysfs_ops = &orangefs_sysfs_ops,
937 	.default_attrs = acache_orangefs_default_attrs,
938 };
939 
940 static struct orangefs_attribute capcache_hard_limit_attribute =
941 	__ATTR(hard_limit,
942 	       0664,
943 	       sysfs_service_op_show,
944 	       sysfs_service_op_store);
945 
946 static struct orangefs_attribute capcache_reclaim_percent_attribute =
947 	__ATTR(reclaim_percentage,
948 	       0664,
949 	       sysfs_service_op_show,
950 	       sysfs_service_op_store);
951 
952 static struct orangefs_attribute capcache_soft_limit_attribute =
953 	__ATTR(soft_limit,
954 	       0664,
955 	       sysfs_service_op_show,
956 	       sysfs_service_op_store);
957 
958 static struct orangefs_attribute capcache_timeout_secs_attribute =
959 	__ATTR(timeout_secs,
960 	       0664,
961 	       sysfs_service_op_show,
962 	       sysfs_service_op_store);
963 
964 static struct attribute *capcache_orangefs_default_attrs[] = {
965 	&capcache_hard_limit_attribute.attr,
966 	&capcache_reclaim_percent_attribute.attr,
967 	&capcache_soft_limit_attribute.attr,
968 	&capcache_timeout_secs_attribute.attr,
969 	NULL,
970 };
971 
972 static struct kobj_type capcache_orangefs_ktype = {
973 	.sysfs_ops = &orangefs_sysfs_ops,
974 	.default_attrs = capcache_orangefs_default_attrs,
975 };
976 
977 static struct orangefs_attribute ccache_hard_limit_attribute =
978 	__ATTR(hard_limit,
979 	       0664,
980 	       sysfs_service_op_show,
981 	       sysfs_service_op_store);
982 
983 static struct orangefs_attribute ccache_reclaim_percent_attribute =
984 	__ATTR(reclaim_percentage,
985 	       0664,
986 	       sysfs_service_op_show,
987 	       sysfs_service_op_store);
988 
989 static struct orangefs_attribute ccache_soft_limit_attribute =
990 	__ATTR(soft_limit,
991 	       0664,
992 	       sysfs_service_op_show,
993 	       sysfs_service_op_store);
994 
995 static struct orangefs_attribute ccache_timeout_secs_attribute =
996 	__ATTR(timeout_secs,
997 	       0664,
998 	       sysfs_service_op_show,
999 	       sysfs_service_op_store);
1000 
1001 static struct attribute *ccache_orangefs_default_attrs[] = {
1002 	&ccache_hard_limit_attribute.attr,
1003 	&ccache_reclaim_percent_attribute.attr,
1004 	&ccache_soft_limit_attribute.attr,
1005 	&ccache_timeout_secs_attribute.attr,
1006 	NULL,
1007 };
1008 
1009 static struct kobj_type ccache_orangefs_ktype = {
1010 	.sysfs_ops = &orangefs_sysfs_ops,
1011 	.default_attrs = ccache_orangefs_default_attrs,
1012 };
1013 
1014 static struct orangefs_attribute ncache_hard_limit_attribute =
1015 	__ATTR(hard_limit,
1016 	       0664,
1017 	       sysfs_service_op_show,
1018 	       sysfs_service_op_store);
1019 
1020 static struct orangefs_attribute ncache_reclaim_percent_attribute =
1021 	__ATTR(reclaim_percentage,
1022 	       0664,
1023 	       sysfs_service_op_show,
1024 	       sysfs_service_op_store);
1025 
1026 static struct orangefs_attribute ncache_soft_limit_attribute =
1027 	__ATTR(soft_limit,
1028 	       0664,
1029 	       sysfs_service_op_show,
1030 	       sysfs_service_op_store);
1031 
1032 static struct orangefs_attribute ncache_timeout_msecs_attribute =
1033 	__ATTR(timeout_msecs,
1034 	       0664,
1035 	       sysfs_service_op_show,
1036 	       sysfs_service_op_store);
1037 
1038 static struct attribute *ncache_orangefs_default_attrs[] = {
1039 	&ncache_hard_limit_attribute.attr,
1040 	&ncache_reclaim_percent_attribute.attr,
1041 	&ncache_soft_limit_attribute.attr,
1042 	&ncache_timeout_msecs_attribute.attr,
1043 	NULL,
1044 };
1045 
1046 static struct kobj_type ncache_orangefs_ktype = {
1047 	.sysfs_ops = &orangefs_sysfs_ops,
1048 	.default_attrs = ncache_orangefs_default_attrs,
1049 };
1050 
1051 static struct orangefs_attribute pc_acache_attribute =
1052 	__ATTR(acache,
1053 	       0664,
1054 	       sysfs_service_op_show,
1055 	       NULL);
1056 
1057 static struct orangefs_attribute pc_capcache_attribute =
1058 	__ATTR(capcache,
1059 	       0664,
1060 	       sysfs_service_op_show,
1061 	       NULL);
1062 
1063 static struct orangefs_attribute pc_ncache_attribute =
1064 	__ATTR(ncache,
1065 	       0664,
1066 	       sysfs_service_op_show,
1067 	       NULL);
1068 
1069 static struct attribute *pc_orangefs_default_attrs[] = {
1070 	&pc_acache_attribute.attr,
1071 	&pc_capcache_attribute.attr,
1072 	&pc_ncache_attribute.attr,
1073 	NULL,
1074 };
1075 
1076 static struct kobj_type pc_orangefs_ktype = {
1077 	.sysfs_ops = &orangefs_sysfs_ops,
1078 	.default_attrs = pc_orangefs_default_attrs,
1079 };
1080 
1081 static struct orangefs_attribute stats_reads_attribute =
1082 	__ATTR(reads,
1083 	       0664,
1084 	       sysfs_int_show,
1085 	       NULL);
1086 
1087 static struct orangefs_attribute stats_writes_attribute =
1088 	__ATTR(writes,
1089 	       0664,
1090 	       sysfs_int_show,
1091 	       NULL);
1092 
1093 static struct attribute *stats_orangefs_default_attrs[] = {
1094 	&stats_reads_attribute.attr,
1095 	&stats_writes_attribute.attr,
1096 	NULL,
1097 };
1098 
1099 static struct kobj_type stats_orangefs_ktype = {
1100 	.sysfs_ops = &orangefs_sysfs_ops,
1101 	.default_attrs = stats_orangefs_default_attrs,
1102 };
1103 
1104 static struct kobject *orangefs_obj;
1105 static struct kobject *acache_orangefs_obj;
1106 static struct kobject *capcache_orangefs_obj;
1107 static struct kobject *ccache_orangefs_obj;
1108 static struct kobject *ncache_orangefs_obj;
1109 static struct kobject *pc_orangefs_obj;
1110 static struct kobject *stats_orangefs_obj;
1111 
1112 int orangefs_sysfs_init(void)
1113 {
1114 	int rc = -EINVAL;
1115 
1116 	gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_init: start\n");
1117 
1118 	/* create /sys/fs/orangefs. */
1119 	orangefs_obj = kzalloc(sizeof(*orangefs_obj), GFP_KERNEL);
1120 	if (!orangefs_obj)
1121 		goto out;
1122 
1123 	rc = kobject_init_and_add(orangefs_obj,
1124 				  &orangefs_ktype,
1125 				  fs_kobj,
1126 				  ORANGEFS_KOBJ_ID);
1127 
1128 	if (rc)
1129 		goto ofs_obj_bail;
1130 
1131 	kobject_uevent(orangefs_obj, KOBJ_ADD);
1132 
1133 	/* create /sys/fs/orangefs/acache. */
1134 	acache_orangefs_obj = kzalloc(sizeof(*acache_orangefs_obj), GFP_KERNEL);
1135 	if (!acache_orangefs_obj) {
1136 		rc = -EINVAL;
1137 		goto ofs_obj_bail;
1138 	}
1139 
1140 	rc = kobject_init_and_add(acache_orangefs_obj,
1141 				  &acache_orangefs_ktype,
1142 				  orangefs_obj,
1143 				  ACACHE_KOBJ_ID);
1144 
1145 	if (rc)
1146 		goto acache_obj_bail;
1147 
1148 	kobject_uevent(acache_orangefs_obj, KOBJ_ADD);
1149 
1150 	/* create /sys/fs/orangefs/capcache. */
1151 	capcache_orangefs_obj =
1152 		kzalloc(sizeof(*capcache_orangefs_obj), GFP_KERNEL);
1153 	if (!capcache_orangefs_obj) {
1154 		rc = -EINVAL;
1155 		goto acache_obj_bail;
1156 	}
1157 
1158 	rc = kobject_init_and_add(capcache_orangefs_obj,
1159 				  &capcache_orangefs_ktype,
1160 				  orangefs_obj,
1161 				  CAPCACHE_KOBJ_ID);
1162 	if (rc)
1163 		goto capcache_obj_bail;
1164 
1165 	kobject_uevent(capcache_orangefs_obj, KOBJ_ADD);
1166 
1167 	/* create /sys/fs/orangefs/ccache. */
1168 	ccache_orangefs_obj =
1169 		kzalloc(sizeof(*ccache_orangefs_obj), GFP_KERNEL);
1170 	if (!ccache_orangefs_obj) {
1171 		rc = -EINVAL;
1172 		goto capcache_obj_bail;
1173 	}
1174 
1175 	rc = kobject_init_and_add(ccache_orangefs_obj,
1176 				  &ccache_orangefs_ktype,
1177 				  orangefs_obj,
1178 				  CCACHE_KOBJ_ID);
1179 	if (rc)
1180 		goto ccache_obj_bail;
1181 
1182 	kobject_uevent(ccache_orangefs_obj, KOBJ_ADD);
1183 
1184 	/* create /sys/fs/orangefs/ncache. */
1185 	ncache_orangefs_obj = kzalloc(sizeof(*ncache_orangefs_obj), GFP_KERNEL);
1186 	if (!ncache_orangefs_obj) {
1187 		rc = -EINVAL;
1188 		goto ccache_obj_bail;
1189 	}
1190 
1191 	rc = kobject_init_and_add(ncache_orangefs_obj,
1192 				  &ncache_orangefs_ktype,
1193 				  orangefs_obj,
1194 				  NCACHE_KOBJ_ID);
1195 
1196 	if (rc)
1197 		goto ncache_obj_bail;
1198 
1199 	kobject_uevent(ncache_orangefs_obj, KOBJ_ADD);
1200 
1201 	/* create /sys/fs/orangefs/perf_counters. */
1202 	pc_orangefs_obj = kzalloc(sizeof(*pc_orangefs_obj), GFP_KERNEL);
1203 	if (!pc_orangefs_obj) {
1204 		rc = -EINVAL;
1205 		goto ncache_obj_bail;
1206 	}
1207 
1208 	rc = kobject_init_and_add(pc_orangefs_obj,
1209 				  &pc_orangefs_ktype,
1210 				  orangefs_obj,
1211 				  "perf_counters");
1212 
1213 	if (rc)
1214 		goto pc_obj_bail;
1215 
1216 	kobject_uevent(pc_orangefs_obj, KOBJ_ADD);
1217 
1218 	/* create /sys/fs/orangefs/stats. */
1219 	stats_orangefs_obj = kzalloc(sizeof(*stats_orangefs_obj), GFP_KERNEL);
1220 	if (!stats_orangefs_obj) {
1221 		rc = -EINVAL;
1222 		goto pc_obj_bail;
1223 	}
1224 
1225 	rc = kobject_init_and_add(stats_orangefs_obj,
1226 				  &stats_orangefs_ktype,
1227 				  orangefs_obj,
1228 				  STATS_KOBJ_ID);
1229 
1230 	if (rc)
1231 		goto stats_obj_bail;
1232 
1233 	kobject_uevent(stats_orangefs_obj, KOBJ_ADD);
1234 	goto out;
1235 
1236 stats_obj_bail:
1237 		kobject_put(stats_orangefs_obj);
1238 pc_obj_bail:
1239 		kobject_put(pc_orangefs_obj);
1240 ncache_obj_bail:
1241 		kobject_put(ncache_orangefs_obj);
1242 ccache_obj_bail:
1243 		kobject_put(ccache_orangefs_obj);
1244 capcache_obj_bail:
1245 		kobject_put(capcache_orangefs_obj);
1246 acache_obj_bail:
1247 		kobject_put(acache_orangefs_obj);
1248 ofs_obj_bail:
1249 		kobject_put(orangefs_obj);
1250 out:
1251 	return rc;
1252 }
1253 
1254 void orangefs_sysfs_exit(void)
1255 {
1256 	gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_exit: start\n");
1257 	kobject_put(acache_orangefs_obj);
1258 	kobject_put(capcache_orangefs_obj);
1259 	kobject_put(ccache_orangefs_obj);
1260 	kobject_put(ncache_orangefs_obj);
1261 	kobject_put(pc_orangefs_obj);
1262 	kobject_put(stats_orangefs_obj);
1263 	kobject_put(orangefs_obj);
1264 }
1265