xref: /linux/fs/orangefs/orangefs-sysfs.c (revision ac46ff0f77f1298892a4a1eeac375ed3db495704)
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 = sysfs_emit(buf,
221 				       "%d\n",
222 				       op_timeout_secs);
223 			goto out;
224 		} else if (!strcmp(attr->attr.name,
225 				   "slot_timeout_secs")) {
226 			rc = sysfs_emit(buf,
227 				       "%d\n",
228 				       slot_timeout_secs);
229 			goto out;
230 		} else if (!strcmp(attr->attr.name,
231 				   "cache_timeout_msecs")) {
232 			rc = sysfs_emit(buf,
233 				       "%d\n",
234 				       orangefs_cache_timeout_msecs);
235 			goto out;
236 		} else if (!strcmp(attr->attr.name,
237 				   "dcache_timeout_msecs")) {
238 			rc = sysfs_emit(buf,
239 				       "%d\n",
240 				       orangefs_dcache_timeout_msecs);
241 			goto out;
242 		} else if (!strcmp(attr->attr.name,
243 				   "getattr_timeout_msecs")) {
244 			rc = sysfs_emit(buf,
245 				       "%d\n",
246 				       orangefs_getattr_timeout_msecs);
247 			goto out;
248 		} else {
249 			goto out;
250 		}
251 
252 	} else if (!strcmp(kobj->name, STATS_KOBJ_ID)) {
253 		if (!strcmp(attr->attr.name, "reads")) {
254 			rc = sysfs_emit(buf,
255 				       "%lu\n",
256 				       orangefs_stats.reads);
257 			goto out;
258 		} else if (!strcmp(attr->attr.name, "writes")) {
259 			rc = sysfs_emit(buf,
260 				       "%lu\n",
261 				       orangefs_stats.writes);
262 			goto out;
263 		} else {
264 			goto out;
265 		}
266 	}
267 
268 out:
269 
270 	return rc;
271 }
272 
sysfs_int_store(struct kobject * kobj,struct orangefs_attribute * attr,const char * buf,size_t count)273 static ssize_t sysfs_int_store(struct kobject *kobj,
274     struct orangefs_attribute *attr, const char *buf, size_t count)
275 {
276 	int rc = 0;
277 
278 	gossip_debug(GOSSIP_SYSFS_DEBUG,
279 		     "sysfs_int_store: start attr->attr.name:%s: buf:%s:\n",
280 		     attr->attr.name, buf);
281 
282 	if (!strcmp(attr->attr.name, "op_timeout_secs")) {
283 		rc = kstrtoint(buf, 0, &op_timeout_secs);
284 		goto out;
285 	} else if (!strcmp(attr->attr.name, "slot_timeout_secs")) {
286 		rc = kstrtoint(buf, 0, &slot_timeout_secs);
287 		goto out;
288 	} else if (!strcmp(attr->attr.name, "cache_timeout_msecs")) {
289 		rc = kstrtoint(buf, 0, &orangefs_cache_timeout_msecs);
290 		goto out;
291 	} else if (!strcmp(attr->attr.name, "dcache_timeout_msecs")) {
292 		rc = kstrtoint(buf, 0, &orangefs_dcache_timeout_msecs);
293 		goto out;
294 	} else if (!strcmp(attr->attr.name, "getattr_timeout_msecs")) {
295 		rc = kstrtoint(buf, 0, &orangefs_getattr_timeout_msecs);
296 		goto out;
297 	} else {
298 		goto out;
299 	}
300 
301 out:
302 	if (rc)
303 		rc = -EINVAL;
304 	else
305 		rc = count;
306 
307 	return rc;
308 }
309 
310 /*
311  * obtain attribute values from userspace with a service operation.
312  */
sysfs_service_op_show(struct kobject * kobj,struct orangefs_attribute * attr,char * buf)313 static ssize_t sysfs_service_op_show(struct kobject *kobj,
314     struct orangefs_attribute *attr, char *buf)
315 {
316 	struct orangefs_kernel_op_s *new_op = NULL;
317 	int rc = 0;
318 	char *ser_op_type = NULL;
319 	__u32 op_alloc_type;
320 
321 	gossip_debug(GOSSIP_SYSFS_DEBUG,
322 		     "sysfs_service_op_show: id:%s:\n",
323 		     kobj->name);
324 
325 	if (strcmp(kobj->name, PC_KOBJ_ID))
326 		op_alloc_type = ORANGEFS_VFS_OP_PARAM;
327 	else
328 		op_alloc_type = ORANGEFS_VFS_OP_PERF_COUNT;
329 
330 	new_op = op_alloc(op_alloc_type);
331 	if (!new_op)
332 		return -ENOMEM;
333 
334 	/* Can't do a service_operation if the client is not running... */
335 	rc = is_daemon_in_service();
336 	if (rc) {
337 		pr_info_ratelimited("%s: Client not running :%d:\n",
338 			__func__,
339 			is_daemon_in_service());
340 		goto out;
341 	}
342 
343 	if (strcmp(kobj->name, PC_KOBJ_ID))
344 		new_op->upcall.req.param.type = ORANGEFS_PARAM_REQUEST_GET;
345 
346 	if (!strcmp(kobj->name, ORANGEFS_KOBJ_ID)) {
347 		/* Drop unsupported requests first. */
348 		if (!(orangefs_features & ORANGEFS_FEATURE_READAHEAD) &&
349 		    (!strcmp(attr->attr.name, "readahead_count") ||
350 		    !strcmp(attr->attr.name, "readahead_size") ||
351 		    !strcmp(attr->attr.name, "readahead_count_size") ||
352 		    !strcmp(attr->attr.name, "readahead_readcnt"))) {
353 			rc = -EINVAL;
354 			goto out;
355 		}
356 
357 		if (!strcmp(attr->attr.name, "perf_history_size"))
358 			new_op->upcall.req.param.op =
359 				ORANGEFS_PARAM_REQUEST_OP_PERF_HISTORY_SIZE;
360 		else if (!strcmp(attr->attr.name,
361 				 "perf_time_interval_secs"))
362 			new_op->upcall.req.param.op =
363 				ORANGEFS_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS;
364 		else if (!strcmp(attr->attr.name,
365 				 "perf_counter_reset"))
366 			new_op->upcall.req.param.op =
367 				ORANGEFS_PARAM_REQUEST_OP_PERF_RESET;
368 
369 		else if (!strcmp(attr->attr.name,
370 				 "readahead_count"))
371 			new_op->upcall.req.param.op =
372 				ORANGEFS_PARAM_REQUEST_OP_READAHEAD_COUNT;
373 
374 		else if (!strcmp(attr->attr.name,
375 				 "readahead_size"))
376 			new_op->upcall.req.param.op =
377 				ORANGEFS_PARAM_REQUEST_OP_READAHEAD_SIZE;
378 
379 		else if (!strcmp(attr->attr.name,
380 				 "readahead_count_size"))
381 			new_op->upcall.req.param.op =
382 				ORANGEFS_PARAM_REQUEST_OP_READAHEAD_COUNT_SIZE;
383 
384 		else if (!strcmp(attr->attr.name,
385 				 "readahead_readcnt"))
386 			new_op->upcall.req.param.op =
387 				ORANGEFS_PARAM_REQUEST_OP_READAHEAD_READCNT;
388 	} else if (!strcmp(kobj->name, ACACHE_KOBJ_ID)) {
389 		if (!strcmp(attr->attr.name, "timeout_msecs"))
390 			new_op->upcall.req.param.op =
391 				ORANGEFS_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS;
392 
393 		if (!strcmp(attr->attr.name, "hard_limit"))
394 			new_op->upcall.req.param.op =
395 				ORANGEFS_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT;
396 
397 		if (!strcmp(attr->attr.name, "soft_limit"))
398 			new_op->upcall.req.param.op =
399 				ORANGEFS_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT;
400 
401 		if (!strcmp(attr->attr.name, "reclaim_percentage"))
402 			new_op->upcall.req.param.op =
403 			  ORANGEFS_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE;
404 
405 	} else if (!strcmp(kobj->name, CAPCACHE_KOBJ_ID)) {
406 		if (!strcmp(attr->attr.name, "timeout_secs"))
407 			new_op->upcall.req.param.op =
408 				ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS;
409 
410 		if (!strcmp(attr->attr.name, "hard_limit"))
411 			new_op->upcall.req.param.op =
412 				ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT;
413 
414 		if (!strcmp(attr->attr.name, "soft_limit"))
415 			new_op->upcall.req.param.op =
416 				ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT;
417 
418 		if (!strcmp(attr->attr.name, "reclaim_percentage"))
419 			new_op->upcall.req.param.op =
420 			  ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE;
421 
422 	} else if (!strcmp(kobj->name, CCACHE_KOBJ_ID)) {
423 		if (!strcmp(attr->attr.name, "timeout_secs"))
424 			new_op->upcall.req.param.op =
425 				ORANGEFS_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS;
426 
427 		if (!strcmp(attr->attr.name, "hard_limit"))
428 			new_op->upcall.req.param.op =
429 				ORANGEFS_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT;
430 
431 		if (!strcmp(attr->attr.name, "soft_limit"))
432 			new_op->upcall.req.param.op =
433 				ORANGEFS_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT;
434 
435 		if (!strcmp(attr->attr.name, "reclaim_percentage"))
436 			new_op->upcall.req.param.op =
437 			  ORANGEFS_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE;
438 
439 	} else if (!strcmp(kobj->name, NCACHE_KOBJ_ID)) {
440 		if (!strcmp(attr->attr.name, "timeout_msecs"))
441 			new_op->upcall.req.param.op =
442 				ORANGEFS_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS;
443 
444 		if (!strcmp(attr->attr.name, "hard_limit"))
445 			new_op->upcall.req.param.op =
446 				ORANGEFS_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT;
447 
448 		if (!strcmp(attr->attr.name, "soft_limit"))
449 			new_op->upcall.req.param.op =
450 				ORANGEFS_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT;
451 
452 		if (!strcmp(attr->attr.name, "reclaim_percentage"))
453 			new_op->upcall.req.param.op =
454 			  ORANGEFS_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE;
455 
456 	} else if (!strcmp(kobj->name, PC_KOBJ_ID)) {
457 		if (!strcmp(attr->attr.name, ACACHE_KOBJ_ID))
458 			new_op->upcall.req.perf_count.type =
459 				ORANGEFS_PERF_COUNT_REQUEST_ACACHE;
460 
461 		if (!strcmp(attr->attr.name, CAPCACHE_KOBJ_ID))
462 			new_op->upcall.req.perf_count.type =
463 				ORANGEFS_PERF_COUNT_REQUEST_CAPCACHE;
464 
465 		if (!strcmp(attr->attr.name, NCACHE_KOBJ_ID))
466 			new_op->upcall.req.perf_count.type =
467 				ORANGEFS_PERF_COUNT_REQUEST_NCACHE;
468 
469 	} else {
470 		gossip_err("sysfs_service_op_show: unknown kobj_id:%s:\n",
471 			   kobj->name);
472 		rc = -EINVAL;
473 		goto out;
474 	}
475 
476 
477 	if (strcmp(kobj->name, PC_KOBJ_ID))
478 		ser_op_type = "orangefs_param";
479 	else
480 		ser_op_type = "orangefs_perf_count";
481 
482 	/*
483 	 * The service_operation will return an errno return code on
484 	 * error, and zero on success.
485 	 */
486 	rc = service_operation(new_op, ser_op_type, ORANGEFS_OP_INTERRUPTIBLE);
487 
488 out:
489 	if (!rc) {
490 		if (strcmp(kobj->name, PC_KOBJ_ID)) {
491 			if (new_op->upcall.req.param.op ==
492 			    ORANGEFS_PARAM_REQUEST_OP_READAHEAD_COUNT_SIZE) {
493 				rc = sysfs_emit(buf, "%d %d\n",
494 				    (int)new_op->downcall.resp.param.u.
495 				    value32[0],
496 				    (int)new_op->downcall.resp.param.u.
497 				    value32[1]);
498 			} else {
499 				rc = sysfs_emit(buf, "%d\n",
500 				    (int)new_op->downcall.resp.param.u.value64);
501 			}
502 		} else {
503 			rc = sysfs_emit(
504 				buf,
505 				"%s",
506 				new_op->downcall.resp.perf_count.buffer);
507 		}
508 	}
509 
510 	op_release(new_op);
511 
512 	return rc;
513 
514 }
515 
516 /*
517  * pass attribute values back to userspace with a service operation.
518  *
519  * We have to do a memory allocation, an sscanf and a service operation.
520  * And we have to evaluate what the user entered, to make sure the
521  * value is within the range supported by the attribute. So, there's
522  * a lot of return code checking and mapping going on here.
523  *
524  * We want to return 1 if we think everything went OK, and
525  * EINVAL if not.
526  */
sysfs_service_op_store(struct kobject * kobj,struct orangefs_attribute * attr,const char * buf,size_t count)527 static ssize_t sysfs_service_op_store(struct kobject *kobj,
528     struct orangefs_attribute *attr, const char *buf, size_t count)
529 {
530 	struct orangefs_kernel_op_s *new_op = NULL;
531 	int val = 0;
532 	int rc = 0;
533 
534 	gossip_debug(GOSSIP_SYSFS_DEBUG,
535 		     "sysfs_service_op_store: id:%s:\n",
536 		     kobj->name);
537 
538 	new_op = op_alloc(ORANGEFS_VFS_OP_PARAM);
539 	if (!new_op)
540 		return -EINVAL; /* sic */
541 
542 	/* Can't do a service_operation if the client is not running... */
543 	rc = is_daemon_in_service();
544 	if (rc) {
545 		pr_info("%s: Client not running :%d:\n",
546 			__func__,
547 			is_daemon_in_service());
548 		goto out;
549 	}
550 
551 	/*
552 	 * The value we want to send back to userspace is in buf, unless this
553 	 * there are two parameters, which is specially handled below.
554 	 */
555 	if (strcmp(kobj->name, ORANGEFS_KOBJ_ID) ||
556 	    strcmp(attr->attr.name, "readahead_count_size")) {
557 		rc = kstrtoint(buf, 0, &val);
558 		if (rc)
559 			goto out;
560 	}
561 
562 	new_op->upcall.req.param.type = ORANGEFS_PARAM_REQUEST_SET;
563 
564 	if (!strcmp(kobj->name, ORANGEFS_KOBJ_ID)) {
565 		/* Drop unsupported requests first. */
566 		if (!(orangefs_features & ORANGEFS_FEATURE_READAHEAD) &&
567 		    (!strcmp(attr->attr.name, "readahead_count") ||
568 		    !strcmp(attr->attr.name, "readahead_size") ||
569 		    !strcmp(attr->attr.name, "readahead_count_size") ||
570 		    !strcmp(attr->attr.name, "readahead_readcnt"))) {
571 			rc = -EINVAL;
572 			goto out;
573 		}
574 
575 		if (!strcmp(attr->attr.name, "perf_history_size")) {
576 			if (val > 0) {
577 				new_op->upcall.req.param.op =
578 				  ORANGEFS_PARAM_REQUEST_OP_PERF_HISTORY_SIZE;
579 			} else {
580 				rc = 0;
581 				goto out;
582 			}
583 		} else if (!strcmp(attr->attr.name,
584 				   "perf_time_interval_secs")) {
585 			if (val > 0) {
586 				new_op->upcall.req.param.op =
587 				ORANGEFS_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS;
588 			} else {
589 				rc = 0;
590 				goto out;
591 			}
592 		} else if (!strcmp(attr->attr.name,
593 				   "perf_counter_reset")) {
594 			if ((val == 0) || (val == 1)) {
595 				new_op->upcall.req.param.op =
596 					ORANGEFS_PARAM_REQUEST_OP_PERF_RESET;
597 			} else {
598 				rc = 0;
599 				goto out;
600 			}
601 		} else if (!strcmp(attr->attr.name,
602 				   "readahead_count")) {
603 			if ((val >= 0)) {
604 				new_op->upcall.req.param.op =
605 				ORANGEFS_PARAM_REQUEST_OP_READAHEAD_COUNT;
606 			} else {
607 				rc = 0;
608 				goto out;
609 			}
610 		} else if (!strcmp(attr->attr.name,
611 				   "readahead_size")) {
612 			if ((val >= 0)) {
613 				new_op->upcall.req.param.op =
614 				ORANGEFS_PARAM_REQUEST_OP_READAHEAD_SIZE;
615 			} else {
616 				rc = 0;
617 				goto out;
618 			}
619 		} else if (!strcmp(attr->attr.name,
620 				   "readahead_count_size")) {
621 			int val1, val2;
622 			rc = sscanf(buf, "%d %d", &val1, &val2);
623 			if (rc < 2) {
624 				rc = 0;
625 				goto out;
626 			}
627 			if ((val1 >= 0) && (val2 >= 0)) {
628 				new_op->upcall.req.param.op =
629 				ORANGEFS_PARAM_REQUEST_OP_READAHEAD_COUNT_SIZE;
630 			} else {
631 				rc = 0;
632 				goto out;
633 			}
634 			new_op->upcall.req.param.u.value32[0] = val1;
635 			new_op->upcall.req.param.u.value32[1] = val2;
636 			goto value_set;
637 		} else if (!strcmp(attr->attr.name,
638 				   "readahead_readcnt")) {
639 			if ((val >= 0)) {
640 				new_op->upcall.req.param.op =
641 				ORANGEFS_PARAM_REQUEST_OP_READAHEAD_READCNT;
642 			} else {
643 				rc = 0;
644 				goto out;
645 			}
646 		}
647 
648 	} else if (!strcmp(kobj->name, ACACHE_KOBJ_ID)) {
649 		if (!strcmp(attr->attr.name, "hard_limit")) {
650 			if (val > -1) {
651 				new_op->upcall.req.param.op =
652 				  ORANGEFS_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT;
653 			} else {
654 				rc = 0;
655 				goto out;
656 			}
657 		} else if (!strcmp(attr->attr.name, "soft_limit")) {
658 			if (val > -1) {
659 				new_op->upcall.req.param.op =
660 				  ORANGEFS_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT;
661 			} else {
662 				rc = 0;
663 				goto out;
664 			}
665 		} else if (!strcmp(attr->attr.name,
666 				   "reclaim_percentage")) {
667 			if ((val > -1) && (val < 101)) {
668 				new_op->upcall.req.param.op =
669 				  ORANGEFS_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE;
670 			} else {
671 				rc = 0;
672 				goto out;
673 			}
674 		} else if (!strcmp(attr->attr.name, "timeout_msecs")) {
675 			if (val > -1) {
676 				new_op->upcall.req.param.op =
677 				  ORANGEFS_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS;
678 			} else {
679 				rc = 0;
680 				goto out;
681 			}
682 		}
683 
684 	} else if (!strcmp(kobj->name, CAPCACHE_KOBJ_ID)) {
685 		if (!strcmp(attr->attr.name, "hard_limit")) {
686 			if (val > -1) {
687 				new_op->upcall.req.param.op =
688 				  ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT;
689 			} else {
690 				rc = 0;
691 				goto out;
692 			}
693 		} else if (!strcmp(attr->attr.name, "soft_limit")) {
694 			if (val > -1) {
695 				new_op->upcall.req.param.op =
696 				  ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT;
697 			} else {
698 				rc = 0;
699 				goto out;
700 			}
701 		} else if (!strcmp(attr->attr.name,
702 				   "reclaim_percentage")) {
703 			if ((val > -1) && (val < 101)) {
704 				new_op->upcall.req.param.op =
705 				  ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE;
706 			} else {
707 				rc = 0;
708 				goto out;
709 			}
710 		} else if (!strcmp(attr->attr.name, "timeout_secs")) {
711 			if (val > -1) {
712 				new_op->upcall.req.param.op =
713 				  ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS;
714 			} else {
715 				rc = 0;
716 				goto out;
717 			}
718 		}
719 
720 	} else if (!strcmp(kobj->name, CCACHE_KOBJ_ID)) {
721 		if (!strcmp(attr->attr.name, "hard_limit")) {
722 			if (val > -1) {
723 				new_op->upcall.req.param.op =
724 				  ORANGEFS_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT;
725 			} else {
726 				rc = 0;
727 				goto out;
728 			}
729 		} else if (!strcmp(attr->attr.name, "soft_limit")) {
730 			if (val > -1) {
731 				new_op->upcall.req.param.op =
732 				  ORANGEFS_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT;
733 			} else {
734 				rc = 0;
735 				goto out;
736 			}
737 		} else if (!strcmp(attr->attr.name,
738 				   "reclaim_percentage")) {
739 			if ((val > -1) && (val < 101)) {
740 				new_op->upcall.req.param.op =
741 				  ORANGEFS_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE;
742 			} else {
743 				rc = 0;
744 				goto out;
745 			}
746 		} else if (!strcmp(attr->attr.name, "timeout_secs")) {
747 			if (val > -1) {
748 				new_op->upcall.req.param.op =
749 				  ORANGEFS_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS;
750 			} else {
751 				rc = 0;
752 				goto out;
753 			}
754 		}
755 
756 	} else if (!strcmp(kobj->name, NCACHE_KOBJ_ID)) {
757 		if (!strcmp(attr->attr.name, "hard_limit")) {
758 			if (val > -1) {
759 				new_op->upcall.req.param.op =
760 				  ORANGEFS_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT;
761 			} else {
762 				rc = 0;
763 				goto out;
764 			}
765 		} else if (!strcmp(attr->attr.name, "soft_limit")) {
766 			if (val > -1) {
767 				new_op->upcall.req.param.op =
768 				  ORANGEFS_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT;
769 			} else {
770 				rc = 0;
771 				goto out;
772 			}
773 		} else if (!strcmp(attr->attr.name,
774 				   "reclaim_percentage")) {
775 			if ((val > -1) && (val < 101)) {
776 				new_op->upcall.req.param.op =
777 					ORANGEFS_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE;
778 			} else {
779 				rc = 0;
780 				goto out;
781 			}
782 		} else if (!strcmp(attr->attr.name, "timeout_msecs")) {
783 			if (val > -1) {
784 				new_op->upcall.req.param.op =
785 				  ORANGEFS_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS;
786 			} else {
787 				rc = 0;
788 				goto out;
789 			}
790 		}
791 
792 	} else {
793 		gossip_err("sysfs_service_op_store: unknown kobj_id:%s:\n",
794 			   kobj->name);
795 		rc = -EINVAL;
796 		goto out;
797 	}
798 
799 	new_op->upcall.req.param.u.value64 = val;
800 value_set:
801 
802 	/*
803 	 * The service_operation will return a errno return code on
804 	 * error, and zero on success.
805 	 */
806 	rc = service_operation(new_op, "orangefs_param", ORANGEFS_OP_INTERRUPTIBLE);
807 
808 	if (rc < 0) {
809 		gossip_err("sysfs_service_op_store: service op returned:%d:\n",
810 			rc);
811 		rc = 0;
812 	} else {
813 		rc = count;
814 	}
815 
816 out:
817 	op_release(new_op);
818 
819 	if (rc == -ENOMEM || rc == 0)
820 		rc = -EINVAL;
821 
822 	return rc;
823 }
824 
825 static struct orangefs_attribute op_timeout_secs_attribute =
826 	__ATTR(op_timeout_secs, 0664, sysfs_int_show, sysfs_int_store);
827 
828 static struct orangefs_attribute slot_timeout_secs_attribute =
829 	__ATTR(slot_timeout_secs, 0664, sysfs_int_show, sysfs_int_store);
830 
831 static struct orangefs_attribute cache_timeout_msecs_attribute =
832 	__ATTR(cache_timeout_msecs, 0664, sysfs_int_show, sysfs_int_store);
833 
834 static struct orangefs_attribute dcache_timeout_msecs_attribute =
835 	__ATTR(dcache_timeout_msecs, 0664, sysfs_int_show, sysfs_int_store);
836 
837 static struct orangefs_attribute getattr_timeout_msecs_attribute =
838 	__ATTR(getattr_timeout_msecs, 0664, sysfs_int_show, sysfs_int_store);
839 
840 static struct orangefs_attribute readahead_count_attribute =
841 	__ATTR(readahead_count, 0664, sysfs_service_op_show,
842 	       sysfs_service_op_store);
843 
844 static struct orangefs_attribute readahead_size_attribute =
845 	__ATTR(readahead_size, 0664, sysfs_service_op_show,
846 	       sysfs_service_op_store);
847 
848 static struct orangefs_attribute readahead_count_size_attribute =
849 	__ATTR(readahead_count_size, 0664, sysfs_service_op_show,
850 	       sysfs_service_op_store);
851 
852 static struct orangefs_attribute readahead_readcnt_attribute =
853 	__ATTR(readahead_readcnt, 0664, sysfs_service_op_show,
854 	       sysfs_service_op_store);
855 
856 static struct orangefs_attribute perf_counter_reset_attribute =
857 	__ATTR(perf_counter_reset,
858 	       0664,
859 	       sysfs_service_op_show,
860 	       sysfs_service_op_store);
861 
862 static struct orangefs_attribute perf_history_size_attribute =
863 	__ATTR(perf_history_size,
864 	       0664,
865 	       sysfs_service_op_show,
866 	       sysfs_service_op_store);
867 
868 static struct orangefs_attribute perf_time_interval_secs_attribute =
869 	__ATTR(perf_time_interval_secs,
870 	       0664,
871 	       sysfs_service_op_show,
872 	       sysfs_service_op_store);
873 
874 static struct attribute *orangefs_default_attrs[] = {
875 	&op_timeout_secs_attribute.attr,
876 	&slot_timeout_secs_attribute.attr,
877 	&cache_timeout_msecs_attribute.attr,
878 	&dcache_timeout_msecs_attribute.attr,
879 	&getattr_timeout_msecs_attribute.attr,
880 	&readahead_count_attribute.attr,
881 	&readahead_size_attribute.attr,
882 	&readahead_count_size_attribute.attr,
883 	&readahead_readcnt_attribute.attr,
884 	&perf_counter_reset_attribute.attr,
885 	&perf_history_size_attribute.attr,
886 	&perf_time_interval_secs_attribute.attr,
887 	NULL,
888 };
889 ATTRIBUTE_GROUPS(orangefs_default);
890 
891 static struct kobject *orangefs_obj;
892 
orangefs_obj_release(struct kobject * kobj)893 static void orangefs_obj_release(struct kobject *kobj)
894 {
895 	kfree(orangefs_obj);
896 	orangefs_obj = NULL;
897 }
898 
899 static const struct kobj_type orangefs_ktype = {
900 	.sysfs_ops = &orangefs_sysfs_ops,
901 	.default_groups = orangefs_default_groups,
902 	.release = orangefs_obj_release,
903 };
904 
905 static struct orangefs_attribute acache_hard_limit_attribute =
906 	__ATTR(hard_limit,
907 	       0664,
908 	       sysfs_service_op_show,
909 	       sysfs_service_op_store);
910 
911 static struct orangefs_attribute acache_reclaim_percent_attribute =
912 	__ATTR(reclaim_percentage,
913 	       0664,
914 	       sysfs_service_op_show,
915 	       sysfs_service_op_store);
916 
917 static struct orangefs_attribute acache_soft_limit_attribute =
918 	__ATTR(soft_limit,
919 	       0664,
920 	       sysfs_service_op_show,
921 	       sysfs_service_op_store);
922 
923 static struct orangefs_attribute acache_timeout_msecs_attribute =
924 	__ATTR(timeout_msecs,
925 	       0664,
926 	       sysfs_service_op_show,
927 	       sysfs_service_op_store);
928 
929 static struct attribute *acache_orangefs_default_attrs[] = {
930 	&acache_hard_limit_attribute.attr,
931 	&acache_reclaim_percent_attribute.attr,
932 	&acache_soft_limit_attribute.attr,
933 	&acache_timeout_msecs_attribute.attr,
934 	NULL,
935 };
936 ATTRIBUTE_GROUPS(acache_orangefs_default);
937 
938 static struct kobject *acache_orangefs_obj;
939 
acache_orangefs_obj_release(struct kobject * kobj)940 static void acache_orangefs_obj_release(struct kobject *kobj)
941 {
942 	kfree(acache_orangefs_obj);
943 	acache_orangefs_obj = NULL;
944 }
945 
946 static const struct kobj_type acache_orangefs_ktype = {
947 	.sysfs_ops = &orangefs_sysfs_ops,
948 	.default_groups = acache_orangefs_default_groups,
949 	.release = acache_orangefs_obj_release,
950 };
951 
952 static struct orangefs_attribute capcache_hard_limit_attribute =
953 	__ATTR(hard_limit,
954 	       0664,
955 	       sysfs_service_op_show,
956 	       sysfs_service_op_store);
957 
958 static struct orangefs_attribute capcache_reclaim_percent_attribute =
959 	__ATTR(reclaim_percentage,
960 	       0664,
961 	       sysfs_service_op_show,
962 	       sysfs_service_op_store);
963 
964 static struct orangefs_attribute capcache_soft_limit_attribute =
965 	__ATTR(soft_limit,
966 	       0664,
967 	       sysfs_service_op_show,
968 	       sysfs_service_op_store);
969 
970 static struct orangefs_attribute capcache_timeout_secs_attribute =
971 	__ATTR(timeout_secs,
972 	       0664,
973 	       sysfs_service_op_show,
974 	       sysfs_service_op_store);
975 
976 static struct attribute *capcache_orangefs_default_attrs[] = {
977 	&capcache_hard_limit_attribute.attr,
978 	&capcache_reclaim_percent_attribute.attr,
979 	&capcache_soft_limit_attribute.attr,
980 	&capcache_timeout_secs_attribute.attr,
981 	NULL,
982 };
983 ATTRIBUTE_GROUPS(capcache_orangefs_default);
984 
985 static struct kobject *capcache_orangefs_obj;
986 
capcache_orangefs_obj_release(struct kobject * kobj)987 static void capcache_orangefs_obj_release(struct kobject *kobj)
988 {
989 	kfree(capcache_orangefs_obj);
990 	capcache_orangefs_obj = NULL;
991 }
992 
993 static const struct kobj_type capcache_orangefs_ktype = {
994 	.sysfs_ops = &orangefs_sysfs_ops,
995 	.default_groups = capcache_orangefs_default_groups,
996 	.release = capcache_orangefs_obj_release,
997 };
998 
999 static struct orangefs_attribute ccache_hard_limit_attribute =
1000 	__ATTR(hard_limit,
1001 	       0664,
1002 	       sysfs_service_op_show,
1003 	       sysfs_service_op_store);
1004 
1005 static struct orangefs_attribute ccache_reclaim_percent_attribute =
1006 	__ATTR(reclaim_percentage,
1007 	       0664,
1008 	       sysfs_service_op_show,
1009 	       sysfs_service_op_store);
1010 
1011 static struct orangefs_attribute ccache_soft_limit_attribute =
1012 	__ATTR(soft_limit,
1013 	       0664,
1014 	       sysfs_service_op_show,
1015 	       sysfs_service_op_store);
1016 
1017 static struct orangefs_attribute ccache_timeout_secs_attribute =
1018 	__ATTR(timeout_secs,
1019 	       0664,
1020 	       sysfs_service_op_show,
1021 	       sysfs_service_op_store);
1022 
1023 static struct attribute *ccache_orangefs_default_attrs[] = {
1024 	&ccache_hard_limit_attribute.attr,
1025 	&ccache_reclaim_percent_attribute.attr,
1026 	&ccache_soft_limit_attribute.attr,
1027 	&ccache_timeout_secs_attribute.attr,
1028 	NULL,
1029 };
1030 ATTRIBUTE_GROUPS(ccache_orangefs_default);
1031 
1032 static struct kobject *ccache_orangefs_obj;
1033 
ccache_orangefs_obj_release(struct kobject * kobj)1034 static void ccache_orangefs_obj_release(struct kobject *kobj)
1035 {
1036 	kfree(ccache_orangefs_obj);
1037 	ccache_orangefs_obj = NULL;
1038 }
1039 
1040 static const struct kobj_type ccache_orangefs_ktype = {
1041 	.sysfs_ops = &orangefs_sysfs_ops,
1042 	.default_groups = ccache_orangefs_default_groups,
1043 	.release = ccache_orangefs_obj_release,
1044 };
1045 
1046 static struct orangefs_attribute ncache_hard_limit_attribute =
1047 	__ATTR(hard_limit,
1048 	       0664,
1049 	       sysfs_service_op_show,
1050 	       sysfs_service_op_store);
1051 
1052 static struct orangefs_attribute ncache_reclaim_percent_attribute =
1053 	__ATTR(reclaim_percentage,
1054 	       0664,
1055 	       sysfs_service_op_show,
1056 	       sysfs_service_op_store);
1057 
1058 static struct orangefs_attribute ncache_soft_limit_attribute =
1059 	__ATTR(soft_limit,
1060 	       0664,
1061 	       sysfs_service_op_show,
1062 	       sysfs_service_op_store);
1063 
1064 static struct orangefs_attribute ncache_timeout_msecs_attribute =
1065 	__ATTR(timeout_msecs,
1066 	       0664,
1067 	       sysfs_service_op_show,
1068 	       sysfs_service_op_store);
1069 
1070 static struct attribute *ncache_orangefs_default_attrs[] = {
1071 	&ncache_hard_limit_attribute.attr,
1072 	&ncache_reclaim_percent_attribute.attr,
1073 	&ncache_soft_limit_attribute.attr,
1074 	&ncache_timeout_msecs_attribute.attr,
1075 	NULL,
1076 };
1077 ATTRIBUTE_GROUPS(ncache_orangefs_default);
1078 
1079 static struct kobject *ncache_orangefs_obj;
1080 
ncache_orangefs_obj_release(struct kobject * kobj)1081 static void ncache_orangefs_obj_release(struct kobject *kobj)
1082 {
1083 	kfree(ncache_orangefs_obj);
1084 	ncache_orangefs_obj = NULL;
1085 }
1086 
1087 static const struct kobj_type ncache_orangefs_ktype = {
1088 	.sysfs_ops = &orangefs_sysfs_ops,
1089 	.default_groups = ncache_orangefs_default_groups,
1090 	.release = ncache_orangefs_obj_release,
1091 };
1092 
1093 static struct orangefs_attribute pc_acache_attribute =
1094 	__ATTR(acache,
1095 	       0664,
1096 	       sysfs_service_op_show,
1097 	       NULL);
1098 
1099 static struct orangefs_attribute pc_capcache_attribute =
1100 	__ATTR(capcache,
1101 	       0664,
1102 	       sysfs_service_op_show,
1103 	       NULL);
1104 
1105 static struct orangefs_attribute pc_ncache_attribute =
1106 	__ATTR(ncache,
1107 	       0664,
1108 	       sysfs_service_op_show,
1109 	       NULL);
1110 
1111 static struct attribute *pc_orangefs_default_attrs[] = {
1112 	&pc_acache_attribute.attr,
1113 	&pc_capcache_attribute.attr,
1114 	&pc_ncache_attribute.attr,
1115 	NULL,
1116 };
1117 ATTRIBUTE_GROUPS(pc_orangefs_default);
1118 
1119 static struct kobject *pc_orangefs_obj;
1120 
pc_orangefs_obj_release(struct kobject * kobj)1121 static void pc_orangefs_obj_release(struct kobject *kobj)
1122 {
1123 	kfree(pc_orangefs_obj);
1124 	pc_orangefs_obj = NULL;
1125 }
1126 
1127 static const struct kobj_type pc_orangefs_ktype = {
1128 	.sysfs_ops = &orangefs_sysfs_ops,
1129 	.default_groups = pc_orangefs_default_groups,
1130 	.release = pc_orangefs_obj_release,
1131 };
1132 
1133 static struct orangefs_attribute stats_reads_attribute =
1134 	__ATTR(reads,
1135 	       0664,
1136 	       sysfs_int_show,
1137 	       NULL);
1138 
1139 static struct orangefs_attribute stats_writes_attribute =
1140 	__ATTR(writes,
1141 	       0664,
1142 	       sysfs_int_show,
1143 	       NULL);
1144 
1145 static struct attribute *stats_orangefs_default_attrs[] = {
1146 	&stats_reads_attribute.attr,
1147 	&stats_writes_attribute.attr,
1148 	NULL,
1149 };
1150 ATTRIBUTE_GROUPS(stats_orangefs_default);
1151 
1152 static struct kobject *stats_orangefs_obj;
1153 
stats_orangefs_obj_release(struct kobject * kobj)1154 static void stats_orangefs_obj_release(struct kobject *kobj)
1155 {
1156 	kfree(stats_orangefs_obj);
1157 	stats_orangefs_obj = NULL;
1158 }
1159 
1160 static const struct kobj_type stats_orangefs_ktype = {
1161 	.sysfs_ops = &orangefs_sysfs_ops,
1162 	.default_groups = stats_orangefs_default_groups,
1163 	.release = stats_orangefs_obj_release,
1164 };
1165 
orangefs_sysfs_init(void)1166 int orangefs_sysfs_init(void)
1167 {
1168 	int rc = -EINVAL;
1169 
1170 	gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_init: start\n");
1171 
1172 	/* create /sys/fs/orangefs. */
1173 	orangefs_obj = kzalloc(sizeof(*orangefs_obj), GFP_KERNEL);
1174 	if (!orangefs_obj)
1175 		goto out;
1176 
1177 	rc = kobject_init_and_add(orangefs_obj,
1178 				  &orangefs_ktype,
1179 				  fs_kobj,
1180 				  ORANGEFS_KOBJ_ID);
1181 
1182 	if (rc)
1183 		goto ofs_obj_bail;
1184 
1185 	kobject_uevent(orangefs_obj, KOBJ_ADD);
1186 
1187 	/* create /sys/fs/orangefs/acache. */
1188 	acache_orangefs_obj = kzalloc(sizeof(*acache_orangefs_obj), GFP_KERNEL);
1189 	if (!acache_orangefs_obj) {
1190 		rc = -EINVAL;
1191 		goto ofs_obj_bail;
1192 	}
1193 
1194 	rc = kobject_init_and_add(acache_orangefs_obj,
1195 				  &acache_orangefs_ktype,
1196 				  orangefs_obj,
1197 				  ACACHE_KOBJ_ID);
1198 
1199 	if (rc)
1200 		goto acache_obj_bail;
1201 
1202 	kobject_uevent(acache_orangefs_obj, KOBJ_ADD);
1203 
1204 	/* create /sys/fs/orangefs/capcache. */
1205 	capcache_orangefs_obj =
1206 		kzalloc(sizeof(*capcache_orangefs_obj), GFP_KERNEL);
1207 	if (!capcache_orangefs_obj) {
1208 		rc = -EINVAL;
1209 		goto acache_obj_bail;
1210 	}
1211 
1212 	rc = kobject_init_and_add(capcache_orangefs_obj,
1213 				  &capcache_orangefs_ktype,
1214 				  orangefs_obj,
1215 				  CAPCACHE_KOBJ_ID);
1216 	if (rc)
1217 		goto capcache_obj_bail;
1218 
1219 	kobject_uevent(capcache_orangefs_obj, KOBJ_ADD);
1220 
1221 	/* create /sys/fs/orangefs/ccache. */
1222 	ccache_orangefs_obj =
1223 		kzalloc(sizeof(*ccache_orangefs_obj), GFP_KERNEL);
1224 	if (!ccache_orangefs_obj) {
1225 		rc = -EINVAL;
1226 		goto capcache_obj_bail;
1227 	}
1228 
1229 	rc = kobject_init_and_add(ccache_orangefs_obj,
1230 				  &ccache_orangefs_ktype,
1231 				  orangefs_obj,
1232 				  CCACHE_KOBJ_ID);
1233 	if (rc)
1234 		goto ccache_obj_bail;
1235 
1236 	kobject_uevent(ccache_orangefs_obj, KOBJ_ADD);
1237 
1238 	/* create /sys/fs/orangefs/ncache. */
1239 	ncache_orangefs_obj = kzalloc(sizeof(*ncache_orangefs_obj), GFP_KERNEL);
1240 	if (!ncache_orangefs_obj) {
1241 		rc = -EINVAL;
1242 		goto ccache_obj_bail;
1243 	}
1244 
1245 	rc = kobject_init_and_add(ncache_orangefs_obj,
1246 				  &ncache_orangefs_ktype,
1247 				  orangefs_obj,
1248 				  NCACHE_KOBJ_ID);
1249 
1250 	if (rc)
1251 		goto ncache_obj_bail;
1252 
1253 	kobject_uevent(ncache_orangefs_obj, KOBJ_ADD);
1254 
1255 	/* create /sys/fs/orangefs/perf_counters. */
1256 	pc_orangefs_obj = kzalloc(sizeof(*pc_orangefs_obj), GFP_KERNEL);
1257 	if (!pc_orangefs_obj) {
1258 		rc = -EINVAL;
1259 		goto ncache_obj_bail;
1260 	}
1261 
1262 	rc = kobject_init_and_add(pc_orangefs_obj,
1263 				  &pc_orangefs_ktype,
1264 				  orangefs_obj,
1265 				  "perf_counters");
1266 
1267 	if (rc)
1268 		goto pc_obj_bail;
1269 
1270 	kobject_uevent(pc_orangefs_obj, KOBJ_ADD);
1271 
1272 	/* create /sys/fs/orangefs/stats. */
1273 	stats_orangefs_obj = kzalloc(sizeof(*stats_orangefs_obj), GFP_KERNEL);
1274 	if (!stats_orangefs_obj) {
1275 		rc = -EINVAL;
1276 		goto pc_obj_bail;
1277 	}
1278 
1279 	rc = kobject_init_and_add(stats_orangefs_obj,
1280 				  &stats_orangefs_ktype,
1281 				  orangefs_obj,
1282 				  STATS_KOBJ_ID);
1283 
1284 	if (rc)
1285 		goto stats_obj_bail;
1286 
1287 	kobject_uevent(stats_orangefs_obj, KOBJ_ADD);
1288 	goto out;
1289 
1290 stats_obj_bail:
1291 		kobject_put(stats_orangefs_obj);
1292 pc_obj_bail:
1293 		kobject_put(pc_orangefs_obj);
1294 ncache_obj_bail:
1295 		kobject_put(ncache_orangefs_obj);
1296 ccache_obj_bail:
1297 		kobject_put(ccache_orangefs_obj);
1298 capcache_obj_bail:
1299 		kobject_put(capcache_orangefs_obj);
1300 acache_obj_bail:
1301 		kobject_put(acache_orangefs_obj);
1302 ofs_obj_bail:
1303 		kobject_put(orangefs_obj);
1304 out:
1305 	return rc;
1306 }
1307 
orangefs_sysfs_exit(void)1308 void orangefs_sysfs_exit(void)
1309 {
1310 	gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_exit: start\n");
1311 	kobject_put(acache_orangefs_obj);
1312 	kobject_put(capcache_orangefs_obj);
1313 	kobject_put(ccache_orangefs_obj);
1314 	kobject_put(ncache_orangefs_obj);
1315 	kobject_put(pc_orangefs_obj);
1316 	kobject_put(stats_orangefs_obj);
1317 	kobject_put(orangefs_obj);
1318 }
1319