Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
   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 const 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 const 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 const 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 const 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 const 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 const 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 const 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}