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 } 613 614 } else if (!strcmp(kobj->name, ACACHE_KOBJ_ID)) { 615 if (!strcmp(attr->attr.name, "hard_limit")) { 616 if (val > -1) { 617 new_op->upcall.req.param.op = 618 ORANGEFS_PARAM_REQUEST_OP_ACACHE_HARD_LIMIT; 619 } else { 620 rc = 0; 621 goto out; 622 } 623 } else if (!strcmp(attr->attr.name, "soft_limit")) { 624 if (val > -1) { 625 new_op->upcall.req.param.op = 626 ORANGEFS_PARAM_REQUEST_OP_ACACHE_SOFT_LIMIT; 627 } else { 628 rc = 0; 629 goto out; 630 } 631 } else if (!strcmp(attr->attr.name, 632 "reclaim_percentage")) { 633 if ((val > -1) && (val < 101)) { 634 new_op->upcall.req.param.op = 635 ORANGEFS_PARAM_REQUEST_OP_ACACHE_RECLAIM_PERCENTAGE; 636 } else { 637 rc = 0; 638 goto out; 639 } 640 } else if (!strcmp(attr->attr.name, "timeout_msecs")) { 641 if (val > -1) { 642 new_op->upcall.req.param.op = 643 ORANGEFS_PARAM_REQUEST_OP_ACACHE_TIMEOUT_MSECS; 644 } else { 645 rc = 0; 646 goto out; 647 } 648 } 649 650 } else if (!strcmp(kobj->name, CAPCACHE_KOBJ_ID)) { 651 if (!strcmp(attr->attr.name, "hard_limit")) { 652 if (val > -1) { 653 new_op->upcall.req.param.op = 654 ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_HARD_LIMIT; 655 } else { 656 rc = 0; 657 goto out; 658 } 659 } else if (!strcmp(attr->attr.name, "soft_limit")) { 660 if (val > -1) { 661 new_op->upcall.req.param.op = 662 ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_SOFT_LIMIT; 663 } else { 664 rc = 0; 665 goto out; 666 } 667 } else if (!strcmp(attr->attr.name, 668 "reclaim_percentage")) { 669 if ((val > -1) && (val < 101)) { 670 new_op->upcall.req.param.op = 671 ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_RECLAIM_PERCENTAGE; 672 } else { 673 rc = 0; 674 goto out; 675 } 676 } else if (!strcmp(attr->attr.name, "timeout_secs")) { 677 if (val > -1) { 678 new_op->upcall.req.param.op = 679 ORANGEFS_PARAM_REQUEST_OP_CAPCACHE_TIMEOUT_SECS; 680 } else { 681 rc = 0; 682 goto out; 683 } 684 } 685 686 } else if (!strcmp(kobj->name, CCACHE_KOBJ_ID)) { 687 if (!strcmp(attr->attr.name, "hard_limit")) { 688 if (val > -1) { 689 new_op->upcall.req.param.op = 690 ORANGEFS_PARAM_REQUEST_OP_CCACHE_HARD_LIMIT; 691 } else { 692 rc = 0; 693 goto out; 694 } 695 } else if (!strcmp(attr->attr.name, "soft_limit")) { 696 if (val > -1) { 697 new_op->upcall.req.param.op = 698 ORANGEFS_PARAM_REQUEST_OP_CCACHE_SOFT_LIMIT; 699 } else { 700 rc = 0; 701 goto out; 702 } 703 } else if (!strcmp(attr->attr.name, 704 "reclaim_percentage")) { 705 if ((val > -1) && (val < 101)) { 706 new_op->upcall.req.param.op = 707 ORANGEFS_PARAM_REQUEST_OP_CCACHE_RECLAIM_PERCENTAGE; 708 } else { 709 rc = 0; 710 goto out; 711 } 712 } else if (!strcmp(attr->attr.name, "timeout_secs")) { 713 if (val > -1) { 714 new_op->upcall.req.param.op = 715 ORANGEFS_PARAM_REQUEST_OP_CCACHE_TIMEOUT_SECS; 716 } else { 717 rc = 0; 718 goto out; 719 } 720 } 721 722 } else if (!strcmp(kobj->name, NCACHE_KOBJ_ID)) { 723 if (!strcmp(attr->attr.name, "hard_limit")) { 724 if (val > -1) { 725 new_op->upcall.req.param.op = 726 ORANGEFS_PARAM_REQUEST_OP_NCACHE_HARD_LIMIT; 727 } else { 728 rc = 0; 729 goto out; 730 } 731 } else if (!strcmp(attr->attr.name, "soft_limit")) { 732 if (val > -1) { 733 new_op->upcall.req.param.op = 734 ORANGEFS_PARAM_REQUEST_OP_NCACHE_SOFT_LIMIT; 735 } else { 736 rc = 0; 737 goto out; 738 } 739 } else if (!strcmp(attr->attr.name, 740 "reclaim_percentage")) { 741 if ((val > -1) && (val < 101)) { 742 new_op->upcall.req.param.op = 743 ORANGEFS_PARAM_REQUEST_OP_NCACHE_RECLAIM_PERCENTAGE; 744 } else { 745 rc = 0; 746 goto out; 747 } 748 } else if (!strcmp(attr->attr.name, "timeout_msecs")) { 749 if (val > -1) { 750 new_op->upcall.req.param.op = 751 ORANGEFS_PARAM_REQUEST_OP_NCACHE_TIMEOUT_MSECS; 752 } else { 753 rc = 0; 754 goto out; 755 } 756 } 757 758 } else { 759 gossip_err("sysfs_service_op_store: unknown kobj_id:%s:\n", 760 kobj->name); 761 rc = -EINVAL; 762 goto out; 763 } 764 765 new_op->upcall.req.param.u.value64 = val; 766 value_set: 767 768 /* 769 * The service_operation will return a errno return code on 770 * error, and zero on success. 771 */ 772 rc = service_operation(new_op, "orangefs_param", ORANGEFS_OP_INTERRUPTIBLE); 773 774 if (rc < 0) { 775 gossip_err("sysfs_service_op_store: service op returned:%d:\n", 776 rc); 777 rc = 0; 778 } else { 779 rc = count; 780 } 781 782 out: 783 op_release(new_op); 784 785 if (rc == -ENOMEM || rc == 0) 786 rc = -EINVAL; 787 788 return rc; 789 } 790 791 static struct orangefs_attribute op_timeout_secs_attribute = 792 __ATTR(op_timeout_secs, 0664, sysfs_int_show, sysfs_int_store); 793 794 static struct orangefs_attribute slot_timeout_secs_attribute = 795 __ATTR(slot_timeout_secs, 0664, sysfs_int_show, sysfs_int_store); 796 797 static struct orangefs_attribute dcache_timeout_msecs_attribute = 798 __ATTR(dcache_timeout_msecs, 0664, sysfs_int_show, sysfs_int_store); 799 800 static struct orangefs_attribute getattr_timeout_msecs_attribute = 801 __ATTR(getattr_timeout_msecs, 0664, sysfs_int_show, sysfs_int_store); 802 803 static struct orangefs_attribute readahead_count_attribute = 804 __ATTR(readahead_count, 0664, sysfs_service_op_show, 805 sysfs_service_op_store); 806 807 static struct orangefs_attribute readahead_size_attribute = 808 __ATTR(readahead_size, 0664, sysfs_service_op_show, 809 sysfs_service_op_store); 810 811 static struct orangefs_attribute readahead_count_size_attribute = 812 __ATTR(readahead_count_size, 0664, sysfs_service_op_show, 813 sysfs_service_op_store); 814 815 static struct orangefs_attribute perf_counter_reset_attribute = 816 __ATTR(perf_counter_reset, 817 0664, 818 sysfs_service_op_show, 819 sysfs_service_op_store); 820 821 static struct orangefs_attribute perf_history_size_attribute = 822 __ATTR(perf_history_size, 823 0664, 824 sysfs_service_op_show, 825 sysfs_service_op_store); 826 827 static struct orangefs_attribute perf_time_interval_secs_attribute = 828 __ATTR(perf_time_interval_secs, 829 0664, 830 sysfs_service_op_show, 831 sysfs_service_op_store); 832 833 static struct attribute *orangefs_default_attrs[] = { 834 &op_timeout_secs_attribute.attr, 835 &slot_timeout_secs_attribute.attr, 836 &dcache_timeout_msecs_attribute.attr, 837 &getattr_timeout_msecs_attribute.attr, 838 &readahead_count_attribute.attr, 839 &readahead_size_attribute.attr, 840 &readahead_count_size_attribute.attr, 841 &perf_counter_reset_attribute.attr, 842 &perf_history_size_attribute.attr, 843 &perf_time_interval_secs_attribute.attr, 844 NULL, 845 }; 846 847 static struct kobj_type orangefs_ktype = { 848 .sysfs_ops = &orangefs_sysfs_ops, 849 .default_attrs = orangefs_default_attrs, 850 }; 851 852 static struct orangefs_attribute acache_hard_limit_attribute = 853 __ATTR(hard_limit, 854 0664, 855 sysfs_service_op_show, 856 sysfs_service_op_store); 857 858 static struct orangefs_attribute acache_reclaim_percent_attribute = 859 __ATTR(reclaim_percentage, 860 0664, 861 sysfs_service_op_show, 862 sysfs_service_op_store); 863 864 static struct orangefs_attribute acache_soft_limit_attribute = 865 __ATTR(soft_limit, 866 0664, 867 sysfs_service_op_show, 868 sysfs_service_op_store); 869 870 static struct orangefs_attribute acache_timeout_msecs_attribute = 871 __ATTR(timeout_msecs, 872 0664, 873 sysfs_service_op_show, 874 sysfs_service_op_store); 875 876 static struct attribute *acache_orangefs_default_attrs[] = { 877 &acache_hard_limit_attribute.attr, 878 &acache_reclaim_percent_attribute.attr, 879 &acache_soft_limit_attribute.attr, 880 &acache_timeout_msecs_attribute.attr, 881 NULL, 882 }; 883 884 static struct kobj_type acache_orangefs_ktype = { 885 .sysfs_ops = &orangefs_sysfs_ops, 886 .default_attrs = acache_orangefs_default_attrs, 887 }; 888 889 static struct orangefs_attribute capcache_hard_limit_attribute = 890 __ATTR(hard_limit, 891 0664, 892 sysfs_service_op_show, 893 sysfs_service_op_store); 894 895 static struct orangefs_attribute capcache_reclaim_percent_attribute = 896 __ATTR(reclaim_percentage, 897 0664, 898 sysfs_service_op_show, 899 sysfs_service_op_store); 900 901 static struct orangefs_attribute capcache_soft_limit_attribute = 902 __ATTR(soft_limit, 903 0664, 904 sysfs_service_op_show, 905 sysfs_service_op_store); 906 907 static struct orangefs_attribute capcache_timeout_secs_attribute = 908 __ATTR(timeout_secs, 909 0664, 910 sysfs_service_op_show, 911 sysfs_service_op_store); 912 913 static struct attribute *capcache_orangefs_default_attrs[] = { 914 &capcache_hard_limit_attribute.attr, 915 &capcache_reclaim_percent_attribute.attr, 916 &capcache_soft_limit_attribute.attr, 917 &capcache_timeout_secs_attribute.attr, 918 NULL, 919 }; 920 921 static struct kobj_type capcache_orangefs_ktype = { 922 .sysfs_ops = &orangefs_sysfs_ops, 923 .default_attrs = capcache_orangefs_default_attrs, 924 }; 925 926 static struct orangefs_attribute ccache_hard_limit_attribute = 927 __ATTR(hard_limit, 928 0664, 929 sysfs_service_op_show, 930 sysfs_service_op_store); 931 932 static struct orangefs_attribute ccache_reclaim_percent_attribute = 933 __ATTR(reclaim_percentage, 934 0664, 935 sysfs_service_op_show, 936 sysfs_service_op_store); 937 938 static struct orangefs_attribute ccache_soft_limit_attribute = 939 __ATTR(soft_limit, 940 0664, 941 sysfs_service_op_show, 942 sysfs_service_op_store); 943 944 static struct orangefs_attribute ccache_timeout_secs_attribute = 945 __ATTR(timeout_secs, 946 0664, 947 sysfs_service_op_show, 948 sysfs_service_op_store); 949 950 static struct attribute *ccache_orangefs_default_attrs[] = { 951 &ccache_hard_limit_attribute.attr, 952 &ccache_reclaim_percent_attribute.attr, 953 &ccache_soft_limit_attribute.attr, 954 &ccache_timeout_secs_attribute.attr, 955 NULL, 956 }; 957 958 static struct kobj_type ccache_orangefs_ktype = { 959 .sysfs_ops = &orangefs_sysfs_ops, 960 .default_attrs = ccache_orangefs_default_attrs, 961 }; 962 963 static struct orangefs_attribute ncache_hard_limit_attribute = 964 __ATTR(hard_limit, 965 0664, 966 sysfs_service_op_show, 967 sysfs_service_op_store); 968 969 static struct orangefs_attribute ncache_reclaim_percent_attribute = 970 __ATTR(reclaim_percentage, 971 0664, 972 sysfs_service_op_show, 973 sysfs_service_op_store); 974 975 static struct orangefs_attribute ncache_soft_limit_attribute = 976 __ATTR(soft_limit, 977 0664, 978 sysfs_service_op_show, 979 sysfs_service_op_store); 980 981 static struct orangefs_attribute ncache_timeout_msecs_attribute = 982 __ATTR(timeout_msecs, 983 0664, 984 sysfs_service_op_show, 985 sysfs_service_op_store); 986 987 static struct attribute *ncache_orangefs_default_attrs[] = { 988 &ncache_hard_limit_attribute.attr, 989 &ncache_reclaim_percent_attribute.attr, 990 &ncache_soft_limit_attribute.attr, 991 &ncache_timeout_msecs_attribute.attr, 992 NULL, 993 }; 994 995 static struct kobj_type ncache_orangefs_ktype = { 996 .sysfs_ops = &orangefs_sysfs_ops, 997 .default_attrs = ncache_orangefs_default_attrs, 998 }; 999 1000 static struct orangefs_attribute pc_acache_attribute = 1001 __ATTR(acache, 1002 0664, 1003 sysfs_service_op_show, 1004 NULL); 1005 1006 static struct orangefs_attribute pc_capcache_attribute = 1007 __ATTR(capcache, 1008 0664, 1009 sysfs_service_op_show, 1010 NULL); 1011 1012 static struct orangefs_attribute pc_ncache_attribute = 1013 __ATTR(ncache, 1014 0664, 1015 sysfs_service_op_show, 1016 NULL); 1017 1018 static struct attribute *pc_orangefs_default_attrs[] = { 1019 &pc_acache_attribute.attr, 1020 &pc_capcache_attribute.attr, 1021 &pc_ncache_attribute.attr, 1022 NULL, 1023 }; 1024 1025 static struct kobj_type pc_orangefs_ktype = { 1026 .sysfs_ops = &orangefs_sysfs_ops, 1027 .default_attrs = pc_orangefs_default_attrs, 1028 }; 1029 1030 static struct orangefs_attribute stats_reads_attribute = 1031 __ATTR(reads, 1032 0664, 1033 sysfs_int_show, 1034 NULL); 1035 1036 static struct orangefs_attribute stats_writes_attribute = 1037 __ATTR(writes, 1038 0664, 1039 sysfs_int_show, 1040 NULL); 1041 1042 static struct attribute *stats_orangefs_default_attrs[] = { 1043 &stats_reads_attribute.attr, 1044 &stats_writes_attribute.attr, 1045 NULL, 1046 }; 1047 1048 static struct kobj_type stats_orangefs_ktype = { 1049 .sysfs_ops = &orangefs_sysfs_ops, 1050 .default_attrs = stats_orangefs_default_attrs, 1051 }; 1052 1053 static struct kobject *orangefs_obj; 1054 static struct kobject *acache_orangefs_obj; 1055 static struct kobject *capcache_orangefs_obj; 1056 static struct kobject *ccache_orangefs_obj; 1057 static struct kobject *ncache_orangefs_obj; 1058 static struct kobject *pc_orangefs_obj; 1059 static struct kobject *stats_orangefs_obj; 1060 1061 int orangefs_sysfs_init(void) 1062 { 1063 int rc = -EINVAL; 1064 1065 gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_init: start\n"); 1066 1067 /* create /sys/fs/orangefs. */ 1068 orangefs_obj = kzalloc(sizeof(*orangefs_obj), GFP_KERNEL); 1069 if (!orangefs_obj) 1070 goto out; 1071 1072 rc = kobject_init_and_add(orangefs_obj, 1073 &orangefs_ktype, 1074 fs_kobj, 1075 ORANGEFS_KOBJ_ID); 1076 1077 if (rc) 1078 goto ofs_obj_bail; 1079 1080 kobject_uevent(orangefs_obj, KOBJ_ADD); 1081 1082 /* create /sys/fs/orangefs/acache. */ 1083 acache_orangefs_obj = kzalloc(sizeof(*acache_orangefs_obj), GFP_KERNEL); 1084 if (!acache_orangefs_obj) { 1085 rc = -EINVAL; 1086 goto ofs_obj_bail; 1087 } 1088 1089 rc = kobject_init_and_add(acache_orangefs_obj, 1090 &acache_orangefs_ktype, 1091 orangefs_obj, 1092 ACACHE_KOBJ_ID); 1093 1094 if (rc) 1095 goto acache_obj_bail; 1096 1097 kobject_uevent(acache_orangefs_obj, KOBJ_ADD); 1098 1099 /* create /sys/fs/orangefs/capcache. */ 1100 capcache_orangefs_obj = 1101 kzalloc(sizeof(*capcache_orangefs_obj), GFP_KERNEL); 1102 if (!capcache_orangefs_obj) { 1103 rc = -EINVAL; 1104 goto acache_obj_bail; 1105 } 1106 1107 rc = kobject_init_and_add(capcache_orangefs_obj, 1108 &capcache_orangefs_ktype, 1109 orangefs_obj, 1110 CAPCACHE_KOBJ_ID); 1111 if (rc) 1112 goto capcache_obj_bail; 1113 1114 kobject_uevent(capcache_orangefs_obj, KOBJ_ADD); 1115 1116 /* create /sys/fs/orangefs/ccache. */ 1117 ccache_orangefs_obj = 1118 kzalloc(sizeof(*ccache_orangefs_obj), GFP_KERNEL); 1119 if (!ccache_orangefs_obj) { 1120 rc = -EINVAL; 1121 goto capcache_obj_bail; 1122 } 1123 1124 rc = kobject_init_and_add(ccache_orangefs_obj, 1125 &ccache_orangefs_ktype, 1126 orangefs_obj, 1127 CCACHE_KOBJ_ID); 1128 if (rc) 1129 goto ccache_obj_bail; 1130 1131 kobject_uevent(ccache_orangefs_obj, KOBJ_ADD); 1132 1133 /* create /sys/fs/orangefs/ncache. */ 1134 ncache_orangefs_obj = kzalloc(sizeof(*ncache_orangefs_obj), GFP_KERNEL); 1135 if (!ncache_orangefs_obj) { 1136 rc = -EINVAL; 1137 goto ccache_obj_bail; 1138 } 1139 1140 rc = kobject_init_and_add(ncache_orangefs_obj, 1141 &ncache_orangefs_ktype, 1142 orangefs_obj, 1143 NCACHE_KOBJ_ID); 1144 1145 if (rc) 1146 goto ncache_obj_bail; 1147 1148 kobject_uevent(ncache_orangefs_obj, KOBJ_ADD); 1149 1150 /* create /sys/fs/orangefs/perf_counters. */ 1151 pc_orangefs_obj = kzalloc(sizeof(*pc_orangefs_obj), GFP_KERNEL); 1152 if (!pc_orangefs_obj) { 1153 rc = -EINVAL; 1154 goto ncache_obj_bail; 1155 } 1156 1157 rc = kobject_init_and_add(pc_orangefs_obj, 1158 &pc_orangefs_ktype, 1159 orangefs_obj, 1160 "perf_counters"); 1161 1162 if (rc) 1163 goto pc_obj_bail; 1164 1165 kobject_uevent(pc_orangefs_obj, KOBJ_ADD); 1166 1167 /* create /sys/fs/orangefs/stats. */ 1168 stats_orangefs_obj = kzalloc(sizeof(*stats_orangefs_obj), GFP_KERNEL); 1169 if (!stats_orangefs_obj) { 1170 rc = -EINVAL; 1171 goto pc_obj_bail; 1172 } 1173 1174 rc = kobject_init_and_add(stats_orangefs_obj, 1175 &stats_orangefs_ktype, 1176 orangefs_obj, 1177 STATS_KOBJ_ID); 1178 1179 if (rc) 1180 goto stats_obj_bail; 1181 1182 kobject_uevent(stats_orangefs_obj, KOBJ_ADD); 1183 goto out; 1184 1185 stats_obj_bail: 1186 kobject_put(stats_orangefs_obj); 1187 pc_obj_bail: 1188 kobject_put(pc_orangefs_obj); 1189 ncache_obj_bail: 1190 kobject_put(ncache_orangefs_obj); 1191 ccache_obj_bail: 1192 kobject_put(ccache_orangefs_obj); 1193 capcache_obj_bail: 1194 kobject_put(capcache_orangefs_obj); 1195 acache_obj_bail: 1196 kobject_put(acache_orangefs_obj); 1197 ofs_obj_bail: 1198 kobject_put(orangefs_obj); 1199 out: 1200 return rc; 1201 } 1202 1203 void orangefs_sysfs_exit(void) 1204 { 1205 gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_exit: start\n"); 1206 kobject_put(acache_orangefs_obj); 1207 kobject_put(capcache_orangefs_obj); 1208 kobject_put(ccache_orangefs_obj); 1209 kobject_put(ncache_orangefs_obj); 1210 kobject_put(pc_orangefs_obj); 1211 kobject_put(stats_orangefs_obj); 1212 kobject_put(orangefs_obj); 1213 } 1214