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