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