1// SPDX-License-Identifier: GPL-2.0 2/* 3 * fs/hmdfs/comm/device_node.c 4 * 5 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 6 */ 7 8#include "device_node.h" 9 10#include <linux/errno.h> 11#include <linux/fs.h> 12#include <linux/init.h> 13#include <linux/kernel.h> 14#include <linux/kfifo.h> 15#include <linux/module.h> 16#include <linux/string.h> 17#include <linux/sysfs.h> 18#include <linux/types.h> 19#include <linux/backing-dev.h> 20 21#include "client_writeback.h" 22#include "server_writeback.h" 23#include "connection.h" 24#include "hmdfs_client.h" 25#include "socket_adapter.h" 26#include "authority/authentication.h" 27 28DEFINE_MUTEX(hmdfs_sysfs_mutex); 29static struct kset *hmdfs_kset; 30 31static void ctrl_cmd_update_socket_handler(const char *buf, size_t len, 32 struct hmdfs_sb_info *sbi) 33{ 34 struct update_socket_param cmd; 35 struct hmdfs_peer *node = NULL; 36 struct connection *conn = NULL; 37 38 if (unlikely(!buf || len != sizeof(cmd))) { 39 hmdfs_err("len/buf error"); 40 goto out; 41 } 42 memcpy(&cmd, buf, sizeof(cmd)); 43 if (cmd.status != CONNECT_STAT_WAIT_REQUEST && 44 cmd.status != CONNECT_STAT_WAIT_RESPONSE) { 45 hmdfs_err("invalid status"); 46 goto out; 47 } 48 49 node = hmdfs_get_peer(sbi, cmd.cid, cmd.devsl); 50 if (unlikely(!node)) { 51 hmdfs_err("failed to update ctrl node: cannot get peer"); 52 goto out; 53 } 54 55 conn = hmdfs_get_conn_tcp(node, cmd.newfd, cmd.masterkey, cmd.status); 56 if (unlikely(!conn)) { 57 hmdfs_err("failed to update ctrl node: cannot get conn"); 58 } else if (!sbi->system_cred) { 59 const struct cred *system_cred = get_cred(current_cred()); 60 61 if (cmpxchg_relaxed(&sbi->system_cred, NULL, system_cred)) 62 put_cred(system_cred); 63 else 64 hmdfs_check_cred(system_cred); 65 } 66 67 if (conn) 68 connection_put(conn); 69out: 70 if (node) 71 peer_put(node); 72} 73 74static void ctrl_cmd_update_devsl_handler(const char *buf, size_t len, 75 struct hmdfs_sb_info *sbi) 76{ 77 struct update_devsl_param cmd; 78 struct hmdfs_peer *node = NULL; 79 80 if (unlikely(!buf || len != sizeof(cmd))) { 81 hmdfs_err("Recved a invalid userbuf"); 82 return; 83 } 84 memcpy(&cmd, buf, sizeof(cmd)); 85 86 node = hmdfs_lookup_from_cid(sbi, cmd.cid); 87 if (unlikely(!node)) { 88 hmdfs_err("failed to update devsl: cannot get peer"); 89 return; 90 } 91 hmdfs_info("Found peer: device_id = %llu", node->device_id); 92 node->devsl = cmd.devsl; 93 peer_put(node); 94} 95 96static inline void hmdfs_disconnect_node_marked(struct hmdfs_peer *conn) 97{ 98 hmdfs_start_process_offline(conn); 99 hmdfs_disconnect_node(conn); 100 hmdfs_stop_process_offline(conn); 101} 102 103static void ctrl_cmd_off_line_handler(const char *buf, size_t len, 104 struct hmdfs_sb_info *sbi) 105{ 106 struct offline_param cmd; 107 struct hmdfs_peer *node = NULL; 108 109 if (unlikely(!buf || len != sizeof(cmd))) { 110 hmdfs_err("Recved a invalid userbuf"); 111 return; 112 } 113 memcpy(&cmd, buf, sizeof(cmd)); 114 node = hmdfs_lookup_from_cid(sbi, cmd.remote_cid); 115 if (unlikely(!node)) { 116 hmdfs_err("Cannot find node by device"); 117 return; 118 } 119 hmdfs_info("Found peer: device_id = %llu", node->device_id); 120 hmdfs_disconnect_node_marked(node); 121 peer_put(node); 122} 123 124typedef void (*ctrl_cmd_handler)(const char *buf, size_t len, 125 struct hmdfs_sb_info *sbi); 126 127static const ctrl_cmd_handler cmd_handler[CMD_CNT] = { 128 [CMD_UPDATE_SOCKET] = ctrl_cmd_update_socket_handler, 129 [CMD_UPDATE_DEVSL] = ctrl_cmd_update_devsl_handler, 130 [CMD_OFF_LINE] = ctrl_cmd_off_line_handler, 131}; 132 133static ssize_t sbi_cmd_show(struct kobject *kobj, struct sbi_attribute *attr, 134 char *buf) 135{ 136 struct notify_param param; 137 int out_len; 138 struct hmdfs_sb_info *sbi = to_sbi(kobj); 139 140 memset(¶m, 0, sizeof(param)); 141 spin_lock(&sbi->notify_fifo_lock); 142 out_len = kfifo_out(&sbi->notify_fifo, ¶m, sizeof(param)); 143 spin_unlock(&sbi->notify_fifo_lock); 144 if (out_len != sizeof(param)) 145 param.notify = NOTIFY_NONE; 146 memcpy(buf, ¶m, sizeof(param)); 147 return sizeof(param); 148} 149 150static const char *cmd2str(int cmd) 151{ 152 switch (cmd) { 153 case 0: 154 return "CMD_UPDATE_SOCKET"; 155 case 1: 156 return "CMD_UPDATE_DEVSL"; 157 case 2: 158 return "CMD_OFF_LINE"; 159 default: 160 return "illegal cmd"; 161 } 162} 163 164static ssize_t sbi_cmd_store(struct kobject *kobj, struct sbi_attribute *attr, 165 const char *buf, size_t len) 166{ 167 int cmd; 168 struct hmdfs_sb_info *sbi = to_sbi(kobj); 169 170 if (!sbi) { 171 hmdfs_info("Fatal! Empty sbi. Mount fs first"); 172 return len; 173 } 174 if (len < sizeof(int)) { 175 hmdfs_err("Illegal cmd: cmd len = %zu", len); 176 return len; 177 } 178 cmd = *(int *)buf; 179 if (cmd < 0 || cmd >= CMD_CNT) { 180 hmdfs_err("Illegal cmd : cmd = %d", cmd); 181 return len; 182 } 183 mutex_lock(&sbi->cmd_handler_mutex); 184 hmdfs_info("Recved cmd: %s", cmd2str(cmd)); 185 if (cmd_handler[cmd]) 186 cmd_handler[cmd](buf, len, sbi); 187 mutex_unlock(&sbi->cmd_handler_mutex); 188 return len; 189} 190 191static struct sbi_attribute sbi_cmd_attr = 192 __ATTR(cmd, 0664, sbi_cmd_show, sbi_cmd_store); 193 194static ssize_t sbi_status_show(struct kobject *kobj, struct sbi_attribute *attr, 195 char *buf) 196{ 197 ssize_t size = 0; 198 struct hmdfs_sb_info *sbi = NULL; 199 struct hmdfs_peer *peer = NULL; 200 struct connection *conn_impl = NULL; 201 struct tcp_handle *tcp = NULL; 202 203 sbi = to_sbi(kobj); 204 size += snprintf(buf + size, PAGE_SIZE - size, "peers status\n"); 205 206 mutex_lock(&sbi->connections.node_lock); 207 list_for_each_entry(peer, &sbi->connections.node_list, list) { 208 size += snprintf(buf + size, PAGE_SIZE - size, "%s %d\n", 209 peer->cid, peer->status); 210 // connection information 211 size += snprintf( 212 buf + size, PAGE_SIZE - size, 213 "\t socket_fd connection_status tcp_status ... refcnt\n"); 214 mutex_lock(&peer->conn_impl_list_lock); 215 list_for_each_entry(conn_impl, &peer->conn_impl_list, list) { 216 tcp = conn_impl->connect_handle; 217 size += snprintf(buf + size, PAGE_SIZE - size, 218 "\t %d \t%d \t%d \t%p \t%ld\n", 219 tcp->fd, conn_impl->status, 220 tcp->sock->state, tcp->sock, file_count(tcp->sock->file)); 221 } 222 mutex_unlock(&peer->conn_impl_list_lock); 223 } 224 mutex_unlock(&sbi->connections.node_lock); 225 return size; 226} 227 228static ssize_t sbi_status_store(struct kobject *kobj, 229 struct sbi_attribute *attr, const char *buf, 230 size_t len) 231{ 232 return len; 233} 234 235static struct sbi_attribute sbi_status_attr = 236 __ATTR(status, 0664, sbi_status_show, sbi_status_store); 237 238static ssize_t sbi_stat_show(struct kobject *kobj, struct sbi_attribute *attr, 239 char *buf) 240{ 241 ssize_t size = 0; 242 struct hmdfs_sb_info *sbi = NULL; 243 struct hmdfs_peer *peer = NULL; 244 struct connection *conn_impl = NULL; 245 struct tcp_handle *tcp = NULL; 246 247 sbi = to_sbi(kobj); 248 mutex_lock(&sbi->connections.node_lock); 249 list_for_each_entry(peer, &sbi->connections.node_list, list) { 250 // connection information 251 mutex_lock(&peer->conn_impl_list_lock); 252 list_for_each_entry(conn_impl, &peer->conn_impl_list, list) { 253 tcp = conn_impl->connect_handle; 254 size += snprintf(buf + size, PAGE_SIZE - size, 255 "socket_fd: %d\n", tcp->fd); 256 size += snprintf(buf + size, PAGE_SIZE - size, 257 "\tsend_msg %d \tsend_bytes %llu\n", 258 conn_impl->stat.send_message_count, 259 conn_impl->stat.send_bytes); 260 size += snprintf(buf + size, PAGE_SIZE - size, 261 "\trecv_msg %d \trecv_bytes %llu\n", 262 conn_impl->stat.recv_message_count, 263 conn_impl->stat.recv_bytes); 264 } 265 mutex_unlock(&peer->conn_impl_list_lock); 266 } 267 mutex_unlock(&sbi->connections.node_lock); 268 return size; 269} 270 271static ssize_t sbi_stat_store(struct kobject *kobj, struct sbi_attribute *attr, 272 const char *buf, size_t len) 273{ 274 struct hmdfs_sb_info *sbi = NULL; 275 struct hmdfs_peer *peer = NULL; 276 struct connection *conn_impl = NULL; 277 278 sbi = to_sbi(kobj); 279 mutex_lock(&sbi->connections.node_lock); 280 list_for_each_entry(peer, &sbi->connections.node_list, list) { 281 // connection information 282 mutex_lock(&peer->conn_impl_list_lock); 283 list_for_each_entry(conn_impl, &peer->conn_impl_list, list) { 284 conn_impl->stat.send_message_count = 0; 285 conn_impl->stat.send_bytes = 0; 286 conn_impl->stat.recv_message_count = 0; 287 conn_impl->stat.recv_bytes = 0; 288 } 289 mutex_unlock(&peer->conn_impl_list_lock); 290 } 291 mutex_unlock(&sbi->connections.node_lock); 292 return len; 293} 294 295static struct sbi_attribute sbi_statistic_attr = 296 __ATTR(statistic, 0664, sbi_stat_show, sbi_stat_store); 297 298static ssize_t sbi_dcache_precision_show(struct kobject *kobj, 299 struct sbi_attribute *attr, char *buf) 300{ 301 return snprintf(buf, PAGE_SIZE, "%u\n", to_sbi(kobj)->dcache_precision); 302} 303 304#define PRECISION_MAX 3600000 305 306static ssize_t sbi_dcache_precision_store(struct kobject *kobj, 307 struct sbi_attribute *attr, 308 const char *buf, size_t len) 309{ 310 int ret; 311 unsigned int precision; 312 struct hmdfs_sb_info *sbi = to_sbi(kobj); 313 314 ret = kstrtouint(skip_spaces(buf), 0, &precision); 315 if (!ret) { 316 if (precision <= PRECISION_MAX) 317 sbi->dcache_precision = precision; 318 else 319 ret = -EINVAL; 320 } 321 322 return ret ? ret : len; 323} 324 325static struct sbi_attribute sbi_dcache_precision_attr = 326 __ATTR(dcache_precision, 0664, sbi_dcache_precision_show, 327 sbi_dcache_precision_store); 328 329static ssize_t sbi_dcache_threshold_show(struct kobject *kobj, 330 struct sbi_attribute *attr, char *buf) 331{ 332 return snprintf(buf, PAGE_SIZE, "%lu\n", 333 to_sbi(kobj)->dcache_threshold); 334} 335 336static ssize_t sbi_dcache_threshold_store(struct kobject *kobj, 337 struct sbi_attribute *attr, 338 const char *buf, size_t len) 339{ 340 int ret; 341 unsigned long threshold; 342 struct hmdfs_sb_info *sbi = to_sbi(kobj); 343 344 ret = kstrtoul(skip_spaces(buf), 0, &threshold); 345 if (!ret) 346 sbi->dcache_threshold = threshold; 347 348 return ret ? ret : len; 349} 350 351static struct sbi_attribute sbi_dcache_threshold_attr = 352 __ATTR(dcache_threshold, 0664, sbi_dcache_threshold_show, 353 sbi_dcache_threshold_store); 354 355static ssize_t server_statistic_show(struct kobject *kobj, 356 struct sbi_attribute *attr, char *buf) 357{ 358 int i, ret; 359 const size_t size = PAGE_SIZE - 1; 360 ssize_t pos = 0; 361 struct server_statistic *stat = to_sbi(kobj)->s_server_statis; 362 363 for (i = 0; i < F_SIZE; i++) { 364 365 ret = snprintf(buf + pos, size - pos, 366 "%llu %u %llu %llu\n", 367 stat[i].cnt, 368 jiffies_to_msecs(stat[i].max), 369 stat[i].snd_cnt, stat[i].snd_fail_cnt); 370 if (ret > size - pos) 371 break; 372 pos += ret; 373 } 374 375 /* If break, we should add a new line */ 376 if (i < F_SIZE) { 377 ret = snprintf(buf + pos, size + 1 - pos, "\n"); 378 pos += ret; 379 } 380 return pos; 381} 382 383static struct sbi_attribute sbi_local_op_attr = __ATTR_RO(server_statistic); 384 385static ssize_t client_statistic_show(struct kobject *kobj, 386 struct sbi_attribute *attr, char *buf) 387{ 388 int i, ret; 389 const size_t size = PAGE_SIZE - 1; 390 ssize_t pos = 0; 391 struct client_statistic *stat = to_sbi(kobj)->s_client_statis; 392 393 for (i = 0; i < F_SIZE; i++) { 394 395 ret = snprintf(buf + pos, size - pos, 396 "%llu %llu %llu %llu %llu %u\n", 397 stat[i].snd_cnt, 398 stat[i].snd_fail_cnt, 399 stat[i].resp_cnt, 400 stat[i].timeout_cnt, 401 stat[i].delay_resp_cnt, 402 jiffies_to_msecs(stat[i].max)); 403 if (ret > size - pos) 404 break; 405 pos += ret; 406 } 407 408 /* If break, we should add a new line */ 409 if (i < F_SIZE) { 410 ret = snprintf(buf + pos, size + 1 - pos, "\n"); 411 pos += ret; 412 } 413 414 return pos; 415} 416 417static struct sbi_attribute sbi_delay_resp_attr = __ATTR_RO(client_statistic); 418 419static inline unsigned long pages_to_kbytes(unsigned long page) 420{ 421 return page << (PAGE_SHIFT - 10); 422} 423 424static ssize_t dirty_writeback_stats_show(struct kobject *kobj, 425 struct sbi_attribute *attr, 426 char *buf) 427{ 428 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 429 struct hmdfs_writeback *hwb = sbi->h_wb; 430 unsigned long avg; 431 unsigned long max; 432 unsigned long min; 433 434 spin_lock(&hwb->write_bandwidth_lock); 435 avg = hwb->avg_write_bandwidth; 436 max = hwb->max_write_bandwidth; 437 min = hwb->min_write_bandwidth; 438 spin_unlock(&hwb->write_bandwidth_lock); 439 440 if (min == ULONG_MAX) 441 min = 0; 442 443 return snprintf(buf, PAGE_SIZE, 444 "%10lu\n" 445 "%10lu\n" 446 "%10lu\n", 447 pages_to_kbytes(avg), 448 pages_to_kbytes(max), 449 pages_to_kbytes(min)); 450} 451 452static struct sbi_attribute sbi_dirty_writeback_stats_attr = 453 __ATTR_RO(dirty_writeback_stats); 454 455static ssize_t sbi_wb_timeout_ms_show(struct kobject *kobj, 456 struct sbi_attribute *attr, 457 char *buf) 458{ 459 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 460 461 return snprintf(buf, PAGE_SIZE, "%u\n", sbi->wb_timeout_ms); 462} 463 464static ssize_t sbi_wb_timeout_ms_store(struct kobject *kobj, 465 struct sbi_attribute *attr, 466 const char *buf, size_t len) 467{ 468 struct hmdfs_sb_info *sbi = to_sbi(kobj); 469 unsigned int val; 470 int err; 471 472 err = kstrtouint(buf, 10, &val); 473 if (err) 474 return err; 475 476 if (!val || val > HMDFS_MAX_WB_TIMEOUT_MS) 477 return -EINVAL; 478 479 sbi->wb_timeout_ms = val; 480 481 return len; 482} 483 484static struct sbi_attribute sbi_wb_timeout_ms_attr = 485 __ATTR(wb_timeout_ms, 0664, sbi_wb_timeout_ms_show, 486 sbi_wb_timeout_ms_store); 487 488static ssize_t sbi_dirty_writeback_centisecs_show(struct kobject *kobj, 489 struct sbi_attribute *attr, 490 char *buf) 491{ 492 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 493 494 return snprintf(buf, PAGE_SIZE, "%u\n", 495 sbi->h_wb->dirty_writeback_interval); 496} 497 498static ssize_t sbi_dirty_writeback_centisecs_store(struct kobject *kobj, 499 struct sbi_attribute *attr, 500 const char *buf, size_t len) 501{ 502 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 503 int err; 504 505 err = kstrtouint(buf, 10, &sbi->h_wb->dirty_writeback_interval); 506 if (err) 507 return err; 508 return len; 509} 510 511static struct sbi_attribute sbi_dirty_writeback_centisecs_attr = 512 __ATTR(dirty_writeback_centisecs, 0664, 513 sbi_dirty_writeback_centisecs_show, 514 sbi_dirty_writeback_centisecs_store); 515 516static ssize_t sbi_dirty_file_background_bytes_show(struct kobject *kobj, 517 struct sbi_attribute *attr, 518 char *buf) 519{ 520 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 521 522 return snprintf(buf, PAGE_SIZE, "%lu\n", 523 sbi->h_wb->dirty_file_bg_bytes); 524} 525 526static ssize_t sbi_dirty_file_background_bytes_store(struct kobject *kobj, 527 struct sbi_attribute *attr, 528 const char *buf, 529 size_t len) 530{ 531 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 532 unsigned long file_background_bytes = 0; 533 int err; 534 535 err = kstrtoul(buf, 10, &file_background_bytes); 536 if (err) 537 return err; 538 if (file_background_bytes == 0) 539 return -EINVAL; 540 541 sbi->h_wb->dirty_fs_bytes = 542 max(sbi->h_wb->dirty_fs_bytes, file_background_bytes); 543 sbi->h_wb->dirty_fs_bg_bytes = 544 max(sbi->h_wb->dirty_fs_bg_bytes, file_background_bytes); 545 sbi->h_wb->dirty_file_bytes = 546 max(sbi->h_wb->dirty_file_bytes, file_background_bytes); 547 548 sbi->h_wb->dirty_file_bg_bytes = file_background_bytes; 549 hmdfs_calculate_dirty_thresh(sbi->h_wb); 550 hmdfs_update_ratelimit(sbi->h_wb); 551 return len; 552} 553 554static ssize_t sbi_dirty_fs_background_bytes_show(struct kobject *kobj, 555 struct sbi_attribute *attr, 556 char *buf) 557{ 558 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 559 560 return snprintf(buf, PAGE_SIZE, "%lu\n", sbi->h_wb->dirty_fs_bg_bytes); 561} 562 563static ssize_t sbi_dirty_fs_background_bytes_store(struct kobject *kobj, 564 struct sbi_attribute *attr, 565 const char *buf, size_t len) 566{ 567 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 568 unsigned long fs_background_bytes = 0; 569 int err; 570 571 err = kstrtoul(buf, 10, &fs_background_bytes); 572 if (err) 573 return err; 574 if (fs_background_bytes == 0) 575 return -EINVAL; 576 577 sbi->h_wb->dirty_file_bg_bytes = 578 min(sbi->h_wb->dirty_file_bg_bytes, fs_background_bytes); 579 sbi->h_wb->dirty_fs_bytes = 580 max(sbi->h_wb->dirty_fs_bytes, fs_background_bytes); 581 582 sbi->h_wb->dirty_fs_bg_bytes = fs_background_bytes; 583 hmdfs_calculate_dirty_thresh(sbi->h_wb); 584 hmdfs_update_ratelimit(sbi->h_wb); 585 return len; 586} 587 588static struct sbi_attribute sbi_dirty_file_background_bytes_attr = 589 __ATTR(dirty_file_background_bytes, 0644, 590 sbi_dirty_file_background_bytes_show, 591 sbi_dirty_file_background_bytes_store); 592static struct sbi_attribute sbi_dirty_fs_background_bytes_attr = 593 __ATTR(dirty_fs_background_bytes, 0644, 594 sbi_dirty_fs_background_bytes_show, 595 sbi_dirty_fs_background_bytes_store); 596 597static ssize_t sbi_dirty_file_bytes_show(struct kobject *kobj, 598 struct sbi_attribute *attr, char *buf) 599{ 600 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 601 602 return snprintf(buf, PAGE_SIZE, "%lu\n", sbi->h_wb->dirty_file_bytes); 603} 604 605static ssize_t sbi_dirty_file_bytes_store(struct kobject *kobj, 606 struct sbi_attribute *attr, 607 const char *buf, size_t len) 608{ 609 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 610 unsigned long file_bytes = 0; 611 int err; 612 613 err = kstrtoul(buf, 10, &file_bytes); 614 if (err) 615 return err; 616 if (file_bytes == 0) 617 return -EINVAL; 618 619 sbi->h_wb->dirty_file_bg_bytes = 620 min(sbi->h_wb->dirty_file_bg_bytes, file_bytes); 621 sbi->h_wb->dirty_fs_bytes = max(sbi->h_wb->dirty_fs_bytes, file_bytes); 622 623 sbi->h_wb->dirty_file_bytes = file_bytes; 624 hmdfs_calculate_dirty_thresh(sbi->h_wb); 625 hmdfs_update_ratelimit(sbi->h_wb); 626 return len; 627} 628 629static ssize_t sbi_dirty_fs_bytes_show(struct kobject *kobj, 630 struct sbi_attribute *attr, char *buf) 631{ 632 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 633 634 return snprintf(buf, PAGE_SIZE, "%lu\n", sbi->h_wb->dirty_fs_bytes); 635} 636 637static ssize_t sbi_dirty_fs_bytes_store(struct kobject *kobj, 638 struct sbi_attribute *attr, 639 const char *buf, size_t len) 640{ 641 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 642 unsigned long fs_bytes = 0; 643 int err; 644 645 err = kstrtoul(buf, 10, &fs_bytes); 646 if (err) 647 return err; 648 if (fs_bytes == 0) 649 return -EINVAL; 650 651 sbi->h_wb->dirty_file_bg_bytes = 652 min(sbi->h_wb->dirty_file_bg_bytes, fs_bytes); 653 sbi->h_wb->dirty_file_bytes = 654 min(sbi->h_wb->dirty_file_bytes, fs_bytes); 655 sbi->h_wb->dirty_fs_bg_bytes = 656 min(sbi->h_wb->dirty_fs_bg_bytes, fs_bytes); 657 658 sbi->h_wb->dirty_fs_bytes = fs_bytes; 659 hmdfs_calculate_dirty_thresh(sbi->h_wb); 660 hmdfs_update_ratelimit(sbi->h_wb); 661 return len; 662} 663 664static struct sbi_attribute sbi_dirty_file_bytes_attr = 665 __ATTR(dirty_file_bytes, 0644, sbi_dirty_file_bytes_show, 666 sbi_dirty_file_bytes_store); 667static struct sbi_attribute sbi_dirty_fs_bytes_attr = 668 __ATTR(dirty_fs_bytes, 0644, sbi_dirty_fs_bytes_show, 669 sbi_dirty_fs_bytes_store); 670 671static ssize_t sbi_dirty_writeback_timelimit_show(struct kobject *kobj, 672 struct sbi_attribute *attr, 673 char *buf) 674{ 675 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 676 677 return snprintf(buf, PAGE_SIZE, "%u\n", 678 sbi->h_wb->writeback_timelimit / HZ); 679} 680 681static ssize_t sbi_dirty_writeback_timelimit_store(struct kobject *kobj, 682 struct sbi_attribute *attr, 683 const char *buf, 684 size_t len) 685{ 686 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 687 unsigned int time_limit = 0; 688 int err; 689 690 err = kstrtouint(buf, 10, &time_limit); 691 if (err) 692 return err; 693 if (time_limit == 0 || time_limit > (HMDFS_MAX_WB_TIMELIMIT / HZ)) 694 return -EINVAL; 695 696 sbi->h_wb->writeback_timelimit = time_limit * HZ; 697 return len; 698} 699 700static struct sbi_attribute sbi_dirty_writeback_timelimit_attr = 701__ATTR(dirty_writeback_timelimit, 0644, sbi_dirty_writeback_timelimit_show, 702 sbi_dirty_writeback_timelimit_store); 703 704static ssize_t sbi_dirty_thresh_lowerlimit_show(struct kobject *kobj, 705 struct sbi_attribute *attr, 706 char *buf) 707{ 708 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 709 710 return snprintf(buf, PAGE_SIZE, "%lu\n", 711 sbi->h_wb->bw_thresh_lowerlimit << PAGE_SHIFT); 712} 713 714static ssize_t sbi_dirty_thresh_lowerlimit_store(struct kobject *kobj, 715 struct sbi_attribute *attr, 716 const char *buf, 717 size_t len) 718{ 719 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 720 unsigned long bw_thresh_lowerbytes = 0; 721 unsigned long bw_thresh_lowerlimit; 722 int err; 723 724 err = kstrtoul(buf, 10, &bw_thresh_lowerbytes); 725 if (err) 726 return err; 727 728 bw_thresh_lowerlimit = DIV_ROUND_UP(bw_thresh_lowerbytes, PAGE_SIZE); 729 if (bw_thresh_lowerlimit < HMDFS_BW_THRESH_MIN_LIMIT || 730 bw_thresh_lowerlimit > HMDFS_BW_THRESH_MAX_LIMIT) 731 return -EINVAL; 732 733 sbi->h_wb->bw_thresh_lowerlimit = bw_thresh_lowerlimit; 734 return len; 735} 736 737static struct sbi_attribute sbi_dirty_thresh_lowerlimit_attr = 738__ATTR(dirty_thresh_lowerlimit, 0644, sbi_dirty_thresh_lowerlimit_show, 739 sbi_dirty_thresh_lowerlimit_store); 740 741static ssize_t sbi_dirty_writeback_autothresh_show(struct kobject *kobj, 742 struct sbi_attribute *attr, 743 char *buf) 744{ 745 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 746 747 return snprintf(buf, PAGE_SIZE, "%d\n", 748 sbi->h_wb->dirty_auto_threshold); 749} 750 751static ssize_t sbi_dirty_writeback_autothresh_store(struct kobject *kobj, 752 struct sbi_attribute *attr, 753 const char *buf, 754 size_t len) 755{ 756 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 757 bool dirty_auto_threshold = false; 758 int err; 759 760 err = kstrtobool(buf, &dirty_auto_threshold); 761 if (err) 762 return err; 763 764 sbi->h_wb->dirty_auto_threshold = dirty_auto_threshold; 765 return len; 766} 767 768static struct sbi_attribute sbi_dirty_writeback_autothresh_attr = 769__ATTR(dirty_writeback_autothresh, 0644, sbi_dirty_writeback_autothresh_show, 770 sbi_dirty_writeback_autothresh_store); 771 772static ssize_t sbi_dirty_writeback_control_show(struct kobject *kobj, 773 struct sbi_attribute *attr, 774 char *buf) 775{ 776 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 777 778 return snprintf(buf, PAGE_SIZE, "%d\n", 779 sbi->h_wb->dirty_writeback_control); 780} 781 782static ssize_t sbi_dirty_writeback_control_store(struct kobject *kobj, 783 struct sbi_attribute *attr, 784 const char *buf, size_t len) 785{ 786 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 787 unsigned int dirty_writeback_control = 0; 788 int err; 789 790 err = kstrtouint(buf, 10, &dirty_writeback_control); 791 if (err) 792 return err; 793 794 sbi->h_wb->dirty_writeback_control = (bool)dirty_writeback_control; 795 return len; 796} 797 798static struct sbi_attribute sbi_dirty_writeback_control_attr = 799 __ATTR(dirty_writeback_control, 0644, sbi_dirty_writeback_control_show, 800 sbi_dirty_writeback_control_store); 801 802static ssize_t sbi_srv_dirty_thresh_show(struct kobject *kobj, 803 struct sbi_attribute *attr, 804 char *buf) 805{ 806 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 807 808 return snprintf(buf, PAGE_SIZE, "%d\n", 809 sbi->h_swb->dirty_thresh_pg >> HMDFS_MB_TO_PAGE_SHIFT); 810} 811 812static ssize_t sbi_srv_dirty_thresh_store(struct kobject *kobj, 813 struct sbi_attribute *attr, 814 const char *buf, 815 size_t len) 816{ 817 struct hmdfs_server_writeback *hswb = to_sbi(kobj)->h_swb; 818 int dirty_thresh_mb; 819 unsigned long long pages; 820 int err; 821 822 err = kstrtoint(buf, 10, &dirty_thresh_mb); 823 if (err) 824 return err; 825 826 if (dirty_thresh_mb <= 0) 827 return -EINVAL; 828 829 pages = dirty_thresh_mb; 830 pages <<= HMDFS_MB_TO_PAGE_SHIFT; 831 if (pages > INT_MAX) { 832 hmdfs_err("Illegal dirty_thresh_mb %d, its page count beyonds max int", 833 dirty_thresh_mb); 834 return -EINVAL; 835 } 836 837 hswb->dirty_thresh_pg = (unsigned int)pages; 838 return len; 839} 840 841static struct sbi_attribute sbi_srv_dirty_thresh_attr = 842__ATTR(srv_dirty_thresh, 0644, sbi_srv_dirty_thresh_show, 843 sbi_srv_dirty_thresh_store); 844 845 846static ssize_t sbi_srv_dirty_wb_control_show(struct kobject *kobj, 847 struct sbi_attribute *attr, 848 char *buf) 849{ 850 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 851 852 return snprintf(buf, PAGE_SIZE, "%d\n", 853 sbi->h_swb->dirty_writeback_control); 854} 855 856static ssize_t sbi_srv_dirty_wb_conctrol_store(struct kobject *kobj, 857 struct sbi_attribute *attr, 858 const char *buf, 859 size_t len) 860{ 861 struct hmdfs_server_writeback *hswb = to_sbi(kobj)->h_swb; 862 bool dirty_writeback_control = true; 863 int err; 864 865 err = kstrtobool(buf, &dirty_writeback_control); 866 if (err) 867 return err; 868 869 hswb->dirty_writeback_control = dirty_writeback_control; 870 871 return len; 872} 873 874static struct sbi_attribute sbi_srv_dirty_wb_control_attr = 875__ATTR(srv_dirty_writeback_control, 0644, sbi_srv_dirty_wb_control_show, 876 sbi_srv_dirty_wb_conctrol_store); 877 878static ssize_t sbi_dcache_timeout_show(struct kobject *kobj, 879 struct sbi_attribute *attr, char *buf) 880{ 881 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 882 883 return snprintf(buf, PAGE_SIZE, "%u\n", sbi->dcache_timeout); 884} 885 886static ssize_t sbi_dcache_timeout_store(struct kobject *kobj, 887 struct sbi_attribute *attr, 888 const char *buf, size_t len) 889{ 890 struct hmdfs_sb_info *sbi = to_sbi(kobj); 891 unsigned int timeout; 892 int err; 893 894 err = kstrtouint(buf, 0, &timeout); 895 if (err) 896 return err; 897 898 /* zero is invalid, and it doesn't mean no cache */ 899 if (timeout == 0 || timeout > MAX_DCACHE_TIMEOUT) 900 return -EINVAL; 901 902 sbi->dcache_timeout = timeout; 903 904 return len; 905} 906 907static struct sbi_attribute sbi_dcache_timeout_attr = 908 __ATTR(dcache_timeout, 0644, sbi_dcache_timeout_show, 909 sbi_dcache_timeout_store); 910 911static ssize_t sbi_write_cache_timeout_sec_show(struct kobject *kobj, 912 struct sbi_attribute *attr, char *buf) 913{ 914 return snprintf(buf, PAGE_SIZE, "%u\n", 915 to_sbi(kobj)->write_cache_timeout); 916} 917 918static ssize_t sbi_write_cache_timeout_sec_store(struct kobject *kobj, 919 struct sbi_attribute *attr, const char *buf, size_t len) 920{ 921 int ret; 922 unsigned int timeout; 923 struct hmdfs_sb_info *sbi = to_sbi(kobj); 924 925 ret = kstrtouint(buf, 0, &timeout); 926 if (ret) 927 return ret; 928 929 /* set write_cache_timeout to 0 means this functionality is disabled */ 930 sbi->write_cache_timeout = timeout; 931 932 return len; 933} 934 935static struct sbi_attribute sbi_write_cache_timeout_sec_attr = 936 __ATTR(write_cache_timeout_sec, 0664, sbi_write_cache_timeout_sec_show, 937 sbi_write_cache_timeout_sec_store); 938 939static ssize_t sbi_node_evt_cb_delay_show(struct kobject *kobj, 940 struct sbi_attribute *attr, 941 char *buf) 942{ 943 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 944 945 return snprintf(buf, PAGE_SIZE, "%u\n", sbi->async_cb_delay); 946} 947 948static ssize_t sbi_node_evt_cb_delay_store(struct kobject *kobj, 949 struct sbi_attribute *attr, 950 const char *buf, 951 size_t len) 952{ 953 struct hmdfs_sb_info *sbi = to_sbi(kobj); 954 unsigned int delay = 0; 955 int err; 956 957 err = kstrtouint(buf, 10, &delay); 958 if (err) 959 return err; 960 961 sbi->async_cb_delay = delay; 962 963 return len; 964} 965 966static struct sbi_attribute sbi_node_evt_cb_delay_attr = 967__ATTR(node_event_delay, 0644, sbi_node_evt_cb_delay_show, 968 sbi_node_evt_cb_delay_store); 969 970static int calc_idr_number(struct idr *idr) 971{ 972 void *entry = NULL; 973 int id; 974 int number = 0; 975 976 idr_for_each_entry(idr, entry, id) { 977 number++; 978 if (number % HMDFS_IDR_RESCHED_COUNT == 0) 979 cond_resched(); 980 } 981 982 return number; 983} 984 985static ssize_t sbi_show_idr_stats(struct kobject *kobj, 986 struct sbi_attribute *attr, 987 char *buf, bool showmsg) 988{ 989 ssize_t size = 0; 990 int count; 991 struct hmdfs_sb_info *sbi = NULL; 992 struct hmdfs_peer *peer = NULL; 993 struct idr *idr = NULL; 994 995 sbi = to_sbi(kobj); 996 997 mutex_lock(&sbi->connections.node_lock); 998 list_for_each_entry(peer, &sbi->connections.node_list, list) { 999 idr = showmsg ? &peer->msg_idr : &peer->file_id_idr; 1000 count = calc_idr_number(idr); 1001 size += snprintf(buf + size, PAGE_SIZE - size, 1002 "device-id\tcount\tnext-id\n\t%llu\t\t%d\t%u\n", 1003 peer->device_id, count, idr_get_cursor(idr)); 1004 if (size >= PAGE_SIZE) { 1005 size = PAGE_SIZE; 1006 break; 1007 } 1008 } 1009 mutex_unlock(&sbi->connections.node_lock); 1010 1011 return size; 1012} 1013 1014static ssize_t pending_message_show(struct kobject *kobj, 1015 struct sbi_attribute *attr, 1016 char *buf) 1017{ 1018 return sbi_show_idr_stats(kobj, attr, buf, true); 1019} 1020 1021static struct sbi_attribute sbi_pending_message_attr = 1022 __ATTR_RO(pending_message); 1023 1024static ssize_t peer_opened_fd_show(struct kobject *kobj, 1025 struct sbi_attribute *attr, char *buf) 1026{ 1027 return sbi_show_idr_stats(kobj, attr, buf, false); 1028} 1029 1030static struct sbi_attribute sbi_peer_opened_fd_attr = __ATTR_RO(peer_opened_fd); 1031 1032static ssize_t sbi_srv_req_max_active_attr_show(struct kobject *kobj, 1033 struct sbi_attribute *attr, 1034 char *buf) 1035{ 1036 const struct hmdfs_sb_info *sbi = to_sbi(kobj); 1037 1038 return snprintf(buf, PAGE_SIZE, "%u\n", sbi->async_req_max_active); 1039} 1040 1041static ssize_t sbi_srv_req_max_active_attr_store(struct kobject *kobj, 1042 struct sbi_attribute *attr, const char *buf, size_t len) 1043{ 1044 int ret; 1045 unsigned int max_active; 1046 struct hmdfs_sb_info *sbi = to_sbi(kobj); 1047 1048 ret = kstrtouint(buf, 0, &max_active); 1049 if (ret) 1050 return ret; 1051 1052 sbi->async_req_max_active = max_active; 1053 1054 return len; 1055} 1056 1057static struct sbi_attribute sbi_srv_req_max_active_attr = 1058__ATTR(srv_req_handle_max_active, 0644, sbi_srv_req_max_active_attr_show, 1059 sbi_srv_req_max_active_attr_store); 1060 1061 1062static ssize_t cache_file_show(struct hmdfs_sb_info *sbi, 1063 struct list_head *head, char *buf) 1064{ 1065 struct cache_file_node *cfn = NULL; 1066 ssize_t pos = 0; 1067 1068 mutex_lock(&sbi->cache_list_lock); 1069 list_for_each_entry(cfn, head, list) { 1070 pos += snprintf(buf + pos, PAGE_SIZE - pos, 1071 "dev_id: %s relative_path: %s\n", 1072 cfn->cid, cfn->relative_path); 1073 if (pos >= PAGE_SIZE) { 1074 pos = PAGE_SIZE; 1075 break; 1076 } 1077 } 1078 mutex_unlock(&sbi->cache_list_lock); 1079 1080 return pos; 1081} 1082 1083static ssize_t client_cache_file_show(struct kobject *kobj, 1084 struct sbi_attribute *attr, char *buf) 1085{ 1086 return cache_file_show(to_sbi(kobj), &to_sbi(kobj)->client_cache, buf); 1087} 1088static ssize_t server_cache_file_show(struct kobject *kobj, 1089 struct sbi_attribute *attr, char *buf) 1090{ 1091 return cache_file_show(to_sbi(kobj), &to_sbi(kobj)->server_cache, buf); 1092} 1093 1094static struct sbi_attribute sbi_server_cache_file_attr = 1095 __ATTR_RO(server_cache_file); 1096static struct sbi_attribute sbi_client_cache_file_attr = 1097 __ATTR_RO(client_cache_file); 1098 1099static ssize_t sb_seq_show(struct kobject *kobj, struct sbi_attribute *attr, 1100 char *buf) 1101{ 1102 return snprintf(buf, PAGE_SIZE, "%u\n", to_sbi(kobj)->seq); 1103} 1104 1105static struct sbi_attribute sbi_seq_attr = __ATTR_RO(sb_seq); 1106 1107static ssize_t peers_sum_attr_show(struct kobject *kobj, 1108 struct sbi_attribute *attr, char *buf) 1109{ 1110 struct hmdfs_sb_info *sbi = to_sbi(kobj); 1111 struct hmdfs_peer *node = NULL; 1112 unsigned int stash_ok = 0, stash_fail = 0, restore_ok = 0, 1113 restore_fail = 0, rebuild_ok = 0, rebuild_fail = 0, rebuild_invalid = 0, 1114 rebuild_time = 0; 1115 unsigned long long stash_ok_pages = 0, stash_fail_pages = 0, 1116 restore_ok_pages = 0, restore_fail_pages = 0; 1117 1118 mutex_lock(&sbi->connections.node_lock); 1119 list_for_each_entry(node, &sbi->connections.node_list, list) { 1120 peer_get(node); 1121 mutex_unlock(&sbi->connections.node_lock); 1122 stash_ok += node->stats.stash.total_ok; 1123 stash_fail += node->stats.stash.total_fail; 1124 stash_ok_pages += node->stats.stash.ok_pages; 1125 stash_fail_pages += node->stats.stash.fail_pages; 1126 restore_ok += node->stats.restore.total_ok; 1127 restore_fail += node->stats.restore.total_fail; 1128 restore_ok_pages += node->stats.restore.ok_pages; 1129 restore_fail_pages += node->stats.restore.fail_pages; 1130 rebuild_ok += node->stats.rebuild.total_ok; 1131 rebuild_fail += node->stats.rebuild.total_fail; 1132 rebuild_invalid += node->stats.rebuild.total_invalid; 1133 rebuild_time += node->stats.rebuild.time; 1134 peer_put(node); 1135 mutex_lock(&sbi->connections.node_lock); 1136 } 1137 mutex_unlock(&sbi->connections.node_lock); 1138 1139 return snprintf(buf, PAGE_SIZE, 1140 "%u %u %llu %llu\n" 1141 "%u %u %llu %llu\n" 1142 "%u %u %u %u\n", 1143 stash_ok, stash_fail, stash_ok_pages, stash_fail_pages, 1144 restore_ok, restore_fail, restore_ok_pages, 1145 restore_fail_pages, rebuild_ok, rebuild_fail, 1146 rebuild_invalid, rebuild_time); 1147} 1148 1149static struct sbi_attribute sbi_peers_attr = __ATTR_RO(peers_sum_attr); 1150 1151const char * const flag_name[] = { 1152 "READPAGES", 1153 "READPAGES_OPEN", 1154 "ATOMIC_OPEN", 1155}; 1156 1157static ssize_t fill_features(char *buf, unsigned long long flag) 1158{ 1159 int i; 1160 ssize_t pos = 0; 1161 bool sep = false; 1162 int flag_name_count = ARRAY_SIZE(flag_name) / sizeof(flag_name[0]); 1163 1164 for (i = 0; i < sizeof(flag) * BITS_PER_BYTE; ++i) { 1165 if (!(flag & BIT(i))) 1166 continue; 1167 1168 if (sep) 1169 pos += snprintf(buf + pos, PAGE_SIZE - pos, "|"); 1170 sep = true; 1171 1172 if (pos >= PAGE_SIZE) { 1173 pos = PAGE_SIZE; 1174 break; 1175 } 1176 1177 if (i < flag_name_count && flag_name[i]) 1178 pos += snprintf(buf + pos, PAGE_SIZE - pos, "%s", 1179 flag_name[i]); 1180 else 1181 pos += snprintf(buf + pos, PAGE_SIZE - pos, "%d", i); 1182 1183 if (pos >= PAGE_SIZE) { 1184 pos = PAGE_SIZE; 1185 break; 1186 } 1187 } 1188 pos += snprintf(buf + pos, PAGE_SIZE - pos, "\n"); 1189 if (pos >= PAGE_SIZE) 1190 pos = PAGE_SIZE; 1191 1192 return pos; 1193} 1194 1195static ssize_t sbi_features_show(struct kobject *kobj, 1196 struct sbi_attribute *attr, char *buf) 1197{ 1198 struct hmdfs_sb_info *sbi = to_sbi(kobj); 1199 1200 return fill_features(buf, sbi->s_features); 1201} 1202 1203static struct sbi_attribute sbi_features_attr = __ATTR(features, 0444, 1204 sbi_features_show, NULL); 1205 1206static struct attribute *sbi_attrs[] = { 1207 &sbi_cmd_attr.attr, 1208 &sbi_status_attr.attr, 1209 &sbi_statistic_attr.attr, 1210 &sbi_dcache_precision_attr.attr, 1211 &sbi_dcache_threshold_attr.attr, 1212 &sbi_dcache_timeout_attr.attr, 1213 &sbi_write_cache_timeout_sec_attr.attr, 1214 &sbi_local_op_attr.attr, 1215 &sbi_delay_resp_attr.attr, 1216 &sbi_wb_timeout_ms_attr.attr, 1217 &sbi_dirty_writeback_centisecs_attr.attr, 1218 &sbi_dirty_file_background_bytes_attr.attr, 1219 &sbi_dirty_fs_background_bytes_attr.attr, 1220 &sbi_dirty_file_bytes_attr.attr, 1221 &sbi_dirty_fs_bytes_attr.attr, 1222 &sbi_dirty_writeback_autothresh_attr.attr, 1223 &sbi_dirty_writeback_timelimit_attr.attr, 1224 &sbi_dirty_thresh_lowerlimit_attr.attr, 1225 &sbi_dirty_writeback_control_attr.attr, 1226 &sbi_dirty_writeback_stats_attr.attr, 1227 &sbi_srv_dirty_thresh_attr.attr, 1228 &sbi_srv_dirty_wb_control_attr.attr, 1229 &sbi_node_evt_cb_delay_attr.attr, 1230 &sbi_srv_req_max_active_attr.attr, 1231 &sbi_pending_message_attr.attr, 1232 &sbi_peer_opened_fd_attr.attr, 1233 &sbi_server_cache_file_attr.attr, 1234 &sbi_client_cache_file_attr.attr, 1235 &sbi_seq_attr.attr, 1236 &sbi_peers_attr.attr, 1237 &sbi_features_attr.attr, 1238 NULL, 1239}; 1240 1241static ssize_t sbi_attr_show(struct kobject *kobj, struct attribute *attr, 1242 char *buf) 1243{ 1244 struct sbi_attribute *sbi_attr = to_sbi_attr(attr); 1245 1246 if (!sbi_attr->show) 1247 return -EIO; 1248 return sbi_attr->show(kobj, sbi_attr, buf); 1249} 1250 1251static ssize_t sbi_attr_store(struct kobject *kobj, struct attribute *attr, 1252 const char *buf, size_t len) 1253{ 1254 struct sbi_attribute *sbi_attr = to_sbi_attr(attr); 1255 1256 if (!sbi_attr->store) 1257 return -EIO; 1258 return sbi_attr->store(kobj, sbi_attr, buf, len); 1259} 1260 1261static const struct sysfs_ops sbi_sysfs_ops = { 1262 .show = sbi_attr_show, 1263 .store = sbi_attr_store, 1264}; 1265 1266static void sbi_release(struct kobject *kobj) 1267{ 1268 struct hmdfs_sb_info *sbi = to_sbi(kobj); 1269 1270 complete(&sbi->s_kobj_unregister); 1271} 1272 1273static struct kobj_type sbi_ktype = { 1274 .sysfs_ops = &sbi_sysfs_ops, 1275 .default_attrs = sbi_attrs, 1276 .release = sbi_release, 1277}; 1278 1279static inline struct sbi_cmd_attribute *to_sbi_cmd_attr(struct attribute *x) 1280{ 1281 return container_of(x, struct sbi_cmd_attribute, attr); 1282} 1283 1284static inline struct hmdfs_sb_info *cmd_kobj_to_sbi(struct kobject *x) 1285{ 1286 return container_of(x, struct hmdfs_sb_info, s_cmd_timeout_kobj); 1287} 1288 1289static ssize_t cmd_timeout_show(struct kobject *kobj, struct attribute *attr, 1290 char *buf) 1291{ 1292 int cmd = to_sbi_cmd_attr(attr)->command; 1293 struct hmdfs_sb_info *sbi = cmd_kobj_to_sbi(kobj); 1294 1295 if (cmd < 0 || cmd >= F_SIZE) 1296 return 0; 1297 1298 return snprintf(buf, PAGE_SIZE, "%u\n", get_cmd_timeout(sbi, cmd)); 1299} 1300 1301static ssize_t cmd_timeout_store(struct kobject *kobj, struct attribute *attr, 1302 const char *buf, size_t len) 1303{ 1304 unsigned int value; 1305 int cmd = to_sbi_cmd_attr(attr)->command; 1306 int ret = kstrtouint(skip_spaces(buf), 0, &value); 1307 struct hmdfs_sb_info *sbi = cmd_kobj_to_sbi(kobj); 1308 1309 if (cmd < 0 || cmd >= F_SIZE) 1310 return -EINVAL; 1311 1312 if (!ret) 1313 set_cmd_timeout(sbi, cmd, value); 1314 1315 return ret ? ret : len; 1316} 1317 1318#define HMDFS_CMD_ATTR(_name, _cmd) \ 1319 static struct sbi_cmd_attribute hmdfs_attr_##_name = { \ 1320 .attr = { .name = __stringify(_name), .mode = 0664 }, \ 1321 .command = (_cmd), \ 1322 } 1323 1324HMDFS_CMD_ATTR(open, F_OPEN); 1325HMDFS_CMD_ATTR(release, F_RELEASE); 1326HMDFS_CMD_ATTR(readpage, F_READPAGE); 1327HMDFS_CMD_ATTR(writepage, F_WRITEPAGE); 1328HMDFS_CMD_ATTR(iterate, F_ITERATE); 1329HMDFS_CMD_ATTR(rmdir, F_RMDIR); 1330HMDFS_CMD_ATTR(unlink, F_UNLINK); 1331HMDFS_CMD_ATTR(rename, F_RENAME); 1332HMDFS_CMD_ATTR(setattr, F_SETATTR); 1333HMDFS_CMD_ATTR(statfs, F_STATFS); 1334HMDFS_CMD_ATTR(drop_push, F_DROP_PUSH); 1335HMDFS_CMD_ATTR(getattr, F_GETATTR); 1336HMDFS_CMD_ATTR(fsync, F_FSYNC); 1337HMDFS_CMD_ATTR(syncfs, F_SYNCFS); 1338HMDFS_CMD_ATTR(getxattr, F_GETXATTR); 1339HMDFS_CMD_ATTR(setxattr, F_SETXATTR); 1340HMDFS_CMD_ATTR(listxattr, F_LISTXATTR); 1341 1342#define ATTR_LIST(_name) (&hmdfs_attr_##_name.attr) 1343 1344static struct attribute *sbi_timeout_attrs[] = { 1345 ATTR_LIST(open), ATTR_LIST(release), 1346 ATTR_LIST(readpage), ATTR_LIST(writepage), 1347 ATTR_LIST(iterate), ATTR_LIST(rmdir), 1348 ATTR_LIST(unlink), ATTR_LIST(rename), 1349 ATTR_LIST(setattr), 1350 ATTR_LIST(statfs), ATTR_LIST(drop_push), 1351 ATTR_LIST(getattr), ATTR_LIST(fsync), 1352 ATTR_LIST(syncfs), ATTR_LIST(getxattr), 1353 ATTR_LIST(setxattr), ATTR_LIST(listxattr), 1354 NULL 1355}; 1356 1357static const struct sysfs_ops sbi_cmd_sysfs_ops = { 1358 .show = cmd_timeout_show, 1359 .store = cmd_timeout_store, 1360}; 1361 1362static void sbi_timeout_release(struct kobject *kobj) 1363{ 1364 struct hmdfs_sb_info *sbi = container_of(kobj, struct hmdfs_sb_info, 1365 s_cmd_timeout_kobj); 1366 1367 complete(&sbi->s_timeout_kobj_unregister); 1368} 1369 1370static struct kobj_type sbi_timeout_ktype = { 1371 .sysfs_ops = &sbi_cmd_sysfs_ops, 1372 .default_attrs = sbi_timeout_attrs, 1373 .release = sbi_timeout_release, 1374}; 1375 1376void hmdfs_release_sysfs(struct hmdfs_sb_info *sbi) 1377{ 1378 kobject_put(&sbi->s_cmd_timeout_kobj); 1379 wait_for_completion(&sbi->s_timeout_kobj_unregister); 1380 kobject_put(&sbi->kobj); 1381 wait_for_completion(&sbi->s_kobj_unregister); 1382} 1383 1384int hmdfs_register_sysfs(const char *name, struct hmdfs_sb_info *sbi) 1385{ 1386 int ret; 1387 struct kobject *kobj = NULL; 1388 1389 mutex_lock(&hmdfs_sysfs_mutex); 1390 kobj = kset_find_obj(hmdfs_kset, name); 1391 if (kobj) { 1392 hmdfs_err("mount failed, already exist"); 1393 kobject_put(kobj); 1394 mutex_unlock(&hmdfs_sysfs_mutex); 1395 return -EEXIST; 1396 } 1397 1398 sbi->kobj.kset = hmdfs_kset; 1399 init_completion(&sbi->s_kobj_unregister); 1400 ret = kobject_init_and_add(&sbi->kobj, &sbi_ktype, 1401 &hmdfs_kset->kobj, "%s", name); 1402 sysfs_change_owner(&sbi->kobj, KUIDT_INIT(1000), KGIDT_INIT(1000)); 1403 mutex_unlock(&hmdfs_sysfs_mutex); 1404 1405 if (ret) { 1406 kobject_put(&sbi->kobj); 1407 wait_for_completion(&sbi->s_kobj_unregister); 1408 return ret; 1409 } 1410 1411 init_completion(&sbi->s_timeout_kobj_unregister); 1412 ret = kobject_init_and_add(&sbi->s_cmd_timeout_kobj, &sbi_timeout_ktype, 1413 &sbi->kobj, "cmd_timeout"); 1414 if (ret) { 1415 hmdfs_release_sysfs(sbi); 1416 return ret; 1417 } 1418 1419 kobject_uevent(&sbi->kobj, KOBJ_ADD); 1420 return 0; 1421} 1422 1423void hmdfs_unregister_sysfs(struct hmdfs_sb_info *sbi) 1424{ 1425 kobject_del(&sbi->s_cmd_timeout_kobj); 1426 kobject_del(&sbi->kobj); 1427} 1428 1429static inline int to_sysfs_fmt_evt(unsigned int evt) 1430{ 1431 return evt == RAW_NODE_EVT_NR ? -1 : evt; 1432} 1433 1434static ssize_t features_show(struct kobject *kobj, struct peer_attribute *attr, 1435 char *buf) 1436{ 1437 struct hmdfs_peer *peer = to_peer(kobj); 1438 1439 return fill_features(buf, peer->features); 1440} 1441 1442static ssize_t event_show(struct kobject *kobj, struct peer_attribute *attr, 1443 char *buf) 1444{ 1445 struct hmdfs_peer *peer = to_peer(kobj); 1446 1447 return snprintf(buf, PAGE_SIZE, 1448 "cur_async evt %d seq %u\n" 1449 "cur_sync evt %d seq %u\n" 1450 "pending evt %d seq %u\n" 1451 "merged evt %u\n" 1452 "dup_drop evt %u %u\n" 1453 "waiting evt %u %u\n" 1454 "seq_tbl %u %u %u %u\n" 1455 "seq_rd_idx %u\n" 1456 "seq_wr_idx %u\n", 1457 to_sysfs_fmt_evt(peer->cur_evt[0]), 1458 peer->cur_evt_seq[0], 1459 to_sysfs_fmt_evt(peer->cur_evt[1]), 1460 peer->cur_evt_seq[1], 1461 to_sysfs_fmt_evt(peer->pending_evt), 1462 peer->pending_evt_seq, 1463 peer->merged_evt, 1464 peer->dup_evt[RAW_NODE_EVT_OFF], 1465 peer->dup_evt[RAW_NODE_EVT_ON], 1466 peer->waiting_evt[RAW_NODE_EVT_OFF], 1467 peer->waiting_evt[RAW_NODE_EVT_ON], 1468 peer->seq_tbl[0], peer->seq_tbl[1], peer->seq_tbl[2], 1469 peer->seq_tbl[3], 1470 peer->seq_rd_idx % RAW_NODE_EVT_MAX_NR, 1471 peer->seq_wr_idx % RAW_NODE_EVT_MAX_NR); 1472} 1473 1474static ssize_t stash_show(struct kobject *kobj, struct peer_attribute *attr, 1475 char *buf) 1476{ 1477 struct hmdfs_peer *peer = to_peer(kobj); 1478 1479 return snprintf(buf, PAGE_SIZE, 1480 "cur_ok %u\n" 1481 "cur_nothing %u\n" 1482 "cur_fail %u\n" 1483 "total_ok %u\n" 1484 "total_nothing %u\n" 1485 "total_fail %u\n" 1486 "ok_pages %llu\n" 1487 "fail_pages %llu\n", 1488 peer->stats.stash.cur_ok, 1489 peer->stats.stash.cur_nothing, 1490 peer->stats.stash.cur_fail, 1491 peer->stats.stash.total_ok, 1492 peer->stats.stash.total_nothing, 1493 peer->stats.stash.total_fail, 1494 peer->stats.stash.ok_pages, 1495 peer->stats.stash.fail_pages); 1496} 1497 1498static ssize_t restore_show(struct kobject *kobj, struct peer_attribute *attr, 1499 char *buf) 1500{ 1501 struct hmdfs_peer *peer = to_peer(kobj); 1502 1503 return snprintf(buf, PAGE_SIZE, 1504 "cur_ok %u\n" 1505 "cur_fail %u\n" 1506 "cur_keep %u\n" 1507 "total_ok %u\n" 1508 "total_fail %u\n" 1509 "total_keep %u\n" 1510 "ok_pages %llu\n" 1511 "fail_pages %llu\n", 1512 peer->stats.restore.cur_ok, 1513 peer->stats.restore.cur_fail, 1514 peer->stats.restore.cur_keep, 1515 peer->stats.restore.total_ok, 1516 peer->stats.restore.total_fail, 1517 peer->stats.restore.total_keep, 1518 peer->stats.restore.ok_pages, 1519 peer->stats.restore.fail_pages); 1520} 1521 1522static ssize_t rebuild_show(struct kobject *kobj, struct peer_attribute *attr, 1523 char *buf) 1524{ 1525 struct hmdfs_peer *peer = to_peer(kobj); 1526 1527 return snprintf(buf, PAGE_SIZE, 1528 "cur_ok %u\n" 1529 "cur_fail %u\n" 1530 "cur_invalid %u\n" 1531 "total_ok %u\n" 1532 "total_fail %u\n" 1533 "total_invalid %u\n" 1534 "time %u\n", 1535 peer->stats.rebuild.cur_ok, 1536 peer->stats.rebuild.cur_fail, 1537 peer->stats.rebuild.cur_invalid, 1538 peer->stats.rebuild.total_ok, 1539 peer->stats.rebuild.total_fail, 1540 peer->stats.rebuild.total_invalid, 1541 peer->stats.rebuild.time); 1542} 1543 1544static struct peer_attribute peer_features_attr = __ATTR_RO(features); 1545static struct peer_attribute peer_event_attr = __ATTR_RO(event); 1546static struct peer_attribute peer_stash_attr = __ATTR_RO(stash); 1547static struct peer_attribute peer_restore_attr = __ATTR_RO(restore); 1548static struct peer_attribute peer_rebuild_attr = __ATTR_RO(rebuild); 1549 1550static struct attribute *peer_attrs[] = { 1551 &peer_features_attr.attr, 1552 &peer_event_attr.attr, 1553 &peer_stash_attr.attr, 1554 &peer_restore_attr.attr, 1555 &peer_rebuild_attr.attr, 1556 NULL, 1557}; 1558 1559static ssize_t peer_attr_show(struct kobject *kobj, struct attribute *attr, 1560 char *buf) 1561{ 1562 struct peer_attribute *peer_attr = to_peer_attr(attr); 1563 1564 if (!peer_attr->show) 1565 return -EIO; 1566 return peer_attr->show(kobj, peer_attr, buf); 1567} 1568 1569static ssize_t peer_attr_store(struct kobject *kobj, struct attribute *attr, 1570 const char *buf, size_t len) 1571{ 1572 struct peer_attribute *peer_attr = to_peer_attr(attr); 1573 1574 if (!peer_attr->store) 1575 return -EIO; 1576 return peer_attr->store(kobj, peer_attr, buf, len); 1577} 1578 1579static const struct sysfs_ops peer_sysfs_ops = { 1580 .show = peer_attr_show, 1581 .store = peer_attr_store, 1582}; 1583 1584static void peer_sysfs_release(struct kobject *kobj) 1585{ 1586 struct hmdfs_peer *peer = to_peer(kobj); 1587 1588 complete(&peer->kobj_unregister); 1589} 1590 1591static struct kobj_type peer_ktype = { 1592 .sysfs_ops = &peer_sysfs_ops, 1593 .default_attrs = peer_attrs, 1594 .release = peer_sysfs_release, 1595}; 1596 1597int hmdfs_register_peer_sysfs(struct hmdfs_sb_info *sbi, 1598 struct hmdfs_peer *peer) 1599{ 1600 int err = 0; 1601 1602 init_completion(&peer->kobj_unregister); 1603 err = kobject_init_and_add(&peer->kobj, &peer_ktype, &sbi->kobj, 1604 "peer_%llu", peer->device_id); 1605 return err; 1606} 1607 1608void hmdfs_release_peer_sysfs(struct hmdfs_peer *peer) 1609{ 1610 kobject_del(&peer->kobj); 1611 kobject_put(&peer->kobj); 1612 wait_for_completion(&peer->kobj_unregister); 1613} 1614 1615void notify(struct hmdfs_peer *node, struct notify_param *param) 1616{ 1617 struct hmdfs_sb_info *sbi = node->sbi; 1618 int in_len; 1619 1620 if (!param) 1621 return; 1622 spin_lock(&sbi->notify_fifo_lock); 1623 in_len = 1624 kfifo_in(&sbi->notify_fifo, param, sizeof(struct notify_param)); 1625 spin_unlock(&sbi->notify_fifo_lock); 1626 if (in_len != sizeof(struct notify_param)) 1627 return; 1628 sysfs_notify(&sbi->kobj, NULL, "cmd"); 1629} 1630 1631int hmdfs_sysfs_init(void) 1632{ 1633 hmdfs_kset = kset_create_and_add("hmdfs", NULL, fs_kobj); 1634 if (!hmdfs_kset) 1635 return -ENOMEM; 1636 1637 return 0; 1638} 1639 1640void hmdfs_sysfs_exit(void) 1641{ 1642 kset_unregister(hmdfs_kset); 1643 hmdfs_kset = NULL; 1644} 1645