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 898 static struct kobj_type orangefs_ktype = { 899 .sysfs_ops = &orangefs_sysfs_ops, 900 .default_attrs = orangefs_default_attrs, 901 }; 902 903 static struct orangefs_attribute acache_hard_limit_attribute = 904 __ATTR(hard_limit, 905 0664, 906 sysfs_service_op_show, 907 sysfs_service_op_store); 908 909 static struct orangefs_attribute acache_reclaim_percent_attribute = 910 __ATTR(reclaim_percentage, 911 0664, 912 sysfs_service_op_show, 913 sysfs_service_op_store); 914 915 static struct orangefs_attribute acache_soft_limit_attribute = 916 __ATTR(soft_limit, 917 0664, 918 sysfs_service_op_show, 919 sysfs_service_op_store); 920 921 static struct orangefs_attribute acache_timeout_msecs_attribute = 922 __ATTR(timeout_msecs, 923 0664, 924 sysfs_service_op_show, 925 sysfs_service_op_store); 926 927 static 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 935 static struct kobj_type acache_orangefs_ktype = { 936 .sysfs_ops = &orangefs_sysfs_ops, 937 .default_attrs = acache_orangefs_default_attrs, 938 }; 939 940 static struct orangefs_attribute capcache_hard_limit_attribute = 941 __ATTR(hard_limit, 942 0664, 943 sysfs_service_op_show, 944 sysfs_service_op_store); 945 946 static struct orangefs_attribute capcache_reclaim_percent_attribute = 947 __ATTR(reclaim_percentage, 948 0664, 949 sysfs_service_op_show, 950 sysfs_service_op_store); 951 952 static struct orangefs_attribute capcache_soft_limit_attribute = 953 __ATTR(soft_limit, 954 0664, 955 sysfs_service_op_show, 956 sysfs_service_op_store); 957 958 static struct orangefs_attribute capcache_timeout_secs_attribute = 959 __ATTR(timeout_secs, 960 0664, 961 sysfs_service_op_show, 962 sysfs_service_op_store); 963 964 static 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 972 static struct kobj_type capcache_orangefs_ktype = { 973 .sysfs_ops = &orangefs_sysfs_ops, 974 .default_attrs = capcache_orangefs_default_attrs, 975 }; 976 977 static struct orangefs_attribute ccache_hard_limit_attribute = 978 __ATTR(hard_limit, 979 0664, 980 sysfs_service_op_show, 981 sysfs_service_op_store); 982 983 static struct orangefs_attribute ccache_reclaim_percent_attribute = 984 __ATTR(reclaim_percentage, 985 0664, 986 sysfs_service_op_show, 987 sysfs_service_op_store); 988 989 static struct orangefs_attribute ccache_soft_limit_attribute = 990 __ATTR(soft_limit, 991 0664, 992 sysfs_service_op_show, 993 sysfs_service_op_store); 994 995 static struct orangefs_attribute ccache_timeout_secs_attribute = 996 __ATTR(timeout_secs, 997 0664, 998 sysfs_service_op_show, 999 sysfs_service_op_store); 1000 1001 static 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 1009 static struct kobj_type ccache_orangefs_ktype = { 1010 .sysfs_ops = &orangefs_sysfs_ops, 1011 .default_attrs = ccache_orangefs_default_attrs, 1012 }; 1013 1014 static struct orangefs_attribute ncache_hard_limit_attribute = 1015 __ATTR(hard_limit, 1016 0664, 1017 sysfs_service_op_show, 1018 sysfs_service_op_store); 1019 1020 static struct orangefs_attribute ncache_reclaim_percent_attribute = 1021 __ATTR(reclaim_percentage, 1022 0664, 1023 sysfs_service_op_show, 1024 sysfs_service_op_store); 1025 1026 static struct orangefs_attribute ncache_soft_limit_attribute = 1027 __ATTR(soft_limit, 1028 0664, 1029 sysfs_service_op_show, 1030 sysfs_service_op_store); 1031 1032 static struct orangefs_attribute ncache_timeout_msecs_attribute = 1033 __ATTR(timeout_msecs, 1034 0664, 1035 sysfs_service_op_show, 1036 sysfs_service_op_store); 1037 1038 static 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 1046 static struct kobj_type ncache_orangefs_ktype = { 1047 .sysfs_ops = &orangefs_sysfs_ops, 1048 .default_attrs = ncache_orangefs_default_attrs, 1049 }; 1050 1051 static struct orangefs_attribute pc_acache_attribute = 1052 __ATTR(acache, 1053 0664, 1054 sysfs_service_op_show, 1055 NULL); 1056 1057 static struct orangefs_attribute pc_capcache_attribute = 1058 __ATTR(capcache, 1059 0664, 1060 sysfs_service_op_show, 1061 NULL); 1062 1063 static struct orangefs_attribute pc_ncache_attribute = 1064 __ATTR(ncache, 1065 0664, 1066 sysfs_service_op_show, 1067 NULL); 1068 1069 static 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 1076 static struct kobj_type pc_orangefs_ktype = { 1077 .sysfs_ops = &orangefs_sysfs_ops, 1078 .default_attrs = pc_orangefs_default_attrs, 1079 }; 1080 1081 static struct orangefs_attribute stats_reads_attribute = 1082 __ATTR(reads, 1083 0664, 1084 sysfs_int_show, 1085 NULL); 1086 1087 static struct orangefs_attribute stats_writes_attribute = 1088 __ATTR(writes, 1089 0664, 1090 sysfs_int_show, 1091 NULL); 1092 1093 static struct attribute *stats_orangefs_default_attrs[] = { 1094 &stats_reads_attribute.attr, 1095 &stats_writes_attribute.attr, 1096 NULL, 1097 }; 1098 1099 static struct kobj_type stats_orangefs_ktype = { 1100 .sysfs_ops = &orangefs_sysfs_ops, 1101 .default_attrs = stats_orangefs_default_attrs, 1102 }; 1103 1104 static struct kobject *orangefs_obj; 1105 static struct kobject *acache_orangefs_obj; 1106 static struct kobject *capcache_orangefs_obj; 1107 static struct kobject *ccache_orangefs_obj; 1108 static struct kobject *ncache_orangefs_obj; 1109 static struct kobject *pc_orangefs_obj; 1110 static struct kobject *stats_orangefs_obj; 1111 1112 int 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 1236 stats_obj_bail: 1237 kobject_put(stats_orangefs_obj); 1238 pc_obj_bail: 1239 kobject_put(pc_orangefs_obj); 1240 ncache_obj_bail: 1241 kobject_put(ncache_orangefs_obj); 1242 ccache_obj_bail: 1243 kobject_put(ccache_orangefs_obj); 1244 capcache_obj_bail: 1245 kobject_put(capcache_orangefs_obj); 1246 acache_obj_bail: 1247 kobject_put(acache_orangefs_obj); 1248 ofs_obj_bail: 1249 kobject_put(orangefs_obj); 1250 out: 1251 return rc; 1252 } 1253 1254 void 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