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
165struct 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
176static 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
188static 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
205static const struct sysfs_ops orangefs_sysfs_ops = {
206	.show = orangefs_attr_show,
207	.store = orangefs_attr_store,
208};
209
210static 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
275out:
276
277	return rc;
278}
279
280static 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
308out:
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 */
320static 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
495out:
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 */
535static 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;
808value_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
824out:
825	op_release(new_op);
826
827	if (rc == -ENOMEM || rc == 0)
828		rc = -EINVAL;
829
830	return rc;
831}
832
833static struct orangefs_attribute op_timeout_secs_attribute =
834	__ATTR(op_timeout_secs, 0664, sysfs_int_show, sysfs_int_store);
835
836static struct orangefs_attribute slot_timeout_secs_attribute =
837	__ATTR(slot_timeout_secs, 0664, sysfs_int_show, sysfs_int_store);
838
839static struct orangefs_attribute cache_timeout_msecs_attribute =
840	__ATTR(cache_timeout_msecs, 0664, sysfs_int_show, sysfs_int_store);
841
842static struct orangefs_attribute dcache_timeout_msecs_attribute =
843	__ATTR(dcache_timeout_msecs, 0664, sysfs_int_show, sysfs_int_store);
844
845static struct orangefs_attribute getattr_timeout_msecs_attribute =
846	__ATTR(getattr_timeout_msecs, 0664, sysfs_int_show, sysfs_int_store);
847
848static struct orangefs_attribute readahead_count_attribute =
849	__ATTR(readahead_count, 0664, sysfs_service_op_show,
850	       sysfs_service_op_store);
851
852static struct orangefs_attribute readahead_size_attribute =
853	__ATTR(readahead_size, 0664, sysfs_service_op_show,
854	       sysfs_service_op_store);
855
856static struct orangefs_attribute readahead_count_size_attribute =
857	__ATTR(readahead_count_size, 0664, sysfs_service_op_show,
858	       sysfs_service_op_store);
859
860static struct orangefs_attribute readahead_readcnt_attribute =
861	__ATTR(readahead_readcnt, 0664, sysfs_service_op_show,
862	       sysfs_service_op_store);
863
864static 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
870static 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
876static 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
882static 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};
897ATTRIBUTE_GROUPS(orangefs_default);
898
899static struct kobject *orangefs_obj;
900
901static void orangefs_obj_release(struct kobject *kobj)
902{
903	kfree(orangefs_obj);
904	orangefs_obj = NULL;
905}
906
907static struct kobj_type orangefs_ktype = {
908	.sysfs_ops = &orangefs_sysfs_ops,
909	.default_groups = orangefs_default_groups,
910	.release = orangefs_obj_release,
911};
912
913static struct orangefs_attribute acache_hard_limit_attribute =
914	__ATTR(hard_limit,
915	       0664,
916	       sysfs_service_op_show,
917	       sysfs_service_op_store);
918
919static struct orangefs_attribute acache_reclaim_percent_attribute =
920	__ATTR(reclaim_percentage,
921	       0664,
922	       sysfs_service_op_show,
923	       sysfs_service_op_store);
924
925static struct orangefs_attribute acache_soft_limit_attribute =
926	__ATTR(soft_limit,
927	       0664,
928	       sysfs_service_op_show,
929	       sysfs_service_op_store);
930
931static struct orangefs_attribute acache_timeout_msecs_attribute =
932	__ATTR(timeout_msecs,
933	       0664,
934	       sysfs_service_op_show,
935	       sysfs_service_op_store);
936
937static 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};
944ATTRIBUTE_GROUPS(acache_orangefs_default);
945
946static struct kobject *acache_orangefs_obj;
947
948static void acache_orangefs_obj_release(struct kobject *kobj)
949{
950	kfree(acache_orangefs_obj);
951	acache_orangefs_obj = NULL;
952}
953
954static 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
960static struct orangefs_attribute capcache_hard_limit_attribute =
961	__ATTR(hard_limit,
962	       0664,
963	       sysfs_service_op_show,
964	       sysfs_service_op_store);
965
966static struct orangefs_attribute capcache_reclaim_percent_attribute =
967	__ATTR(reclaim_percentage,
968	       0664,
969	       sysfs_service_op_show,
970	       sysfs_service_op_store);
971
972static struct orangefs_attribute capcache_soft_limit_attribute =
973	__ATTR(soft_limit,
974	       0664,
975	       sysfs_service_op_show,
976	       sysfs_service_op_store);
977
978static struct orangefs_attribute capcache_timeout_secs_attribute =
979	__ATTR(timeout_secs,
980	       0664,
981	       sysfs_service_op_show,
982	       sysfs_service_op_store);
983
984static 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};
991ATTRIBUTE_GROUPS(capcache_orangefs_default);
992
993static struct kobject *capcache_orangefs_obj;
994
995static void capcache_orangefs_obj_release(struct kobject *kobj)
996{
997	kfree(capcache_orangefs_obj);
998	capcache_orangefs_obj = NULL;
999}
1000
1001static 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
1007static struct orangefs_attribute ccache_hard_limit_attribute =
1008	__ATTR(hard_limit,
1009	       0664,
1010	       sysfs_service_op_show,
1011	       sysfs_service_op_store);
1012
1013static struct orangefs_attribute ccache_reclaim_percent_attribute =
1014	__ATTR(reclaim_percentage,
1015	       0664,
1016	       sysfs_service_op_show,
1017	       sysfs_service_op_store);
1018
1019static struct orangefs_attribute ccache_soft_limit_attribute =
1020	__ATTR(soft_limit,
1021	       0664,
1022	       sysfs_service_op_show,
1023	       sysfs_service_op_store);
1024
1025static struct orangefs_attribute ccache_timeout_secs_attribute =
1026	__ATTR(timeout_secs,
1027	       0664,
1028	       sysfs_service_op_show,
1029	       sysfs_service_op_store);
1030
1031static 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};
1038ATTRIBUTE_GROUPS(ccache_orangefs_default);
1039
1040static struct kobject *ccache_orangefs_obj;
1041
1042static void ccache_orangefs_obj_release(struct kobject *kobj)
1043{
1044	kfree(ccache_orangefs_obj);
1045	ccache_orangefs_obj = NULL;
1046}
1047
1048static 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
1054static struct orangefs_attribute ncache_hard_limit_attribute =
1055	__ATTR(hard_limit,
1056	       0664,
1057	       sysfs_service_op_show,
1058	       sysfs_service_op_store);
1059
1060static struct orangefs_attribute ncache_reclaim_percent_attribute =
1061	__ATTR(reclaim_percentage,
1062	       0664,
1063	       sysfs_service_op_show,
1064	       sysfs_service_op_store);
1065
1066static struct orangefs_attribute ncache_soft_limit_attribute =
1067	__ATTR(soft_limit,
1068	       0664,
1069	       sysfs_service_op_show,
1070	       sysfs_service_op_store);
1071
1072static struct orangefs_attribute ncache_timeout_msecs_attribute =
1073	__ATTR(timeout_msecs,
1074	       0664,
1075	       sysfs_service_op_show,
1076	       sysfs_service_op_store);
1077
1078static 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};
1085ATTRIBUTE_GROUPS(ncache_orangefs_default);
1086
1087static struct kobject *ncache_orangefs_obj;
1088
1089static void ncache_orangefs_obj_release(struct kobject *kobj)
1090{
1091	kfree(ncache_orangefs_obj);
1092	ncache_orangefs_obj = NULL;
1093}
1094
1095static 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
1101static struct orangefs_attribute pc_acache_attribute =
1102	__ATTR(acache,
1103	       0664,
1104	       sysfs_service_op_show,
1105	       NULL);
1106
1107static struct orangefs_attribute pc_capcache_attribute =
1108	__ATTR(capcache,
1109	       0664,
1110	       sysfs_service_op_show,
1111	       NULL);
1112
1113static struct orangefs_attribute pc_ncache_attribute =
1114	__ATTR(ncache,
1115	       0664,
1116	       sysfs_service_op_show,
1117	       NULL);
1118
1119static struct attribute *pc_orangefs_default_attrs[] = {
1120	&pc_acache_attribute.attr,
1121	&pc_capcache_attribute.attr,
1122	&pc_ncache_attribute.attr,
1123	NULL,
1124};
1125ATTRIBUTE_GROUPS(pc_orangefs_default);
1126
1127static struct kobject *pc_orangefs_obj;
1128
1129static void pc_orangefs_obj_release(struct kobject *kobj)
1130{
1131	kfree(pc_orangefs_obj);
1132	pc_orangefs_obj = NULL;
1133}
1134
1135static 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
1141static struct orangefs_attribute stats_reads_attribute =
1142	__ATTR(reads,
1143	       0664,
1144	       sysfs_int_show,
1145	       NULL);
1146
1147static struct orangefs_attribute stats_writes_attribute =
1148	__ATTR(writes,
1149	       0664,
1150	       sysfs_int_show,
1151	       NULL);
1152
1153static struct attribute *stats_orangefs_default_attrs[] = {
1154	&stats_reads_attribute.attr,
1155	&stats_writes_attribute.attr,
1156	NULL,
1157};
1158ATTRIBUTE_GROUPS(stats_orangefs_default);
1159
1160static struct kobject *stats_orangefs_obj;
1161
1162static void stats_orangefs_obj_release(struct kobject *kobj)
1163{
1164	kfree(stats_orangefs_obj);
1165	stats_orangefs_obj = NULL;
1166}
1167
1168static 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
1174int 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
1298stats_obj_bail:
1299		kobject_put(stats_orangefs_obj);
1300pc_obj_bail:
1301		kobject_put(pc_orangefs_obj);
1302ncache_obj_bail:
1303		kobject_put(ncache_orangefs_obj);
1304ccache_obj_bail:
1305		kobject_put(ccache_orangefs_obj);
1306capcache_obj_bail:
1307		kobject_put(capcache_orangefs_obj);
1308acache_obj_bail:
1309		kobject_put(acache_orangefs_obj);
1310ofs_obj_bail:
1311		kobject_put(orangefs_obj);
1312out:
1313	return rc;
1314}
1315
1316void 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