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/dcache_timeout_msecs 66 * Date: Jul 2016 67 * Contact: Martin Brandenburg <martin@omnibond.com> 68 * Description: 69 * Time lookup is valid in milliseconds. 70 * 71 * What: /sys/fs/orangefs/getattr_timeout_msecs 72 * Date: Jul 2016 73 * Contact: Martin Brandenburg <martin@omnibond.com> 74 * Description: 75 * Time getattr is valid in milliseconds. 76 * 77 * What: /sys/fs/orangefs/readahead_count 78 * Date: Aug 2016 79 * Contact: Martin Brandenburg <martin@omnibond.com> 80 * Description: 81 * Readahead cache buffer count. 82 * 83 * What: /sys/fs/orangefs/readahead_size 84 * Date: Aug 2016 85 * Contact: Martin Brandenburg <martin@omnibond.com> 86 * Description: 87 * Readahead cache buffer size. 88 * 89 * What: /sys/fs/orangefs/readahead_count_size 90 * Date: Aug 2016 91 * Contact: Martin Brandenburg <martin@omnibond.com> 92 * Description: 93 * Readahead cache buffer count and size. 94 * 95 * What: /sys/fs/orangefs/readahead_readcnt 96 * Date: Jan 2017 97 * Contact: Martin Brandenburg <martin@omnibond.com> 98 * Description: 99 * Number of buffers (in multiples of readahead_size) 100 * which can be read ahead for a single file at once. 101 * 102 * What: /sys/fs/orangefs/acache/... 103 * Date: Jun 2015 104 * Contact: Martin Brandenburg <martin@omnibond.com> 105 * Description: 106 * Attribute cache configurable settings. 107 * 108 * 109 * What: /sys/fs/orangefs/ncache/... 110 * Date: Jun 2015 111 * Contact: Mike Marshall <hubcap@omnibond.com> 112 * Description: 113 * Name cache configurable settings. 114 * 115 * 116 * What: /sys/fs/orangefs/capcache/... 117 * Date: Jun 2015 118 * Contact: Mike Marshall <hubcap@omnibond.com> 119 * Description: 120 * Capability cache configurable settings. 121 * 122 * 123 * What: /sys/fs/orangefs/ccache/... 124 * Date: Jun 2015 125 * Contact: Mike Marshall <hubcap@omnibond.com> 126 * Description: 127 * Credential cache configurable settings. 128 * 129 */ 130 131 #include <linux/fs.h> 132 #include <linux/kobject.h> 133 #include <linux/string.h> 134 #include <linux/sysfs.h> 135 #include <linux/module.h> 136 #include <linux/init.h> 137 138 #include "protocol.h" 139 #include "orangefs-kernel.h" 140 #include "orangefs-sysfs.h" 141 142 #define ORANGEFS_KOBJ_ID "orangefs" 143 #define ACACHE_KOBJ_ID "acache" 144 #define CAPCACHE_KOBJ_ID "capcache" 145 #define CCACHE_KOBJ_ID "ccache" 146 #define NCACHE_KOBJ_ID "ncache" 147 #define PC_KOBJ_ID "pc" 148 #define STATS_KOBJ_ID "stats" 149 150 /* 151 * Every item calls orangefs_attr_show and orangefs_attr_store through 152 * orangefs_sysfs_ops. They look at the orangefs_attributes further below to 153 * call one of sysfs_int_show, sysfs_int_store, sysfs_service_op_show, or 154 * sysfs_service_op_store. 155 */ 156 157 struct orangefs_attribute { 158 struct attribute attr; 159 ssize_t (*show)(struct kobject *kobj, 160 struct orangefs_attribute *attr, 161 char *buf); 162 ssize_t (*store)(struct kobject *kobj, 163 struct orangefs_attribute *attr, 164 const char *buf, 165 size_t count); 166 }; 167 168 static ssize_t orangefs_attr_show(struct kobject *kobj, 169 struct attribute *attr, 170 char *buf) 171 { 172 struct orangefs_attribute *attribute; 173 174 attribute = container_of(attr, struct orangefs_attribute, attr); 175 if (!attribute->show) 176 return -EIO; 177 return attribute->show(kobj, attribute, buf); 178 } 179 180 static ssize_t orangefs_attr_store(struct kobject *kobj, 181 struct attribute *attr, 182 const char *buf, 183 size_t len) 184 { 185 struct orangefs_attribute *attribute; 186 187 if (!strcmp(kobj->name, PC_KOBJ_ID) || 188 !strcmp(kobj->name, STATS_KOBJ_ID)) 189 return -EPERM; 190 191 attribute = container_of(attr, struct orangefs_attribute, attr); 192 if (!attribute->store) 193 return -EIO; 194 return attribute->store(kobj, attribute, buf, len); 195 } 196 197 static const struct sysfs_ops orangefs_sysfs_ops = { 198 .show = orangefs_attr_show, 199 .store = orangefs_attr_store, 200 }; 201 202 static ssize_t sysfs_int_show(struct kobject *kobj, 203 struct orangefs_attribute *attr, char *buf) 204 { 205 int rc = -EIO; 206 207 gossip_debug(GOSSIP_SYSFS_DEBUG, "sysfs_int_show: id:%s:\n", 208 kobj->name); 209 210 if (!strcmp(kobj->name, ORANGEFS_KOBJ_ID)) { 211 if (!strcmp(attr->attr.name, "op_timeout_secs")) { 212 rc = scnprintf(buf, 213 PAGE_SIZE, 214 "%d\n", 215 op_timeout_secs); 216 goto out; 217 } else if (!strcmp(attr->attr.name, 218 "slot_timeout_secs")) { 219 rc = scnprintf(buf, 220 PAGE_SIZE, 221 "%d\n", 222 slot_timeout_secs); 223 goto out; 224 } else if (!strcmp(attr->attr.name, 225 "dcache_timeout_msecs")) { 226 rc = scnprintf(buf, 227 PAGE_SIZE, 228 "%d\n", 229 orangefs_dcache_timeout_msecs); 230 goto out; 231 } else if (!strcmp(attr->attr.name, 232 "getattr_timeout_msecs")) { 233 rc = scnprintf(buf, 234 PAGE_SIZE, 235 "%d\n", 236 orangefs_getattr_timeout_msecs); 237 goto out; 238 } else { 239 goto out; 240 } 241 242 } else if (!strcmp(kobj->name, STATS_KOBJ_ID)) { 243 if (!strcmp(attr->attr.name, "reads")) { 244 rc = scnprintf(buf, 245 PAGE_SIZE, 246 "%lu\n", 247 orangefs_stats.reads); 248 goto out; 249 } else if (!strcmp(attr->attr.name, "writes")) { 250 rc = scnprintf(buf, 251 PAGE_SIZE, 252 "%lu\n", 253 orangefs_stats.writes); 254 goto out; 255 } else { 256 goto out; 257 } 258 } 259 260 out: 261 262 return rc; 263 } 264 265 static ssize_t sysfs_int_store(struct kobject *kobj, 266 struct orangefs_attribute *attr, const char *buf, size_t count) 267 { 268 int rc = 0; 269 270 gossip_debug(GOSSIP_SYSFS_DEBUG, 271 "sysfs_int_store: start attr->attr.name:%s: buf:%s:\n", 272 attr->attr.name, buf); 273 274 if (!strcmp(attr->attr.name, "op_timeout_secs")) { 275 rc = kstrtoint(buf, 0, &op_timeout_secs); 276 goto out; 277 } else if (!strcmp(attr->attr.name, "slot_timeout_secs")) { 278 rc = kstrtoint(buf, 0, &slot_timeout_secs); 279 goto out; 280 } else if (!strcmp(attr->attr.name, "dcache_timeout_msecs")) { 281 rc = kstrtoint(buf, 0, &orangefs_dcache_timeout_msecs); 282 goto out; 283 } else if (!strcmp(attr->attr.name, "getattr_timeout_msecs")) { 284 rc = kstrtoint(buf, 0, &orangefs_getattr_timeout_msecs); 285 goto out; 286 } else { 287 goto out; 288 } 289 290 out: 291 if (rc) 292 rc = -EINVAL; 293 else 294 rc = count; 295 296 return rc; 297 } 298 299 /* 300 * obtain attribute values from userspace with a service operation. 301 */ 302 static ssize_t sysfs_service_op_show(struct kobject *kobj, 303 struct orangefs_attribute *attr, char *buf) 304 { 305 struct orangefs_kernel_op_s *new_op = NULL; 306 int rc = 0; 307 char *ser_op_type = NULL; 308 __u32 op_alloc_type; 309 310 gossip_debug(GOSSIP_SYSFS_DEBUG, 311 "sysfs_service_op_show: id:%s:\n", 312 kobj->name); 313 314 if (strcmp(kobj->name, PC_KOBJ_ID)) 315 op_alloc_type = ORANGEFS_VFS_OP_PARAM; 316 else 317 op_alloc_type = ORANGEFS_VFS_OP_PERF_COUNT; 318 319 new_op = op_alloc(op_alloc_type); 320 if (!new_op) 321 return -ENOMEM; 322 323 /* Can't do a service_operation if the client is not running... */ 324 rc = is_daemon_in_service(); 325 if (rc) { 326 pr_info_ratelimited("%s: Client not running :%d:\n", 327 __func__, 328 is_daemon_in_service()); 329 goto out; 330 } 331 332 if (strcmp(kobj->name, PC_KOBJ_ID)) 333 new_op->upcall.req.param.type = ORANGEFS_PARAM_REQUEST_GET; 334 335 if (!strcmp(kobj->name, ORANGEFS_KOBJ_ID)) { 336 /* Drop unsupported requests first. */ 337 if (!(orangefs_features & ORANGEFS_FEATURE_READAHEAD) && 338 (!strcmp(attr->attr.name, "readahead_count") || 339 !strcmp(attr->attr.name, "readahead_size") || 340 !strcmp(attr->attr.name, "readahead_count_size") || 341 !strcmp(attr->attr.name, "readahead_readcnt"))) { 342 rc = -EINVAL; 343 goto out; 344 } 345 346 if (!strcmp(attr->attr.name, "perf_history_size")) 347 new_op->upcall.req.param.op = 348 ORANGEFS_PARAM_REQUEST_OP_PERF_HISTORY_SIZE; 349 else if (!strcmp(attr->attr.name, 350 "perf_time_interval_secs")) 351 new_op->upcall.req.param.op = 352 ORANGEFS_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS; 353 else if (!strcmp(attr->attr.name, 354 "perf_counter_reset")) 355 new_op->upcall.req.param.op = 356 ORANGEFS_PARAM_REQUEST_OP_PERF_RESET; 357 358 else if (!strcmp(attr->attr.name, 359 "readahead_count")) 360 new_op->upcall.req.param.op = 361 ORANGEFS_PARAM_REQUEST_OP_READAHEAD_COUNT; 362 363 else if (!strcmp(attr->attr.name, 364 "readahead_size")) 365 new_op->upcall.req.param.op = 366 ORANGEFS_PARAM_REQUEST_OP_READAHEAD_SIZE; 367 368 else if (!strcmp(attr->attr.name, 369 "readahead_count_size")) 370 new_op->upcall.req.param.op = 371 ORANGEFS_PARAM_REQUEST_OP_READAHEAD_COUNT_SIZE; 372 373 else if (!strcmp(attr->attr.name, 374 "readahead_readcnt")) 375 new_op->upcall.req.param.op = 376 ORANGEFS_PARAM_REQUEST_OP_READAHEAD_READCNT; 377 } else if (!strcmp(kobj->name, ACACHE_KOBJ_ID)) { 378 if (!strcmp(attr->attr.name, "timeout_msecs")) 379 new_op->upcall.req.param.op = 380 ORANGEFS_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS; 381 382 if (!strcmp(attr->attr.name, "hard_limit")) 383 new_op->upcall.req.param.op = 384 ORANGEFS_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT; 385 386 if (!strcmp(attr->attr.name, "soft_limit")) 387 new_op->upcall.req.param.op = 388 ORANGEFS_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT; 389 390 if (!strcmp(attr->attr.name, "reclaim_percentage")) 391 new_op->upcall.req.param.op = 392 ORANGEFS_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE; 393 394 } else if (!strcmp(kobj->name, CAPCACHE_KOBJ_ID)) { 395 if (!strcmp(attr->attr.name, "timeout_secs")) 396 new_op->upcall.req.param.op = 397 ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS; 398 399 if (!strcmp(attr->attr.name, "hard_limit")) 400 new_op->upcall.req.param.op = 401 ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT; 402 403 if (!strcmp(attr->attr.name, "soft_limit")) 404 new_op->upcall.req.param.op = 405 ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT; 406 407 if (!strcmp(attr->attr.name, "reclaim_percentage")) 408 new_op->upcall.req.param.op = 409 ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE; 410 411 } else if (!strcmp(kobj->name, CCACHE_KOBJ_ID)) { 412 if (!strcmp(attr->attr.name, "timeout_secs")) 413 new_op->upcall.req.param.op = 414 ORANGEFS_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS; 415 416 if (!strcmp(attr->attr.name, "hard_limit")) 417 new_op->upcall.req.param.op = 418 ORANGEFS_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT; 419 420 if (!strcmp(attr->attr.name, "soft_limit")) 421 new_op->upcall.req.param.op = 422 ORANGEFS_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT; 423 424 if (!strcmp(attr->attr.name, "reclaim_percentage")) 425 new_op->upcall.req.param.op = 426 ORANGEFS_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE; 427 428 } else if (!strcmp(kobj->name, NCACHE_KOBJ_ID)) { 429 if (!strcmp(attr->attr.name, "timeout_msecs")) 430 new_op->upcall.req.param.op = 431 ORANGEFS_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS; 432 433 if (!strcmp(attr->attr.name, "hard_limit")) 434 new_op->upcall.req.param.op = 435 ORANGEFS_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT; 436 437 if (!strcmp(attr->attr.name, "soft_limit")) 438 new_op->upcall.req.param.op = 439 ORANGEFS_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT; 440 441 if (!strcmp(attr->attr.name, "reclaim_percentage")) 442 new_op->upcall.req.param.op = 443 ORANGEFS_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE; 444 445 } else if (!strcmp(kobj->name, PC_KOBJ_ID)) { 446 if (!strcmp(attr->attr.name, ACACHE_KOBJ_ID)) 447 new_op->upcall.req.perf_count.type = 448 ORANGEFS_PERF_COUNT_REQUEST_ACACHE; 449 450 if (!strcmp(attr->attr.name, CAPCACHE_KOBJ_ID)) 451 new_op->upcall.req.perf_count.type = 452 ORANGEFS_PERF_COUNT_REQUEST_CAPCACHE; 453 454 if (!strcmp(attr->attr.name, NCACHE_KOBJ_ID)) 455 new_op->upcall.req.perf_count.type = 456 ORANGEFS_PERF_COUNT_REQUEST_NCACHE; 457 458 } else { 459 gossip_err("sysfs_service_op_show: unknown kobj_id:%s:\n", 460 kobj->name); 461 rc = -EINVAL; 462 goto out; 463 } 464 465 466 if (strcmp(kobj->name, PC_KOBJ_ID)) 467 ser_op_type = "orangefs_param"; 468 else 469 ser_op_type = "orangefs_perf_count"; 470 471 /* 472 * The service_operation will return an errno return code on 473 * error, and zero on success. 474 */ 475 rc = service_operation(new_op, ser_op_type, ORANGEFS_OP_INTERRUPTIBLE); 476 477 out: 478 if (!rc) { 479 if (strcmp(kobj->name, PC_KOBJ_ID)) { 480 if (new_op->upcall.req.param.op == 481 ORANGEFS_PARAM_REQUEST_OP_READAHEAD_COUNT_SIZE) { 482 rc = scnprintf(buf, PAGE_SIZE, "%d %d\n", 483 (int)new_op->downcall.resp.param.u. 484 value32[0], 485 (int)new_op->downcall.resp.param.u. 486 value32[1]); 487 } else { 488 rc = scnprintf(buf, PAGE_SIZE, "%d\n", 489 (int)new_op->downcall.resp.param.u.value64); 490 } 491 } else { 492 rc = scnprintf( 493 buf, 494 PAGE_SIZE, 495 "%s", 496 new_op->downcall.resp.perf_count.buffer); 497 } 498 } 499 500 op_release(new_op); 501 502 return rc; 503 504 } 505 506 /* 507 * pass attribute values back to userspace with a service operation. 508 * 509 * We have to do a memory allocation, an sscanf and a service operation. 510 * And we have to evaluate what the user entered, to make sure the 511 * value is within the range supported by the attribute. So, there's 512 * a lot of return code checking and mapping going on here. 513 * 514 * We want to return 1 if we think everything went OK, and 515 * EINVAL if not. 516 */ 517 static ssize_t sysfs_service_op_store(struct kobject *kobj, 518 struct orangefs_attribute *attr, const char *buf, size_t count) 519 { 520 struct orangefs_kernel_op_s *new_op = NULL; 521 int val = 0; 522 int rc = 0; 523 524 gossip_debug(GOSSIP_SYSFS_DEBUG, 525 "sysfs_service_op_store: id:%s:\n", 526 kobj->name); 527 528 new_op = op_alloc(ORANGEFS_VFS_OP_PARAM); 529 if (!new_op) 530 return -EINVAL; /* sic */ 531 532 /* Can't do a service_operation if the client is not running... */ 533 rc = is_daemon_in_service(); 534 if (rc) { 535 pr_info("%s: Client not running :%d:\n", 536 __func__, 537 is_daemon_in_service()); 538 goto out; 539 } 540 541 /* 542 * The value we want to send back to userspace is in buf, unless this 543 * there are two parameters, which is specially handled below. 544 */ 545 if (strcmp(kobj->name, ORANGEFS_KOBJ_ID) || 546 strcmp(attr->attr.name, "readahead_count_size")) { 547 rc = kstrtoint(buf, 0, &val); 548 if (rc) 549 goto out; 550 } 551 552 new_op->upcall.req.param.type = ORANGEFS_PARAM_REQUEST_SET; 553 554 if (!strcmp(kobj->name, ORANGEFS_KOBJ_ID)) { 555 /* Drop unsupported requests first. */ 556 if (!(orangefs_features & ORANGEFS_FEATURE_READAHEAD) && 557 (!strcmp(attr->attr.name, "readahead_count") || 558 !strcmp(attr->attr.name, "readahead_size") || 559 !strcmp(attr->attr.name, "readahead_count_size") || 560 !strcmp(attr->attr.name, "readahead_readcnt"))) { 561 rc = -EINVAL; 562 goto out; 563 } 564 565 if (!strcmp(attr->attr.name, "perf_history_size")) { 566 if (val > 0) { 567 new_op->upcall.req.param.op = 568 ORANGEFS_PARAM_REQUEST_OP_PERF_HISTORY_SIZE; 569 } else { 570 rc = 0; 571 goto out; 572 } 573 } else if (!strcmp(attr->attr.name, 574 "perf_time_interval_secs")) { 575 if (val > 0) { 576 new_op->upcall.req.param.op = 577 ORANGEFS_PARAM_REQUEST_OP_PERF_TIME_INTERVAL_SECS; 578 } else { 579 rc = 0; 580 goto out; 581 } 582 } else if (!strcmp(attr->attr.name, 583 "perf_counter_reset")) { 584 if ((val == 0) || (val == 1)) { 585 new_op->upcall.req.param.op = 586 ORANGEFS_PARAM_REQUEST_OP_PERF_RESET; 587 } else { 588 rc = 0; 589 goto out; 590 } 591 } else if (!strcmp(attr->attr.name, 592 "readahead_count")) { 593 if ((val >= 0)) { 594 new_op->upcall.req.param.op = 595 ORANGEFS_PARAM_REQUEST_OP_READAHEAD_COUNT; 596 } else { 597 rc = 0; 598 goto out; 599 } 600 } else if (!strcmp(attr->attr.name, 601 "readahead_size")) { 602 if ((val >= 0)) { 603 new_op->upcall.req.param.op = 604 ORANGEFS_PARAM_REQUEST_OP_READAHEAD_SIZE; 605 } else { 606 rc = 0; 607 goto out; 608 } 609 } else if (!strcmp(attr->attr.name, 610 "readahead_count_size")) { 611 int val1, val2; 612 rc = sscanf(buf, "%d %d", &val1, &val2); 613 if (rc < 2) { 614 rc = 0; 615 goto out; 616 } 617 if ((val1 >= 0) && (val2 >= 0)) { 618 new_op->upcall.req.param.op = 619 ORANGEFS_PARAM_REQUEST_OP_READAHEAD_COUNT_SIZE; 620 } else { 621 rc = 0; 622 goto out; 623 } 624 new_op->upcall.req.param.u.value32[0] = val1; 625 new_op->upcall.req.param.u.value32[1] = val2; 626 goto value_set; 627 } else if (!strcmp(attr->attr.name, 628 "readahead_readcnt")) { 629 if ((val >= 0)) { 630 new_op->upcall.req.param.op = 631 ORANGEFS_PARAM_REQUEST_OP_READAHEAD_READCNT; 632 } else { 633 rc = 0; 634 goto out; 635 } 636 } 637 638 } else if (!strcmp(kobj->name, ACACHE_KOBJ_ID)) { 639 if (!strcmp(attr->attr.name, "hard_limit")) { 640 if (val > -1) { 641 new_op->upcall.req.param.op = 642 ORANGEFS_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT; 643 } else { 644 rc = 0; 645 goto out; 646 } 647 } else if (!strcmp(attr->attr.name, "soft_limit")) { 648 if (val > -1) { 649 new_op->upcall.req.param.op = 650 ORANGEFS_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT; 651 } else { 652 rc = 0; 653 goto out; 654 } 655 } else if (!strcmp(attr->attr.name, 656 "reclaim_percentage")) { 657 if ((val > -1) && (val < 101)) { 658 new_op->upcall.req.param.op = 659 ORANGEFS_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE; 660 } else { 661 rc = 0; 662 goto out; 663 } 664 } else if (!strcmp(attr->attr.name, "timeout_msecs")) { 665 if (val > -1) { 666 new_op->upcall.req.param.op = 667 ORANGEFS_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS; 668 } else { 669 rc = 0; 670 goto out; 671 } 672 } 673 674 } else if (!strcmp(kobj->name, CAPCACHE_KOBJ_ID)) { 675 if (!strcmp(attr->attr.name, "hard_limit")) { 676 if (val > -1) { 677 new_op->upcall.req.param.op = 678 ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT; 679 } else { 680 rc = 0; 681 goto out; 682 } 683 } else if (!strcmp(attr->attr.name, "soft_limit")) { 684 if (val > -1) { 685 new_op->upcall.req.param.op = 686 ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT; 687 } else { 688 rc = 0; 689 goto out; 690 } 691 } else if (!strcmp(attr->attr.name, 692 "reclaim_percentage")) { 693 if ((val > -1) && (val < 101)) { 694 new_op->upcall.req.param.op = 695 ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE; 696 } else { 697 rc = 0; 698 goto out; 699 } 700 } else if (!strcmp(attr->attr.name, "timeout_secs")) { 701 if (val > -1) { 702 new_op->upcall.req.param.op = 703 ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS; 704 } else { 705 rc = 0; 706 goto out; 707 } 708 } 709 710 } else if (!strcmp(kobj->name, CCACHE_KOBJ_ID)) { 711 if (!strcmp(attr->attr.name, "hard_limit")) { 712 if (val > -1) { 713 new_op->upcall.req.param.op = 714 ORANGEFS_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT; 715 } else { 716 rc = 0; 717 goto out; 718 } 719 } else if (!strcmp(attr->attr.name, "soft_limit")) { 720 if (val > -1) { 721 new_op->upcall.req.param.op = 722 ORANGEFS_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT; 723 } else { 724 rc = 0; 725 goto out; 726 } 727 } else if (!strcmp(attr->attr.name, 728 "reclaim_percentage")) { 729 if ((val > -1) && (val < 101)) { 730 new_op->upcall.req.param.op = 731 ORANGEFS_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE; 732 } else { 733 rc = 0; 734 goto out; 735 } 736 } else if (!strcmp(attr->attr.name, "timeout_secs")) { 737 if (val > -1) { 738 new_op->upcall.req.param.op = 739 ORANGEFS_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS; 740 } else { 741 rc = 0; 742 goto out; 743 } 744 } 745 746 } else if (!strcmp(kobj->name, NCACHE_KOBJ_ID)) { 747 if (!strcmp(attr->attr.name, "hard_limit")) { 748 if (val > -1) { 749 new_op->upcall.req.param.op = 750 ORANGEFS_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT; 751 } else { 752 rc = 0; 753 goto out; 754 } 755 } else if (!strcmp(attr->attr.name, "soft_limit")) { 756 if (val > -1) { 757 new_op->upcall.req.param.op = 758 ORANGEFS_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT; 759 } else { 760 rc = 0; 761 goto out; 762 } 763 } else if (!strcmp(attr->attr.name, 764 "reclaim_percentage")) { 765 if ((val > -1) && (val < 101)) { 766 new_op->upcall.req.param.op = 767 ORANGEFS_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE; 768 } else { 769 rc = 0; 770 goto out; 771 } 772 } else if (!strcmp(attr->attr.name, "timeout_msecs")) { 773 if (val > -1) { 774 new_op->upcall.req.param.op = 775 ORANGEFS_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS; 776 } else { 777 rc = 0; 778 goto out; 779 } 780 } 781 782 } else { 783 gossip_err("sysfs_service_op_store: unknown kobj_id:%s:\n", 784 kobj->name); 785 rc = -EINVAL; 786 goto out; 787 } 788 789 new_op->upcall.req.param.u.value64 = val; 790 value_set: 791 792 /* 793 * The service_operation will return a errno return code on 794 * error, and zero on success. 795 */ 796 rc = service_operation(new_op, "orangefs_param", ORANGEFS_OP_INTERRUPTIBLE); 797 798 if (rc < 0) { 799 gossip_err("sysfs_service_op_store: service op returned:%d:\n", 800 rc); 801 rc = 0; 802 } else { 803 rc = count; 804 } 805 806 out: 807 op_release(new_op); 808 809 if (rc == -ENOMEM || rc == 0) 810 rc = -EINVAL; 811 812 return rc; 813 } 814 815 static struct orangefs_attribute op_timeout_secs_attribute = 816 __ATTR(op_timeout_secs, 0664, sysfs_int_show, sysfs_int_store); 817 818 static struct orangefs_attribute slot_timeout_secs_attribute = 819 __ATTR(slot_timeout_secs, 0664, sysfs_int_show, sysfs_int_store); 820 821 static struct orangefs_attribute dcache_timeout_msecs_attribute = 822 __ATTR(dcache_timeout_msecs, 0664, sysfs_int_show, sysfs_int_store); 823 824 static struct orangefs_attribute getattr_timeout_msecs_attribute = 825 __ATTR(getattr_timeout_msecs, 0664, sysfs_int_show, sysfs_int_store); 826 827 static struct orangefs_attribute readahead_count_attribute = 828 __ATTR(readahead_count, 0664, sysfs_service_op_show, 829 sysfs_service_op_store); 830 831 static struct orangefs_attribute readahead_size_attribute = 832 __ATTR(readahead_size, 0664, sysfs_service_op_show, 833 sysfs_service_op_store); 834 835 static struct orangefs_attribute readahead_count_size_attribute = 836 __ATTR(readahead_count_size, 0664, sysfs_service_op_show, 837 sysfs_service_op_store); 838 839 static struct orangefs_attribute readahead_readcnt_attribute = 840 __ATTR(readahead_readcnt, 0664, sysfs_service_op_show, 841 sysfs_service_op_store); 842 843 static struct orangefs_attribute perf_counter_reset_attribute = 844 __ATTR(perf_counter_reset, 845 0664, 846 sysfs_service_op_show, 847 sysfs_service_op_store); 848 849 static struct orangefs_attribute perf_history_size_attribute = 850 __ATTR(perf_history_size, 851 0664, 852 sysfs_service_op_show, 853 sysfs_service_op_store); 854 855 static struct orangefs_attribute perf_time_interval_secs_attribute = 856 __ATTR(perf_time_interval_secs, 857 0664, 858 sysfs_service_op_show, 859 sysfs_service_op_store); 860 861 static struct attribute *orangefs_default_attrs[] = { 862 &op_timeout_secs_attribute.attr, 863 &slot_timeout_secs_attribute.attr, 864 &dcache_timeout_msecs_attribute.attr, 865 &getattr_timeout_msecs_attribute.attr, 866 &readahead_count_attribute.attr, 867 &readahead_size_attribute.attr, 868 &readahead_count_size_attribute.attr, 869 &readahead_readcnt_attribute.attr, 870 &perf_counter_reset_attribute.attr, 871 &perf_history_size_attribute.attr, 872 &perf_time_interval_secs_attribute.attr, 873 NULL, 874 }; 875 876 static struct kobj_type orangefs_ktype = { 877 .sysfs_ops = &orangefs_sysfs_ops, 878 .default_attrs = orangefs_default_attrs, 879 }; 880 881 static struct orangefs_attribute acache_hard_limit_attribute = 882 __ATTR(hard_limit, 883 0664, 884 sysfs_service_op_show, 885 sysfs_service_op_store); 886 887 static struct orangefs_attribute acache_reclaim_percent_attribute = 888 __ATTR(reclaim_percentage, 889 0664, 890 sysfs_service_op_show, 891 sysfs_service_op_store); 892 893 static struct orangefs_attribute acache_soft_limit_attribute = 894 __ATTR(soft_limit, 895 0664, 896 sysfs_service_op_show, 897 sysfs_service_op_store); 898 899 static struct orangefs_attribute acache_timeout_msecs_attribute = 900 __ATTR(timeout_msecs, 901 0664, 902 sysfs_service_op_show, 903 sysfs_service_op_store); 904 905 static struct attribute *acache_orangefs_default_attrs[] = { 906 &acache_hard_limit_attribute.attr, 907 &acache_reclaim_percent_attribute.attr, 908 &acache_soft_limit_attribute.attr, 909 &acache_timeout_msecs_attribute.attr, 910 NULL, 911 }; 912 913 static struct kobj_type acache_orangefs_ktype = { 914 .sysfs_ops = &orangefs_sysfs_ops, 915 .default_attrs = acache_orangefs_default_attrs, 916 }; 917 918 static struct orangefs_attribute capcache_hard_limit_attribute = 919 __ATTR(hard_limit, 920 0664, 921 sysfs_service_op_show, 922 sysfs_service_op_store); 923 924 static struct orangefs_attribute capcache_reclaim_percent_attribute = 925 __ATTR(reclaim_percentage, 926 0664, 927 sysfs_service_op_show, 928 sysfs_service_op_store); 929 930 static struct orangefs_attribute capcache_soft_limit_attribute = 931 __ATTR(soft_limit, 932 0664, 933 sysfs_service_op_show, 934 sysfs_service_op_store); 935 936 static struct orangefs_attribute capcache_timeout_secs_attribute = 937 __ATTR(timeout_secs, 938 0664, 939 sysfs_service_op_show, 940 sysfs_service_op_store); 941 942 static struct attribute *capcache_orangefs_default_attrs[] = { 943 &capcache_hard_limit_attribute.attr, 944 &capcache_reclaim_percent_attribute.attr, 945 &capcache_soft_limit_attribute.attr, 946 &capcache_timeout_secs_attribute.attr, 947 NULL, 948 }; 949 950 static struct kobj_type capcache_orangefs_ktype = { 951 .sysfs_ops = &orangefs_sysfs_ops, 952 .default_attrs = capcache_orangefs_default_attrs, 953 }; 954 955 static struct orangefs_attribute ccache_hard_limit_attribute = 956 __ATTR(hard_limit, 957 0664, 958 sysfs_service_op_show, 959 sysfs_service_op_store); 960 961 static struct orangefs_attribute ccache_reclaim_percent_attribute = 962 __ATTR(reclaim_percentage, 963 0664, 964 sysfs_service_op_show, 965 sysfs_service_op_store); 966 967 static struct orangefs_attribute ccache_soft_limit_attribute = 968 __ATTR(soft_limit, 969 0664, 970 sysfs_service_op_show, 971 sysfs_service_op_store); 972 973 static struct orangefs_attribute ccache_timeout_secs_attribute = 974 __ATTR(timeout_secs, 975 0664, 976 sysfs_service_op_show, 977 sysfs_service_op_store); 978 979 static struct attribute *ccache_orangefs_default_attrs[] = { 980 &ccache_hard_limit_attribute.attr, 981 &ccache_reclaim_percent_attribute.attr, 982 &ccache_soft_limit_attribute.attr, 983 &ccache_timeout_secs_attribute.attr, 984 NULL, 985 }; 986 987 static struct kobj_type ccache_orangefs_ktype = { 988 .sysfs_ops = &orangefs_sysfs_ops, 989 .default_attrs = ccache_orangefs_default_attrs, 990 }; 991 992 static struct orangefs_attribute ncache_hard_limit_attribute = 993 __ATTR(hard_limit, 994 0664, 995 sysfs_service_op_show, 996 sysfs_service_op_store); 997 998 static struct orangefs_attribute ncache_reclaim_percent_attribute = 999 __ATTR(reclaim_percentage, 1000 0664, 1001 sysfs_service_op_show, 1002 sysfs_service_op_store); 1003 1004 static struct orangefs_attribute ncache_soft_limit_attribute = 1005 __ATTR(soft_limit, 1006 0664, 1007 sysfs_service_op_show, 1008 sysfs_service_op_store); 1009 1010 static struct orangefs_attribute ncache_timeout_msecs_attribute = 1011 __ATTR(timeout_msecs, 1012 0664, 1013 sysfs_service_op_show, 1014 sysfs_service_op_store); 1015 1016 static struct attribute *ncache_orangefs_default_attrs[] = { 1017 &ncache_hard_limit_attribute.attr, 1018 &ncache_reclaim_percent_attribute.attr, 1019 &ncache_soft_limit_attribute.attr, 1020 &ncache_timeout_msecs_attribute.attr, 1021 NULL, 1022 }; 1023 1024 static struct kobj_type ncache_orangefs_ktype = { 1025 .sysfs_ops = &orangefs_sysfs_ops, 1026 .default_attrs = ncache_orangefs_default_attrs, 1027 }; 1028 1029 static struct orangefs_attribute pc_acache_attribute = 1030 __ATTR(acache, 1031 0664, 1032 sysfs_service_op_show, 1033 NULL); 1034 1035 static struct orangefs_attribute pc_capcache_attribute = 1036 __ATTR(capcache, 1037 0664, 1038 sysfs_service_op_show, 1039 NULL); 1040 1041 static struct orangefs_attribute pc_ncache_attribute = 1042 __ATTR(ncache, 1043 0664, 1044 sysfs_service_op_show, 1045 NULL); 1046 1047 static struct attribute *pc_orangefs_default_attrs[] = { 1048 &pc_acache_attribute.attr, 1049 &pc_capcache_attribute.attr, 1050 &pc_ncache_attribute.attr, 1051 NULL, 1052 }; 1053 1054 static struct kobj_type pc_orangefs_ktype = { 1055 .sysfs_ops = &orangefs_sysfs_ops, 1056 .default_attrs = pc_orangefs_default_attrs, 1057 }; 1058 1059 static struct orangefs_attribute stats_reads_attribute = 1060 __ATTR(reads, 1061 0664, 1062 sysfs_int_show, 1063 NULL); 1064 1065 static struct orangefs_attribute stats_writes_attribute = 1066 __ATTR(writes, 1067 0664, 1068 sysfs_int_show, 1069 NULL); 1070 1071 static struct attribute *stats_orangefs_default_attrs[] = { 1072 &stats_reads_attribute.attr, 1073 &stats_writes_attribute.attr, 1074 NULL, 1075 }; 1076 1077 static struct kobj_type stats_orangefs_ktype = { 1078 .sysfs_ops = &orangefs_sysfs_ops, 1079 .default_attrs = stats_orangefs_default_attrs, 1080 }; 1081 1082 static struct kobject *orangefs_obj; 1083 static struct kobject *acache_orangefs_obj; 1084 static struct kobject *capcache_orangefs_obj; 1085 static struct kobject *ccache_orangefs_obj; 1086 static struct kobject *ncache_orangefs_obj; 1087 static struct kobject *pc_orangefs_obj; 1088 static struct kobject *stats_orangefs_obj; 1089 1090 int orangefs_sysfs_init(void) 1091 { 1092 int rc = -EINVAL; 1093 1094 gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_init: start\n"); 1095 1096 /* create /sys/fs/orangefs. */ 1097 orangefs_obj = kzalloc(sizeof(*orangefs_obj), GFP_KERNEL); 1098 if (!orangefs_obj) 1099 goto out; 1100 1101 rc = kobject_init_and_add(orangefs_obj, 1102 &orangefs_ktype, 1103 fs_kobj, 1104 ORANGEFS_KOBJ_ID); 1105 1106 if (rc) 1107 goto ofs_obj_bail; 1108 1109 kobject_uevent(orangefs_obj, KOBJ_ADD); 1110 1111 /* create /sys/fs/orangefs/acache. */ 1112 acache_orangefs_obj = kzalloc(sizeof(*acache_orangefs_obj), GFP_KERNEL); 1113 if (!acache_orangefs_obj) { 1114 rc = -EINVAL; 1115 goto ofs_obj_bail; 1116 } 1117 1118 rc = kobject_init_and_add(acache_orangefs_obj, 1119 &acache_orangefs_ktype, 1120 orangefs_obj, 1121 ACACHE_KOBJ_ID); 1122 1123 if (rc) 1124 goto acache_obj_bail; 1125 1126 kobject_uevent(acache_orangefs_obj, KOBJ_ADD); 1127 1128 /* create /sys/fs/orangefs/capcache. */ 1129 capcache_orangefs_obj = 1130 kzalloc(sizeof(*capcache_orangefs_obj), GFP_KERNEL); 1131 if (!capcache_orangefs_obj) { 1132 rc = -EINVAL; 1133 goto acache_obj_bail; 1134 } 1135 1136 rc = kobject_init_and_add(capcache_orangefs_obj, 1137 &capcache_orangefs_ktype, 1138 orangefs_obj, 1139 CAPCACHE_KOBJ_ID); 1140 if (rc) 1141 goto capcache_obj_bail; 1142 1143 kobject_uevent(capcache_orangefs_obj, KOBJ_ADD); 1144 1145 /* create /sys/fs/orangefs/ccache. */ 1146 ccache_orangefs_obj = 1147 kzalloc(sizeof(*ccache_orangefs_obj), GFP_KERNEL); 1148 if (!ccache_orangefs_obj) { 1149 rc = -EINVAL; 1150 goto capcache_obj_bail; 1151 } 1152 1153 rc = kobject_init_and_add(ccache_orangefs_obj, 1154 &ccache_orangefs_ktype, 1155 orangefs_obj, 1156 CCACHE_KOBJ_ID); 1157 if (rc) 1158 goto ccache_obj_bail; 1159 1160 kobject_uevent(ccache_orangefs_obj, KOBJ_ADD); 1161 1162 /* create /sys/fs/orangefs/ncache. */ 1163 ncache_orangefs_obj = kzalloc(sizeof(*ncache_orangefs_obj), GFP_KERNEL); 1164 if (!ncache_orangefs_obj) { 1165 rc = -EINVAL; 1166 goto ccache_obj_bail; 1167 } 1168 1169 rc = kobject_init_and_add(ncache_orangefs_obj, 1170 &ncache_orangefs_ktype, 1171 orangefs_obj, 1172 NCACHE_KOBJ_ID); 1173 1174 if (rc) 1175 goto ncache_obj_bail; 1176 1177 kobject_uevent(ncache_orangefs_obj, KOBJ_ADD); 1178 1179 /* create /sys/fs/orangefs/perf_counters. */ 1180 pc_orangefs_obj = kzalloc(sizeof(*pc_orangefs_obj), GFP_KERNEL); 1181 if (!pc_orangefs_obj) { 1182 rc = -EINVAL; 1183 goto ncache_obj_bail; 1184 } 1185 1186 rc = kobject_init_and_add(pc_orangefs_obj, 1187 &pc_orangefs_ktype, 1188 orangefs_obj, 1189 "perf_counters"); 1190 1191 if (rc) 1192 goto pc_obj_bail; 1193 1194 kobject_uevent(pc_orangefs_obj, KOBJ_ADD); 1195 1196 /* create /sys/fs/orangefs/stats. */ 1197 stats_orangefs_obj = kzalloc(sizeof(*stats_orangefs_obj), GFP_KERNEL); 1198 if (!stats_orangefs_obj) { 1199 rc = -EINVAL; 1200 goto pc_obj_bail; 1201 } 1202 1203 rc = kobject_init_and_add(stats_orangefs_obj, 1204 &stats_orangefs_ktype, 1205 orangefs_obj, 1206 STATS_KOBJ_ID); 1207 1208 if (rc) 1209 goto stats_obj_bail; 1210 1211 kobject_uevent(stats_orangefs_obj, KOBJ_ADD); 1212 goto out; 1213 1214 stats_obj_bail: 1215 kobject_put(stats_orangefs_obj); 1216 pc_obj_bail: 1217 kobject_put(pc_orangefs_obj); 1218 ncache_obj_bail: 1219 kobject_put(ncache_orangefs_obj); 1220 ccache_obj_bail: 1221 kobject_put(ccache_orangefs_obj); 1222 capcache_obj_bail: 1223 kobject_put(capcache_orangefs_obj); 1224 acache_obj_bail: 1225 kobject_put(acache_orangefs_obj); 1226 ofs_obj_bail: 1227 kobject_put(orangefs_obj); 1228 out: 1229 return rc; 1230 } 1231 1232 void orangefs_sysfs_exit(void) 1233 { 1234 gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_exit: start\n"); 1235 kobject_put(acache_orangefs_obj); 1236 kobject_put(capcache_orangefs_obj); 1237 kobject_put(ccache_orangefs_obj); 1238 kobject_put(ncache_orangefs_obj); 1239 kobject_put(pc_orangefs_obj); 1240 kobject_put(stats_orangefs_obj); 1241 kobject_put(orangefs_obj); 1242 } 1243