1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Documentation/ABI/stable/sysfs-fs-orangefs: 4 * 5 * What: /sys/fs/orangefs/perf_counter_reset 6 * Date: June 2015 7 * Contact: Mike Marshall <hubcap@omnibond.com> 8 * Description: 9 * echo a 0 or a 1 into perf_counter_reset to 10 * reset all the counters in 11 * /sys/fs/orangefs/perf_counters 12 * except ones with PINT_PERF_PRESERVE set. 13 * 14 * 15 * What: /sys/fs/orangefs/perf_counters/... 16 * Date: Jun 2015 17 * Contact: Mike Marshall <hubcap@omnibond.com> 18 * Description: 19 * Counters and settings for various caches. 20 * Read only. 21 * 22 * 23 * What: /sys/fs/orangefs/perf_time_interval_secs 24 * Date: Jun 2015 25 * Contact: Mike Marshall <hubcap@omnibond.com> 26 * Description: 27 * Length of perf counter intervals in 28 * seconds. 29 * 30 * 31 * What: /sys/fs/orangefs/perf_history_size 32 * Date: Jun 2015 33 * Contact: Mike Marshall <hubcap@omnibond.com> 34 * Description: 35 * The perf_counters cache statistics have N, or 36 * perf_history_size, samples. The default is 37 * one. 38 * 39 * Every perf_time_interval_secs the (first) 40 * samples are reset. 41 * 42 * If N is greater than one, the "current" set 43 * of samples is reset, and the samples from the 44 * other N-1 intervals remain available. 45 * 46 * 47 * What: /sys/fs/orangefs/op_timeout_secs 48 * Date: Jun 2015 49 * Contact: Mike Marshall <hubcap@omnibond.com> 50 * Description: 51 * Service operation timeout in seconds. 52 * 53 * 54 * What: /sys/fs/orangefs/slot_timeout_secs 55 * Date: Jun 2015 56 * Contact: Mike Marshall <hubcap@omnibond.com> 57 * Description: 58 * "Slot" timeout in seconds. A "slot" 59 * is an indexed buffer in the shared 60 * memory segment used for communication 61 * between the kernel module and userspace. 62 * Slots are requested and waited for, 63 * the wait times out after slot_timeout_secs. 64 * 65 * What: /sys/fs/orangefs/cache_timeout_msecs 66 * Date: Mar 2018 67 * Contact: Martin Brandenburg <martin@omnibond.com> 68 * Description: 69 * Time in milliseconds between which 70 * orangefs_revalidate_mapping will invalidate the page 71 * cache. 72 * 73 * What: /sys/fs/orangefs/dcache_timeout_msecs 74 * Date: Jul 2016 75 * Contact: Martin Brandenburg <martin@omnibond.com> 76 * Description: 77 * Time lookup is valid in milliseconds. 78 * 79 * What: /sys/fs/orangefs/getattr_timeout_msecs 80 * Date: Jul 2016 81 * Contact: Martin Brandenburg <martin@omnibond.com> 82 * Description: 83 * Time getattr is valid in milliseconds. 84 * 85 * What: /sys/fs/orangefs/readahead_count 86 * Date: Aug 2016 87 * Contact: Martin Brandenburg <martin@omnibond.com> 88 * Description: 89 * Readahead cache buffer count. 90 * 91 * What: /sys/fs/orangefs/readahead_size 92 * Date: Aug 2016 93 * Contact: Martin Brandenburg <martin@omnibond.com> 94 * Description: 95 * Readahead cache buffer size. 96 * 97 * What: /sys/fs/orangefs/readahead_count_size 98 * Date: Aug 2016 99 * Contact: Martin Brandenburg <martin@omnibond.com> 100 * Description: 101 * Readahead cache buffer count and size. 102 * 103 * What: /sys/fs/orangefs/readahead_readcnt 104 * Date: Jan 2017 105 * Contact: Martin Brandenburg <martin@omnibond.com> 106 * Description: 107 * Number of buffers (in multiples of readahead_size) 108 * which can be read ahead for a single file at once. 109 * 110 * What: /sys/fs/orangefs/acache/... 111 * Date: Jun 2015 112 * Contact: Martin Brandenburg <martin@omnibond.com> 113 * Description: 114 * Attribute cache configurable settings. 115 * 116 * 117 * What: /sys/fs/orangefs/ncache/... 118 * Date: Jun 2015 119 * Contact: Mike Marshall <hubcap@omnibond.com> 120 * Description: 121 * Name cache configurable settings. 122 * 123 * 124 * What: /sys/fs/orangefs/capcache/... 125 * Date: Jun 2015 126 * Contact: Mike Marshall <hubcap@omnibond.com> 127 * Description: 128 * Capability cache configurable settings. 129 * 130 * 131 * What: /sys/fs/orangefs/ccache/... 132 * Date: Jun 2015 133 * Contact: Mike Marshall <hubcap@omnibond.com> 134 * Description: 135 * Credential cache configurable settings. 136 * 137 */ 138 139 #include <linux/fs.h> 140 #include <linux/kobject.h> 141 #include <linux/string.h> 142 #include <linux/sysfs.h> 143 #include <linux/module.h> 144 #include <linux/init.h> 145 146 #include "protocol.h" 147 #include "orangefs-kernel.h" 148 #include "orangefs-sysfs.h" 149 150 #define ORANGEFS_KOBJ_ID "orangefs" 151 #define ACACHE_KOBJ_ID "acache" 152 #define CAPCACHE_KOBJ_ID "capcache" 153 #define CCACHE_KOBJ_ID "ccache" 154 #define NCACHE_KOBJ_ID "ncache" 155 #define PC_KOBJ_ID "pc" 156 #define STATS_KOBJ_ID "stats" 157 158 /* 159 * Every item calls orangefs_attr_show and orangefs_attr_store through 160 * orangefs_sysfs_ops. They look at the orangefs_attributes further below to 161 * call one of sysfs_int_show, sysfs_int_store, sysfs_service_op_show, or 162 * sysfs_service_op_store. 163 */ 164 165 struct orangefs_attribute { 166 struct attribute attr; 167 ssize_t (*show)(struct kobject *kobj, 168 struct orangefs_attribute *attr, 169 char *buf); 170 ssize_t (*store)(struct kobject *kobj, 171 struct orangefs_attribute *attr, 172 const char *buf, 173 size_t count); 174 }; 175 176 static ssize_t orangefs_attr_show(struct kobject *kobj, 177 struct attribute *attr, 178 char *buf) 179 { 180 struct orangefs_attribute *attribute; 181 182 attribute = container_of(attr, struct orangefs_attribute, attr); 183 if (!attribute->show) 184 return -EIO; 185 return attribute->show(kobj, attribute, buf); 186 } 187 188 static ssize_t orangefs_attr_store(struct kobject *kobj, 189 struct attribute *attr, 190 const char *buf, 191 size_t len) 192 { 193 struct orangefs_attribute *attribute; 194 195 if (!strcmp(kobj->name, PC_KOBJ_ID) || 196 !strcmp(kobj->name, STATS_KOBJ_ID)) 197 return -EPERM; 198 199 attribute = container_of(attr, struct orangefs_attribute, attr); 200 if (!attribute->store) 201 return -EIO; 202 return attribute->store(kobj, attribute, buf, len); 203 } 204 205 static const struct sysfs_ops orangefs_sysfs_ops = { 206 .show = orangefs_attr_show, 207 .store = orangefs_attr_store, 208 }; 209 210 static ssize_t sysfs_int_show(struct kobject *kobj, 211 struct orangefs_attribute *attr, char *buf) 212 { 213 int rc = -EIO; 214 215 gossip_debug(GOSSIP_SYSFS_DEBUG, "sysfs_int_show: id:%s:\n", 216 kobj->name); 217 218 if (!strcmp(kobj->name, ORANGEFS_KOBJ_ID)) { 219 if (!strcmp(attr->attr.name, "op_timeout_secs")) { 220 rc = 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 275 out: 276 277 return rc; 278 } 279 280 static 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 308 out: 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 */ 320 static 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 495 out: 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 */ 535 static 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; 808 value_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 824 out: 825 op_release(new_op); 826 827 if (rc == -ENOMEM || rc == 0) 828 rc = -EINVAL; 829 830 return rc; 831 } 832 833 static struct orangefs_attribute op_timeout_secs_attribute = 834 __ATTR(op_timeout_secs, 0664, sysfs_int_show, sysfs_int_store); 835 836 static struct orangefs_attribute slot_timeout_secs_attribute = 837 __ATTR(slot_timeout_secs, 0664, sysfs_int_show, sysfs_int_store); 838 839 static struct orangefs_attribute cache_timeout_msecs_attribute = 840 __ATTR(cache_timeout_msecs, 0664, sysfs_int_show, sysfs_int_store); 841 842 static struct orangefs_attribute dcache_timeout_msecs_attribute = 843 __ATTR(dcache_timeout_msecs, 0664, sysfs_int_show, sysfs_int_store); 844 845 static struct orangefs_attribute getattr_timeout_msecs_attribute = 846 __ATTR(getattr_timeout_msecs, 0664, sysfs_int_show, sysfs_int_store); 847 848 static struct orangefs_attribute readahead_count_attribute = 849 __ATTR(readahead_count, 0664, sysfs_service_op_show, 850 sysfs_service_op_store); 851 852 static struct orangefs_attribute readahead_size_attribute = 853 __ATTR(readahead_size, 0664, sysfs_service_op_show, 854 sysfs_service_op_store); 855 856 static struct orangefs_attribute readahead_count_size_attribute = 857 __ATTR(readahead_count_size, 0664, sysfs_service_op_show, 858 sysfs_service_op_store); 859 860 static struct orangefs_attribute readahead_readcnt_attribute = 861 __ATTR(readahead_readcnt, 0664, sysfs_service_op_show, 862 sysfs_service_op_store); 863 864 static 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 870 static 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 876 static 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 882 static 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 ATTRIBUTE_GROUPS(orangefs_default); 898 899 static struct kobj_type orangefs_ktype = { 900 .sysfs_ops = &orangefs_sysfs_ops, 901 .default_groups = orangefs_default_groups, 902 }; 903 904 static struct orangefs_attribute acache_hard_limit_attribute = 905 __ATTR(hard_limit, 906 0664, 907 sysfs_service_op_show, 908 sysfs_service_op_store); 909 910 static struct orangefs_attribute acache_reclaim_percent_attribute = 911 __ATTR(reclaim_percentage, 912 0664, 913 sysfs_service_op_show, 914 sysfs_service_op_store); 915 916 static struct orangefs_attribute acache_soft_limit_attribute = 917 __ATTR(soft_limit, 918 0664, 919 sysfs_service_op_show, 920 sysfs_service_op_store); 921 922 static struct orangefs_attribute acache_timeout_msecs_attribute = 923 __ATTR(timeout_msecs, 924 0664, 925 sysfs_service_op_show, 926 sysfs_service_op_store); 927 928 static struct attribute *acache_orangefs_default_attrs[] = { 929 &acache_hard_limit_attribute.attr, 930 &acache_reclaim_percent_attribute.attr, 931 &acache_soft_limit_attribute.attr, 932 &acache_timeout_msecs_attribute.attr, 933 NULL, 934 }; 935 ATTRIBUTE_GROUPS(acache_orangefs_default); 936 937 static struct kobj_type acache_orangefs_ktype = { 938 .sysfs_ops = &orangefs_sysfs_ops, 939 .default_groups = acache_orangefs_default_groups, 940 }; 941 942 static struct orangefs_attribute capcache_hard_limit_attribute = 943 __ATTR(hard_limit, 944 0664, 945 sysfs_service_op_show, 946 sysfs_service_op_store); 947 948 static struct orangefs_attribute capcache_reclaim_percent_attribute = 949 __ATTR(reclaim_percentage, 950 0664, 951 sysfs_service_op_show, 952 sysfs_service_op_store); 953 954 static struct orangefs_attribute capcache_soft_limit_attribute = 955 __ATTR(soft_limit, 956 0664, 957 sysfs_service_op_show, 958 sysfs_service_op_store); 959 960 static struct orangefs_attribute capcache_timeout_secs_attribute = 961 __ATTR(timeout_secs, 962 0664, 963 sysfs_service_op_show, 964 sysfs_service_op_store); 965 966 static struct attribute *capcache_orangefs_default_attrs[] = { 967 &capcache_hard_limit_attribute.attr, 968 &capcache_reclaim_percent_attribute.attr, 969 &capcache_soft_limit_attribute.attr, 970 &capcache_timeout_secs_attribute.attr, 971 NULL, 972 }; 973 ATTRIBUTE_GROUPS(capcache_orangefs_default); 974 975 static struct kobj_type capcache_orangefs_ktype = { 976 .sysfs_ops = &orangefs_sysfs_ops, 977 .default_groups = capcache_orangefs_default_groups, 978 }; 979 980 static struct orangefs_attribute ccache_hard_limit_attribute = 981 __ATTR(hard_limit, 982 0664, 983 sysfs_service_op_show, 984 sysfs_service_op_store); 985 986 static struct orangefs_attribute ccache_reclaim_percent_attribute = 987 __ATTR(reclaim_percentage, 988 0664, 989 sysfs_service_op_show, 990 sysfs_service_op_store); 991 992 static struct orangefs_attribute ccache_soft_limit_attribute = 993 __ATTR(soft_limit, 994 0664, 995 sysfs_service_op_show, 996 sysfs_service_op_store); 997 998 static struct orangefs_attribute ccache_timeout_secs_attribute = 999 __ATTR(timeout_secs, 1000 0664, 1001 sysfs_service_op_show, 1002 sysfs_service_op_store); 1003 1004 static struct attribute *ccache_orangefs_default_attrs[] = { 1005 &ccache_hard_limit_attribute.attr, 1006 &ccache_reclaim_percent_attribute.attr, 1007 &ccache_soft_limit_attribute.attr, 1008 &ccache_timeout_secs_attribute.attr, 1009 NULL, 1010 }; 1011 ATTRIBUTE_GROUPS(ccache_orangefs_default); 1012 1013 static struct kobj_type ccache_orangefs_ktype = { 1014 .sysfs_ops = &orangefs_sysfs_ops, 1015 .default_groups = ccache_orangefs_default_groups, 1016 }; 1017 1018 static struct orangefs_attribute ncache_hard_limit_attribute = 1019 __ATTR(hard_limit, 1020 0664, 1021 sysfs_service_op_show, 1022 sysfs_service_op_store); 1023 1024 static struct orangefs_attribute ncache_reclaim_percent_attribute = 1025 __ATTR(reclaim_percentage, 1026 0664, 1027 sysfs_service_op_show, 1028 sysfs_service_op_store); 1029 1030 static struct orangefs_attribute ncache_soft_limit_attribute = 1031 __ATTR(soft_limit, 1032 0664, 1033 sysfs_service_op_show, 1034 sysfs_service_op_store); 1035 1036 static struct orangefs_attribute ncache_timeout_msecs_attribute = 1037 __ATTR(timeout_msecs, 1038 0664, 1039 sysfs_service_op_show, 1040 sysfs_service_op_store); 1041 1042 static struct attribute *ncache_orangefs_default_attrs[] = { 1043 &ncache_hard_limit_attribute.attr, 1044 &ncache_reclaim_percent_attribute.attr, 1045 &ncache_soft_limit_attribute.attr, 1046 &ncache_timeout_msecs_attribute.attr, 1047 NULL, 1048 }; 1049 ATTRIBUTE_GROUPS(ncache_orangefs_default); 1050 1051 static struct kobj_type ncache_orangefs_ktype = { 1052 .sysfs_ops = &orangefs_sysfs_ops, 1053 .default_groups = ncache_orangefs_default_groups, 1054 }; 1055 1056 static struct orangefs_attribute pc_acache_attribute = 1057 __ATTR(acache, 1058 0664, 1059 sysfs_service_op_show, 1060 NULL); 1061 1062 static struct orangefs_attribute pc_capcache_attribute = 1063 __ATTR(capcache, 1064 0664, 1065 sysfs_service_op_show, 1066 NULL); 1067 1068 static struct orangefs_attribute pc_ncache_attribute = 1069 __ATTR(ncache, 1070 0664, 1071 sysfs_service_op_show, 1072 NULL); 1073 1074 static struct attribute *pc_orangefs_default_attrs[] = { 1075 &pc_acache_attribute.attr, 1076 &pc_capcache_attribute.attr, 1077 &pc_ncache_attribute.attr, 1078 NULL, 1079 }; 1080 ATTRIBUTE_GROUPS(pc_orangefs_default); 1081 1082 static struct kobj_type pc_orangefs_ktype = { 1083 .sysfs_ops = &orangefs_sysfs_ops, 1084 .default_groups = pc_orangefs_default_groups, 1085 }; 1086 1087 static struct orangefs_attribute stats_reads_attribute = 1088 __ATTR(reads, 1089 0664, 1090 sysfs_int_show, 1091 NULL); 1092 1093 static struct orangefs_attribute stats_writes_attribute = 1094 __ATTR(writes, 1095 0664, 1096 sysfs_int_show, 1097 NULL); 1098 1099 static struct attribute *stats_orangefs_default_attrs[] = { 1100 &stats_reads_attribute.attr, 1101 &stats_writes_attribute.attr, 1102 NULL, 1103 }; 1104 ATTRIBUTE_GROUPS(stats_orangefs_default); 1105 1106 static struct kobj_type stats_orangefs_ktype = { 1107 .sysfs_ops = &orangefs_sysfs_ops, 1108 .default_groups = stats_orangefs_default_groups, 1109 }; 1110 1111 static struct kobject *orangefs_obj; 1112 static struct kobject *acache_orangefs_obj; 1113 static struct kobject *capcache_orangefs_obj; 1114 static struct kobject *ccache_orangefs_obj; 1115 static struct kobject *ncache_orangefs_obj; 1116 static struct kobject *pc_orangefs_obj; 1117 static struct kobject *stats_orangefs_obj; 1118 1119 int orangefs_sysfs_init(void) 1120 { 1121 int rc = -EINVAL; 1122 1123 gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_init: start\n"); 1124 1125 /* create /sys/fs/orangefs. */ 1126 orangefs_obj = kzalloc(sizeof(*orangefs_obj), GFP_KERNEL); 1127 if (!orangefs_obj) 1128 goto out; 1129 1130 rc = kobject_init_and_add(orangefs_obj, 1131 &orangefs_ktype, 1132 fs_kobj, 1133 ORANGEFS_KOBJ_ID); 1134 1135 if (rc) 1136 goto ofs_obj_bail; 1137 1138 kobject_uevent(orangefs_obj, KOBJ_ADD); 1139 1140 /* create /sys/fs/orangefs/acache. */ 1141 acache_orangefs_obj = kzalloc(sizeof(*acache_orangefs_obj), GFP_KERNEL); 1142 if (!acache_orangefs_obj) { 1143 rc = -EINVAL; 1144 goto ofs_obj_bail; 1145 } 1146 1147 rc = kobject_init_and_add(acache_orangefs_obj, 1148 &acache_orangefs_ktype, 1149 orangefs_obj, 1150 ACACHE_KOBJ_ID); 1151 1152 if (rc) 1153 goto acache_obj_bail; 1154 1155 kobject_uevent(acache_orangefs_obj, KOBJ_ADD); 1156 1157 /* create /sys/fs/orangefs/capcache. */ 1158 capcache_orangefs_obj = 1159 kzalloc(sizeof(*capcache_orangefs_obj), GFP_KERNEL); 1160 if (!capcache_orangefs_obj) { 1161 rc = -EINVAL; 1162 goto acache_obj_bail; 1163 } 1164 1165 rc = kobject_init_and_add(capcache_orangefs_obj, 1166 &capcache_orangefs_ktype, 1167 orangefs_obj, 1168 CAPCACHE_KOBJ_ID); 1169 if (rc) 1170 goto capcache_obj_bail; 1171 1172 kobject_uevent(capcache_orangefs_obj, KOBJ_ADD); 1173 1174 /* create /sys/fs/orangefs/ccache. */ 1175 ccache_orangefs_obj = 1176 kzalloc(sizeof(*ccache_orangefs_obj), GFP_KERNEL); 1177 if (!ccache_orangefs_obj) { 1178 rc = -EINVAL; 1179 goto capcache_obj_bail; 1180 } 1181 1182 rc = kobject_init_and_add(ccache_orangefs_obj, 1183 &ccache_orangefs_ktype, 1184 orangefs_obj, 1185 CCACHE_KOBJ_ID); 1186 if (rc) 1187 goto ccache_obj_bail; 1188 1189 kobject_uevent(ccache_orangefs_obj, KOBJ_ADD); 1190 1191 /* create /sys/fs/orangefs/ncache. */ 1192 ncache_orangefs_obj = kzalloc(sizeof(*ncache_orangefs_obj), GFP_KERNEL); 1193 if (!ncache_orangefs_obj) { 1194 rc = -EINVAL; 1195 goto ccache_obj_bail; 1196 } 1197 1198 rc = kobject_init_and_add(ncache_orangefs_obj, 1199 &ncache_orangefs_ktype, 1200 orangefs_obj, 1201 NCACHE_KOBJ_ID); 1202 1203 if (rc) 1204 goto ncache_obj_bail; 1205 1206 kobject_uevent(ncache_orangefs_obj, KOBJ_ADD); 1207 1208 /* create /sys/fs/orangefs/perf_counters. */ 1209 pc_orangefs_obj = kzalloc(sizeof(*pc_orangefs_obj), GFP_KERNEL); 1210 if (!pc_orangefs_obj) { 1211 rc = -EINVAL; 1212 goto ncache_obj_bail; 1213 } 1214 1215 rc = kobject_init_and_add(pc_orangefs_obj, 1216 &pc_orangefs_ktype, 1217 orangefs_obj, 1218 "perf_counters"); 1219 1220 if (rc) 1221 goto pc_obj_bail; 1222 1223 kobject_uevent(pc_orangefs_obj, KOBJ_ADD); 1224 1225 /* create /sys/fs/orangefs/stats. */ 1226 stats_orangefs_obj = kzalloc(sizeof(*stats_orangefs_obj), GFP_KERNEL); 1227 if (!stats_orangefs_obj) { 1228 rc = -EINVAL; 1229 goto pc_obj_bail; 1230 } 1231 1232 rc = kobject_init_and_add(stats_orangefs_obj, 1233 &stats_orangefs_ktype, 1234 orangefs_obj, 1235 STATS_KOBJ_ID); 1236 1237 if (rc) 1238 goto stats_obj_bail; 1239 1240 kobject_uevent(stats_orangefs_obj, KOBJ_ADD); 1241 goto out; 1242 1243 stats_obj_bail: 1244 kobject_put(stats_orangefs_obj); 1245 pc_obj_bail: 1246 kobject_put(pc_orangefs_obj); 1247 ncache_obj_bail: 1248 kobject_put(ncache_orangefs_obj); 1249 ccache_obj_bail: 1250 kobject_put(ccache_orangefs_obj); 1251 capcache_obj_bail: 1252 kobject_put(capcache_orangefs_obj); 1253 acache_obj_bail: 1254 kobject_put(acache_orangefs_obj); 1255 ofs_obj_bail: 1256 kobject_put(orangefs_obj); 1257 out: 1258 return rc; 1259 } 1260 1261 void orangefs_sysfs_exit(void) 1262 { 1263 gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_exit: start\n"); 1264 kobject_put(acache_orangefs_obj); 1265 kobject_put(capcache_orangefs_obj); 1266 kobject_put(ccache_orangefs_obj); 1267 kobject_put(ncache_orangefs_obj); 1268 kobject_put(pc_orangefs_obj); 1269 kobject_put(stats_orangefs_obj); 1270 kobject_put(orangefs_obj); 1271 } 1272