File Index
Files and directories
Sign in
FILE

orangefs-sysfs.c

File preview with syntax highlighting.

linux-6.19.14/fs/orangefs/orangefs-sysfs.c C
   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 = 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
 268out:
 269
 270	return rc;
 271}
 272
 273static 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
 301out:
 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 */
 313static 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
 488out:
 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 */
 527static 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;
 800value_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
 816out:
 817	op_release(new_op);
 818
 819	if (rc == -ENOMEM || rc == 0)
 820		rc = -EINVAL;
 821
 822	return rc;
 823}
 824
 825static struct orangefs_attribute op_timeout_secs_attribute =
 826	__ATTR(op_timeout_secs, 0664, sysfs_int_show, sysfs_int_store);
 827
 828static struct orangefs_attribute slot_timeout_secs_attribute =
 829	__ATTR(slot_timeout_secs, 0664, sysfs_int_show, sysfs_int_store);
 830
 831static struct orangefs_attribute cache_timeout_msecs_attribute =
 832	__ATTR(cache_timeout_msecs, 0664, sysfs_int_show, sysfs_int_store);
 833
 834static struct orangefs_attribute dcache_timeout_msecs_attribute =
 835	__ATTR(dcache_timeout_msecs, 0664, sysfs_int_show, sysfs_int_store);
 836
 837static struct orangefs_attribute getattr_timeout_msecs_attribute =
 838	__ATTR(getattr_timeout_msecs, 0664, sysfs_int_show, sysfs_int_store);
 839
 840static struct orangefs_attribute readahead_count_attribute =
 841	__ATTR(readahead_count, 0664, sysfs_service_op_show,
 842	       sysfs_service_op_store);
 843
 844static struct orangefs_attribute readahead_size_attribute =
 845	__ATTR(readahead_size, 0664, sysfs_service_op_show,
 846	       sysfs_service_op_store);
 847
 848static struct orangefs_attribute readahead_count_size_attribute =
 849	__ATTR(readahead_count_size, 0664, sysfs_service_op_show,
 850	       sysfs_service_op_store);
 851
 852static struct orangefs_attribute readahead_readcnt_attribute =
 853	__ATTR(readahead_readcnt, 0664, sysfs_service_op_show,
 854	       sysfs_service_op_store);
 855
 856static 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
 862static 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
 868static 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
 874static 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};
 889ATTRIBUTE_GROUPS(orangefs_default);
 890
 891static struct kobject *orangefs_obj;
 892
 893static void orangefs_obj_release(struct kobject *kobj)
 894{
 895	kfree(orangefs_obj);
 896	orangefs_obj = NULL;
 897}
 898
 899static 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
 905static struct orangefs_attribute acache_hard_limit_attribute =
 906	__ATTR(hard_limit,
 907	       0664,
 908	       sysfs_service_op_show,
 909	       sysfs_service_op_store);
 910
 911static struct orangefs_attribute acache_reclaim_percent_attribute =
 912	__ATTR(reclaim_percentage,
 913	       0664,
 914	       sysfs_service_op_show,
 915	       sysfs_service_op_store);
 916
 917static struct orangefs_attribute acache_soft_limit_attribute =
 918	__ATTR(soft_limit,
 919	       0664,
 920	       sysfs_service_op_show,
 921	       sysfs_service_op_store);
 922
 923static struct orangefs_attribute acache_timeout_msecs_attribute =
 924	__ATTR(timeout_msecs,
 925	       0664,
 926	       sysfs_service_op_show,
 927	       sysfs_service_op_store);
 928
 929static 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};
 936ATTRIBUTE_GROUPS(acache_orangefs_default);
 937
 938static struct kobject *acache_orangefs_obj;
 939
 940static void acache_orangefs_obj_release(struct kobject *kobj)
 941{
 942	kfree(acache_orangefs_obj);
 943	acache_orangefs_obj = NULL;
 944}
 945
 946static 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
 952static struct orangefs_attribute capcache_hard_limit_attribute =
 953	__ATTR(hard_limit,
 954	       0664,
 955	       sysfs_service_op_show,
 956	       sysfs_service_op_store);
 957
 958static struct orangefs_attribute capcache_reclaim_percent_attribute =
 959	__ATTR(reclaim_percentage,
 960	       0664,
 961	       sysfs_service_op_show,
 962	       sysfs_service_op_store);
 963
 964static struct orangefs_attribute capcache_soft_limit_attribute =
 965	__ATTR(soft_limit,
 966	       0664,
 967	       sysfs_service_op_show,
 968	       sysfs_service_op_store);
 969
 970static struct orangefs_attribute capcache_timeout_secs_attribute =
 971	__ATTR(timeout_secs,
 972	       0664,
 973	       sysfs_service_op_show,
 974	       sysfs_service_op_store);
 975
 976static 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};
 983ATTRIBUTE_GROUPS(capcache_orangefs_default);
 984
 985static struct kobject *capcache_orangefs_obj;
 986
 987static void capcache_orangefs_obj_release(struct kobject *kobj)
 988{
 989	kfree(capcache_orangefs_obj);
 990	capcache_orangefs_obj = NULL;
 991}
 992
 993static 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
 999static struct orangefs_attribute ccache_hard_limit_attribute =
1000	__ATTR(hard_limit,
1001	       0664,
1002	       sysfs_service_op_show,
1003	       sysfs_service_op_store);
1004
1005static struct orangefs_attribute ccache_reclaim_percent_attribute =
1006	__ATTR(reclaim_percentage,
1007	       0664,
1008	       sysfs_service_op_show,
1009	       sysfs_service_op_store);
1010
1011static struct orangefs_attribute ccache_soft_limit_attribute =
1012	__ATTR(soft_limit,
1013	       0664,
1014	       sysfs_service_op_show,
1015	       sysfs_service_op_store);
1016
1017static struct orangefs_attribute ccache_timeout_secs_attribute =
1018	__ATTR(timeout_secs,
1019	       0664,
1020	       sysfs_service_op_show,
1021	       sysfs_service_op_store);
1022
1023static 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};
1030ATTRIBUTE_GROUPS(ccache_orangefs_default);
1031
1032static struct kobject *ccache_orangefs_obj;
1033
1034static void ccache_orangefs_obj_release(struct kobject *kobj)
1035{
1036	kfree(ccache_orangefs_obj);
1037	ccache_orangefs_obj = NULL;
1038}
1039
1040static 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
1046static struct orangefs_attribute ncache_hard_limit_attribute =
1047	__ATTR(hard_limit,
1048	       0664,
1049	       sysfs_service_op_show,
1050	       sysfs_service_op_store);
1051
1052static struct orangefs_attribute ncache_reclaim_percent_attribute =
1053	__ATTR(reclaim_percentage,
1054	       0664,
1055	       sysfs_service_op_show,
1056	       sysfs_service_op_store);
1057
1058static struct orangefs_attribute ncache_soft_limit_attribute =
1059	__ATTR(soft_limit,
1060	       0664,
1061	       sysfs_service_op_show,
1062	       sysfs_service_op_store);
1063
1064static struct orangefs_attribute ncache_timeout_msecs_attribute =
1065	__ATTR(timeout_msecs,
1066	       0664,
1067	       sysfs_service_op_show,
1068	       sysfs_service_op_store);
1069
1070static 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};
1077ATTRIBUTE_GROUPS(ncache_orangefs_default);
1078
1079static struct kobject *ncache_orangefs_obj;
1080
1081static void ncache_orangefs_obj_release(struct kobject *kobj)
1082{
1083	kfree(ncache_orangefs_obj);
1084	ncache_orangefs_obj = NULL;
1085}
1086
1087static 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
1093static struct orangefs_attribute pc_acache_attribute =
1094	__ATTR(acache,
1095	       0664,
1096	       sysfs_service_op_show,
1097	       NULL);
1098
1099static struct orangefs_attribute pc_capcache_attribute =
1100	__ATTR(capcache,
1101	       0664,
1102	       sysfs_service_op_show,
1103	       NULL);
1104
1105static struct orangefs_attribute pc_ncache_attribute =
1106	__ATTR(ncache,
1107	       0664,
1108	       sysfs_service_op_show,
1109	       NULL);
1110
1111static struct attribute *pc_orangefs_default_attrs[] = {
1112	&pc_acache_attribute.attr,
1113	&pc_capcache_attribute.attr,
1114	&pc_ncache_attribute.attr,
1115	NULL,
1116};
1117ATTRIBUTE_GROUPS(pc_orangefs_default);
1118
1119static struct kobject *pc_orangefs_obj;
1120
1121static void pc_orangefs_obj_release(struct kobject *kobj)
1122{
1123	kfree(pc_orangefs_obj);
1124	pc_orangefs_obj = NULL;
1125}
1126
1127static 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
1133static struct orangefs_attribute stats_reads_attribute =
1134	__ATTR(reads,
1135	       0664,
1136	       sysfs_int_show,
1137	       NULL);
1138
1139static struct orangefs_attribute stats_writes_attribute =
1140	__ATTR(writes,
1141	       0664,
1142	       sysfs_int_show,
1143	       NULL);
1144
1145static struct attribute *stats_orangefs_default_attrs[] = {
1146	&stats_reads_attribute.attr,
1147	&stats_writes_attribute.attr,
1148	NULL,
1149};
1150ATTRIBUTE_GROUPS(stats_orangefs_default);
1151
1152static struct kobject *stats_orangefs_obj;
1153
1154static void stats_orangefs_obj_release(struct kobject *kobj)
1155{
1156	kfree(stats_orangefs_obj);
1157	stats_orangefs_obj = NULL;
1158}
1159
1160static 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
1166int 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
1290stats_obj_bail:
1291		kobject_put(stats_orangefs_obj);
1292pc_obj_bail:
1293		kobject_put(pc_orangefs_obj);
1294ncache_obj_bail:
1295		kobject_put(ncache_orangefs_obj);
1296ccache_obj_bail:
1297		kobject_put(ccache_orangefs_obj);
1298capcache_obj_bail:
1299		kobject_put(capcache_orangefs_obj);
1300acache_obj_bail:
1301		kobject_put(acache_orangefs_obj);
1302ofs_obj_bail:
1303		kobject_put(orangefs_obj);
1304out:
1305	return rc;
1306}
1307
1308void 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}
~/ Read-only file preview.