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