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