1// SPDX-License-Identifier: GPL-2.0 2/* 3 * fs/hmdfs/hmdfs_server.c 4 * 5 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 6 */ 7 8#include "hmdfs_server.h" 9 10#include <linux/file.h> 11#include <linux/xattr.h> 12#include <linux/namei.h> 13#include <linux/statfs.h> 14#include <linux/mount.h> 15 16#include "authority/authentication.h" 17#include "hmdfs.h" 18#include "hmdfs_dentryfile.h" 19#include "hmdfs_share.h" 20#include "hmdfs_trace.h" 21#include "server_writeback.h" 22#include "comm/node_cb.h" 23 24#define HMDFS_MAX_HIDDEN_DIR 1 25 26struct hmdfs_open_info { 27 struct file *file; 28 struct inode *inode; 29 bool stat_valid; 30 struct kstat stat; 31 uint64_t real_ino; 32 int file_id; 33}; 34 35static void find_first_no_slash(const char **name, int *len) 36{ 37 const char *s = *name; 38 int l = *len; 39 40 while (l > 0 && *s == '/') { 41 s++; 42 l--; 43 } 44 45 *name = s; 46 *len = l; 47} 48 49static void find_first_slash(const char **name, int *len) 50{ 51 const char *s = *name; 52 int l = *len; 53 54 while (l > 0 && *s != '/') { 55 s++; 56 l--; 57 } 58 59 *name = s; 60 *len = l; 61} 62 63static bool path_contain_dotdot(const char *name, int len) 64{ 65 while (true) { 66 find_first_no_slash(&name, &len); 67 68 if (len == 0) 69 return false; 70 71 if (len >= 2 && name[0] == '.' && name[1] == '.' && 72 (len == 2 || name[2] == '/')) 73 return true; 74 75 find_first_slash(&name, &len); 76 } 77} 78 79static int insert_file_into_conn(struct hmdfs_peer *conn, struct file *file) 80{ 81 struct idr *idr = &(conn->file_id_idr); 82 int ret; 83 84 idr_preload(GFP_KERNEL); 85 spin_lock(&(conn->file_id_lock)); 86 ret = idr_alloc_cyclic(idr, file, 0, 0, GFP_NOWAIT); 87 spin_unlock(&(conn->file_id_lock)); 88 idr_preload_end(); 89 return ret; 90} 91 92/* 93 * get_file_from_conn - get file from conn by file_id. It should be noted that 94 * an additional reference will be acquired for returned file, the called should 95 * put it after the file is not used anymore. 96 */ 97static struct file *get_file_from_conn(struct hmdfs_peer *conn, __u32 file_id) 98{ 99 struct file *file; 100 struct idr *idr = &(conn->file_id_idr); 101 102 rcu_read_lock(); 103 file = idr_find(idr, file_id); 104 if (file && !get_file_rcu(file)) 105 file = NULL; 106 rcu_read_unlock(); 107 return file; 108} 109 110int remove_file_from_conn(struct hmdfs_peer *conn, __u32 file_id) 111{ 112 spinlock_t *lock = &(conn->file_id_lock); 113 struct idr *idr = &(conn->file_id_idr); 114 struct file *file; 115 116 spin_lock(lock); 117 file = idr_remove(idr, file_id); 118 spin_unlock(lock); 119 120 if (!file) { 121 return -ENOENT; 122 } else { 123 return 0; 124 } 125} 126 127struct file *hmdfs_open_link(struct hmdfs_sb_info *sbi, 128 const char *path) 129{ 130 struct file *file; 131 int err; 132 const char *root_name = sbi->local_dst; 133 char *real_path; 134 int path_len; 135 136 path_len = strlen(root_name) + strlen(path) + 2; 137 if (path_len > PATH_MAX) { 138 err = -EINVAL; 139 return ERR_PTR(err); 140 } 141 real_path = kzalloc(path_len, GFP_KERNEL); 142 if (!real_path) { 143 err = -ENOMEM; 144 return ERR_PTR(err); 145 } 146 147 sprintf(real_path, "%s%s", root_name, path); 148 file = filp_open(real_path, O_RDWR | O_LARGEFILE, 0644); 149 if (IS_ERR(file)) { 150 hmdfs_info("filp_open failed: %ld", PTR_ERR(file)); 151 } else { 152 hmdfs_info("get file with magic %lu", 153 file->f_inode->i_sb->s_magic); 154 } 155 156 kfree(real_path); 157 return file; 158} 159 160struct file *hmdfs_open_path(struct hmdfs_sb_info *sbi, const char *path) 161{ 162 struct path root_path; 163 struct file *file; 164 int err; 165 const char *root_name = sbi->local_dst; 166 167 err = kern_path(root_name, 0, &root_path); 168 if (err) { 169 hmdfs_info("kern_path failed: %d", err); 170 return ERR_PTR(err); 171 } 172 file = file_open_root(&root_path, path, 173 O_RDWR | O_LARGEFILE, 0644); 174 path_put(&root_path); 175 if (IS_ERR(file)) { 176 hmdfs_err( 177 "GRAPERR sb->s_readonly_remount %d sb_flag %lu", 178 sbi->sb->s_readonly_remount, sbi->sb->s_flags); 179 hmdfs_info("file_open_root failed: %ld", PTR_ERR(file)); 180 } else { 181 hmdfs_info("get file with magic %lu", 182 file->f_inode->i_sb->s_magic); 183 } 184 return file; 185} 186 187inline void hmdfs_close_path(struct file *file) 188{ 189 fput(file); 190} 191 192/* After offline server close all files opened by client */ 193void hmdfs_server_offline_notify(struct hmdfs_peer *conn, int evt, 194 unsigned int seq) 195{ 196 int id; 197 int count = 0; 198 unsigned int next; 199 struct file *filp = NULL; 200 struct idr *idr = &conn->file_id_idr; 201 202 /* wait all async work complete */ 203 flush_workqueue(conn->req_handle_wq); 204 flush_workqueue(conn->async_wq); 205 206 /* If there is some open requests in processing, 207 * Maybe, we need to close file when peer offline 208 */ 209 idr_for_each_entry(idr, filp, id) { 210 hmdfs_debug("[%d]Server close: id=%d", count, id); 211 hmdfs_close_path(filp); 212 count++; 213 if (count % HMDFS_IDR_RESCHED_COUNT == 0) 214 cond_resched(); 215 } 216 217 hmdfs_clear_share_item_offline(conn); 218 219 /* Reinitialize idr */ 220 next = idr_get_cursor(idr); 221 idr_destroy(idr); 222 223 idr_init(idr); 224 idr_set_cursor(idr, next); 225 226 /* Make old file id to be stale */ 227 conn->fid_cookie++; 228} 229 230static struct hmdfs_node_cb_desc server_cb[] = { 231 { 232 .evt = NODE_EVT_OFFLINE, 233 .sync = true, 234 .fn = hmdfs_server_offline_notify 235 }, 236}; 237 238void __init hmdfs_server_add_node_evt_cb(void) 239{ 240 hmdfs_node_add_evt_cb(server_cb, ARRAY_SIZE(server_cb)); 241} 242 243static int hmdfs_get_inode_by_name(struct hmdfs_peer *con, const char *filename, 244 uint64_t *ino) 245{ 246 int ret = 0; 247 struct path root_path; 248 struct path dst_path; 249 struct inode *inode = NULL; 250 251 ret = kern_path(con->sbi->local_dst, 0, &root_path); 252 if (ret) { 253 hmdfs_err("kern_path failed err = %d", ret); 254 return ret; 255 } 256 257 ret = vfs_path_lookup(root_path.dentry, root_path.mnt, filename, 0, 258 &dst_path); 259 if (ret) { 260 path_put(&root_path); 261 return ret; 262 } 263 264 inode = d_inode(dst_path.dentry); 265 if (con->sbi->sb == inode->i_sb) 266 inode = hmdfs_i(inode)->lower_inode; 267 *ino = generate_u64_ino(inode->i_ino, inode->i_generation); 268 269 path_put(&dst_path); 270 path_put(&root_path); 271 272 return 0; 273} 274 275static const char *datasl_str[] = { 276 "s0", "s1", "s2", "s3", "s4" 277}; 278 279static int parse_data_sec_level(const char *sl_value, size_t sl_value_len) 280{ 281 int i; 282 283 for (i = 0; i < sizeof(datasl_str) / sizeof(datasl_str[0]); i++) { 284 if (!strncmp(sl_value, datasl_str[i], strlen(datasl_str[i]))) 285 return i + DATA_SEC_LEVEL0; 286 } 287 288 return DATA_SEC_LEVEL3; 289} 290 291static int check_sec_level(struct hmdfs_peer *node, const char *file_name) 292{ 293 int err; 294 int ret = 0; 295 struct path root_path; 296 struct path file_path; 297 char *value = NULL; 298 size_t value_len = DATA_SEC_LEVEL_LENGTH; 299 300 if (node->devsl <= 0) { 301 ret = -EACCES; 302 goto out_free; 303 } 304 305 value = kzalloc(value_len, GFP_KERNEL); 306 if (!value) { 307 ret = -ENOMEM; 308 goto out_free; 309 } 310 311 err = kern_path(node->sbi->local_dst, LOOKUP_DIRECTORY, &root_path); 312 if (err) { 313 hmdfs_err("get root path error"); 314 ret = err; 315 goto out_free; 316 } 317 318 err = vfs_path_lookup(root_path.dentry, root_path.mnt, file_name, 0, 319 &file_path); 320 if (err) { 321 hmdfs_err("get file path error"); 322 ret = err; 323 goto out_err; 324 } 325 326 err = vfs_getxattr(file_path.dentry, DATA_SEC_LEVEL_LABEL, value, 327 value_len); 328 if (err <= 0 && node->devsl >= DATA_SEC_LEVEL3) 329 goto out; 330 if (err > 0 && node->devsl >= parse_data_sec_level(value, err)) 331 goto out; 332 333 ret = -EACCES; 334out: 335 path_put(&file_path); 336out_err: 337 path_put(&root_path); 338out_free: 339 kfree(value); 340 return ret; 341} 342 343static struct file *hmdfs_open_file(struct hmdfs_peer *con, 344 const char *filename, uint8_t file_type, 345 int *file_id) 346{ 347 struct file *file = NULL; 348 int err = 0; 349 int id; 350 351 if (!filename) { 352 hmdfs_err("filename is NULL"); 353 return ERR_PTR(-EINVAL); 354 } 355 356 if (check_sec_level(con, filename)) { 357 hmdfs_err("devsl permission denied"); 358 return ERR_PTR(-EACCES); 359 } 360 361 if (hm_isshare(file_type)) { 362 err = hmdfs_check_share_access_permission(con->sbi, 363 filename, con->cid); 364 if (err) 365 return ERR_PTR(err); 366 } 367 368 if (hm_islnk(file_type)) 369 file = hmdfs_open_link(con->sbi, filename); 370 else 371 file = hmdfs_open_path(con->sbi, filename); 372 373 if (IS_ERR(file)) { 374 reset_item_opened_status(con->sbi, filename); 375 return file; 376 } 377 378 get_file(file); 379 id = insert_file_into_conn(con, file); 380 if (id < 0) { 381 hmdfs_err("file_id alloc failed! err=%d", id); 382 reset_item_opened_status(con->sbi, filename); 383 hmdfs_close_path(file); 384 hmdfs_close_path(file); 385 return ERR_PTR(id); 386 } 387 *file_id = id; 388 389 return file; 390} 391 392static struct hmdfs_time_t msec_to_timespec(unsigned int msec) 393{ 394 struct hmdfs_time_t timespec = { 395 .tv_sec = msec / MSEC_PER_SEC, 396 .tv_nsec = (msec % MSEC_PER_SEC) * NSEC_PER_MSEC, 397 }; 398 399 return timespec; 400} 401 402static struct hmdfs_time_t hmdfs_current_kernel_time(void) 403{ 404 struct hmdfs_time_t time; 405 406#if KERNEL_VERSION(4, 18, 0) < LINUX_VERSION_CODE 407 ktime_get_coarse_real_ts64(&time); 408#else 409 time = current_kernel_time(); 410#endif 411 return time; 412} 413 414/* 415 * Generate fid version like following format: 416 * 417 * | boot cookie | con cookie | 418 * |---------------------|-------------| 419 * 49 15 (bits) 420 */ 421static uint64_t hmdfs_server_pack_fid_ver(struct hmdfs_peer *con, 422 struct hmdfs_head_cmd *cmd) 423{ 424 uint64_t boot_cookie = con->sbi->boot_cookie; 425 uint16_t con_cookie = con->fid_cookie; 426 427 return (boot_cookie | 428 (con_cookie & ((1 << HMDFS_FID_VER_BOOT_COOKIE_SHIFT) - 1))); 429} 430 431static struct file *get_file_by_fid_and_ver(struct hmdfs_peer *con, 432 struct hmdfs_head_cmd *cmd, 433 __u32 file_id, __u64 file_ver) 434{ 435 struct file *file = NULL; 436 __u64 cur_file_ver = hmdfs_server_pack_fid_ver(con, cmd); 437 438 if (file_ver != cur_file_ver) { 439 hmdfs_warning("Stale file version %llu for fid %u", 440 file_ver, file_id); 441 return ERR_PTR(-EBADF); 442 } 443 444 file = get_file_from_conn(con, file_id); 445 if (!file) 446 return ERR_PTR(-EBADF); 447 448 return file; 449} 450 451static void hmdfs_update_open_response(struct hmdfs_peer *con, 452 struct hmdfs_head_cmd *cmd, 453 struct hmdfs_open_info *info, 454 struct open_response *resp) 455{ 456 struct hmdfs_time_t current_time = hmdfs_current_kernel_time(); 457 struct hmdfs_time_t ctime = info->stat_valid ? info->stat.ctime : 458 info->inode->i_ctime; 459 struct hmdfs_time_t precision = 460 msec_to_timespec(con->sbi->dcache_precision); 461 loff_t size = info->stat_valid ? info->stat.size : 462 i_size_read(info->inode); 463 464 resp->ino = cpu_to_le64(info->real_ino); 465 resp->file_ver = cpu_to_le64(hmdfs_server_pack_fid_ver(con, cmd)); 466 resp->file_id = cpu_to_le32(info->file_id); 467 resp->file_size = cpu_to_le64(size); 468 resp->ctime = cpu_to_le64(ctime.tv_sec); 469 resp->ctime_nsec = cpu_to_le32(ctime.tv_nsec); 470 471 /* 472 * In server, ctime might stay the same after coverwrite. We introduce a 473 * new value stable_ctime to handle the problem. 474 * - if open rpc time < ctime, stable_ctime = 0; 475 * - if ctime <= open rpc time < ctime + dcache_precision, stable_ctime 476 * = ctime 477 * - else, stable_ctime = ctime + dcache_precision; 478 */ 479 precision = hmdfs_time_add(ctime, precision); 480 if (hmdfs_time_compare(¤t_time, &ctime) < 0) { 481 resp->stable_ctime = cpu_to_le64(0); 482 resp->stable_ctime_nsec = cpu_to_le32(0); 483 } else if (hmdfs_time_compare(¤t_time, &ctime) >= 0 && 484 hmdfs_time_compare(¤t_time, &precision) < 0) { 485 resp->stable_ctime = resp->ctime; 486 resp->stable_ctime_nsec = resp->ctime_nsec; 487 } else { 488 resp->stable_ctime = cpu_to_le64(precision.tv_sec); 489 resp->stable_ctime_nsec = cpu_to_le32(precision.tv_nsec); 490 } 491} 492 493static int hmdfs_get_open_info(struct hmdfs_peer *con, uint8_t file_type, 494 const char *filename, 495 struct hmdfs_open_info *info) 496{ 497 int ret = 0; 498 499 info->inode = file_inode(info->file); 500 info->stat_valid = false; 501 if (con->sbi->sb == info->inode->i_sb) { 502 /* if open a regular file */ 503 info->inode = hmdfs_i(info->inode)->lower_inode; 504 } else if (con->sbi->lower_sb != info->inode->i_sb) { 505 /* It's possible that inode is not from lower, for example: 506 * 1. touch /f2fs/file 507 * 2. ln -s /sdcard_fs/file /f2fs/link 508 * 3. cat /hmdfs/link -> generate dentry cache in sdcard_fs 509 * 4. echo hi >> /hmdfs/file -> append write not through 510 * sdcard_fs 511 * 5. cat /hmdfs/link -> got inode in sdcard, which size is 512 * still 0 513 * 514 * If src file isn't in lower, use getattr to get 515 * information. 516 */ 517 ret = vfs_getattr(&info->file->f_path, &info->stat, STATX_BASIC_STATS | STATX_BTIME, 518 0); 519 if (ret) { 520 hmdfs_err("call vfs_getattr failed, err %d", ret); 521 return ret; 522 } 523 info->stat_valid = true; 524 } 525 526 if (hm_islnk(file_type)) { 527 ret = hmdfs_get_inode_by_name(con, filename, &info->real_ino); 528 if (ret) 529 return ret; 530 } else { 531 info->real_ino = generate_u64_ino(info->inode->i_ino, 532 info->inode->i_generation); 533 } 534 return 0; 535} 536 537void hmdfs_server_open(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, 538 void *data) 539{ 540 struct open_request *recv = data; 541 int sizeread = sizeof(struct open_response); 542 struct open_response *resp = NULL; 543 struct hmdfs_open_info *info = NULL; 544 int ret = 0; 545 546 trace_hmdfs_server_open_enter(con, recv); 547 548 resp = kzalloc(sizeread, GFP_KERNEL); 549 info = kmalloc(sizeof(*info), GFP_KERNEL); 550 if (!resp || !info) { 551 ret = -ENOMEM; 552 goto err_free; 553 } 554 555 if (path_contain_dotdot(recv->buf, recv->path_len)) { 556 ret = -EINVAL; 557 goto err_free; 558 } 559 560 info->file = hmdfs_open_file(con, recv->buf, recv->file_type, 561 &info->file_id); 562 if (IS_ERR(info->file)) { 563 ret = PTR_ERR(info->file); 564 goto err_free; 565 } 566 567 ret = hmdfs_get_open_info(con, recv->file_type, recv->buf, info); 568 if (ret) 569 goto err_close; 570 571 hmdfs_update_open_response(con, cmd, info, resp); 572 573 trace_hmdfs_server_open_exit(con, resp, info->file, 0); 574 ret = hmdfs_sendmessage_response(con, cmd, sizeread, resp, 0); 575 if (ret) { 576 hmdfs_err("sending msg response failed, file_id %d, err %d", 577 info->file_id, ret); 578 remove_file_from_conn(con, info->file_id); 579 hmdfs_close_path(info->file); 580 } 581 hmdfs_close_path(info->file); 582 kfree(resp); 583 kfree(info); 584 return; 585 586err_close: 587 hmdfs_close_path(info->file); 588 remove_file_from_conn(con, info->file_id); 589 hmdfs_close_path(info->file); 590err_free: 591 kfree(resp); 592 kfree(info); 593 trace_hmdfs_server_open_exit(con, NULL, NULL, ret); 594 hmdfs_send_err_response(con, cmd, ret); 595} 596 597static int hmdfs_check_and_create(struct path *path_parent, 598 struct dentry *dentry, uint64_t device_id, 599 umode_t mode, bool is_excl) 600{ 601 int err = 0; 602 603 /* if inode doesn't exist, create it */ 604 if (d_is_negative(dentry)) { 605 hmdfs_mark_drop_flag(device_id, path_parent->dentry); 606 err = vfs_create(d_inode(path_parent->dentry), dentry, mode, 607 is_excl); 608 if (err) 609 hmdfs_err("create failed, err %d", err); 610 } else { 611 if (is_excl) 612 err = -EEXIST; 613 else if (S_ISREG(d_inode(dentry)->i_mode) && 614 hm_islnk(hmdfs_d(dentry)->file_type)) 615 err = -EINVAL; 616 else if (S_ISDIR(d_inode(dentry)->i_mode)) 617 err = -EISDIR; 618 } 619 620 return err; 621} 622static int hmdfs_lookup_create(struct hmdfs_peer *con, 623 struct atomic_open_request *recv, 624 struct path *child_path, bool *truncate) 625{ 626 int err = 0; 627 struct path path_root; 628 struct path path_parent; 629 uint32_t open_flags = le32_to_cpu(recv->open_flags); 630 char *path = recv->buf; 631 char *filename = recv->buf + le32_to_cpu(recv->path_len) + 1; 632 struct dentry *dentry = NULL; 633 634 err = kern_path(con->sbi->local_dst, LOOKUP_DIRECTORY, &path_root); 635 if (err) { 636 hmdfs_err("no path for %s, err %d", con->sbi->local_dst, err); 637 return err; 638 } 639 640 err = vfs_path_lookup(path_root.dentry, path_root.mnt, path, 641 LOOKUP_DIRECTORY, &path_parent); 642 if (err) { 643 hmdfs_info("no dir in %s, err %d", con->sbi->local_dst, err); 644 goto put_path_root; 645 } 646 647 inode_lock(d_inode(path_parent.dentry)); 648 dentry = lookup_one_len(filename, path_parent.dentry, strlen(filename)); 649 if (IS_ERR(dentry)) { 650 err = PTR_ERR(dentry); 651 inode_unlock(d_inode(path_parent.dentry)); 652 goto put_path_parent; 653 } 654 /* only truncate if inode already exists */ 655 *truncate = ((open_flags & HMDFS_O_TRUNC) && d_is_positive(dentry)); 656 err = hmdfs_check_and_create(&path_parent, dentry, con->device_id, 657 le16_to_cpu(recv->mode), 658 open_flags & HMDFS_O_EXCL); 659 inode_unlock(d_inode(path_parent.dentry)); 660 if (err) { 661 dput(dentry); 662 } else { 663 child_path->dentry = dentry; 664 child_path->mnt = mntget(path_parent.mnt); 665 } 666 667put_path_parent: 668 path_put(&path_parent); 669put_path_root: 670 path_put(&path_root); 671 return err; 672} 673 674static int hmdfs_dentry_open(struct hmdfs_peer *con, 675 const struct path *path, 676 struct hmdfs_open_info *info) 677{ 678 int err = 0; 679 680 info->file = dentry_open(path, O_RDWR | O_LARGEFILE, current_cred()); 681 if (IS_ERR(info->file)) { 682 err = PTR_ERR(info->file); 683 hmdfs_err("open file failed, err %d", err); 684 return err; 685 } 686 687 get_file(info->file); 688 info->file_id = insert_file_into_conn(con, info->file); 689 if (info->file_id < 0) { 690 err = info->file_id; 691 hmdfs_err("file_id alloc failed! err %d", err); 692 hmdfs_close_path(info->file); 693 hmdfs_close_path(info->file); 694 return err; 695 } 696 697 return 0; 698} 699 700static int hmdfs_server_do_atomic_open(struct hmdfs_peer *con, 701 struct hmdfs_head_cmd *cmd, 702 struct atomic_open_request *recv, 703 struct hmdfs_open_info *info, 704 struct atomic_open_response *resp) 705{ 706 struct path child_path; 707 bool truncate = false; 708 int err = 0; 709 710 err = hmdfs_lookup_create(con, recv, &child_path, &truncate); 711 if (err) 712 return err; 713 714 err = hmdfs_dentry_open(con, &child_path, info); 715 if (err) 716 goto put_child; 717 718 err = hmdfs_get_open_info(con, HM_REG, NULL, info); 719 if (err) 720 goto fail_close; 721 722 if (truncate) { 723 err = vfs_truncate(&child_path, 0); 724 if (err) { 725 hmdfs_err("truncate failed, err %d", err); 726 goto fail_close; 727 } 728 } 729 hmdfs_update_open_response(con, cmd, info, &resp->open_resp); 730 resp->i_mode = cpu_to_le16(file_inode(info->file)->i_mode); 731 732fail_close: 733 if (err) { 734 remove_file_from_conn(con, info->file_id); 735 hmdfs_close_path(info->file); 736 hmdfs_close_path(info->file); 737 } 738put_child: 739 path_put(&child_path); 740 return err; 741} 742 743void hmdfs_server_atomic_open(struct hmdfs_peer *con, 744 struct hmdfs_head_cmd *cmd, void *data) 745{ 746 int err; 747 struct atomic_open_request *recv = data; 748 struct atomic_open_response *resp = NULL; 749 struct hmdfs_open_info *info = NULL; 750 char *file_path = recv->buf; 751 char *file = recv->buf + recv->path_len + 1; 752 753 if (path_contain_dotdot(file_path, recv->path_len)) { 754 err = -EINVAL; 755 goto out; 756 } 757 if (path_contain_dotdot(file, recv->file_len)) { 758 err = -EINVAL; 759 goto out; 760 } 761 762 info = kmalloc(sizeof(*info), GFP_KERNEL); 763 resp = kzalloc(sizeof(*resp), GFP_KERNEL); 764 if (!resp || !info) { 765 err = -ENOMEM; 766 goto out; 767 } 768 769 err = hmdfs_server_do_atomic_open(con, cmd, recv, info, resp); 770 771out: 772 if (err) { 773 hmdfs_send_err_response(con, cmd, err); 774 } else { 775 err = hmdfs_sendmessage_response(con, cmd, sizeof(*resp), resp, 776 0); 777 if (err) { 778 hmdfs_err("sending msg response failed, file_id %d, err %d", 779 info->file_id, err); 780 remove_file_from_conn(con, info->file_id); 781 hmdfs_close_path(info->file); 782 } 783 } 784 kfree(info); 785 kfree(resp); 786} 787 788void hmdfs_server_release(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, 789 void *data) 790{ 791 struct release_request *release_recv = data; 792 struct file *file = NULL; 793 __u32 file_id; 794 __u64 file_ver; 795 int ret = 0; 796 797 file_id = le32_to_cpu(release_recv->file_id); 798 file_ver = le64_to_cpu(release_recv->file_ver); 799 file = get_file_by_fid_and_ver(con, cmd, file_id, file_ver); 800 if (IS_ERR(file)) { 801 hmdfs_err("cannot find %u", file_id); 802 ret = PTR_ERR(file); 803 goto out; 804 } 805 806 if (hmdfs_is_share_file(file)) 807 hmdfs_close_share_item(con->sbi, file, con->cid); 808 809 /* put the reference acquired by get_file_by_fid_and_ver() */ 810 hmdfs_close_path(file); 811 hmdfs_info("close %u", file_id); 812 ret = remove_file_from_conn(con, file_id); 813 if (ret) { 814 hmdfs_err("cannot find after close %u", file_id); 815 goto out; 816 } 817 818 hmdfs_close_path(file); 819 820out: 821 trace_hmdfs_server_release(con, file_id, file_ver, ret); 822 set_conn_sock_quickack(con); 823} 824 825void hmdfs_server_fsync(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, 826 void *data) 827{ 828 struct fsync_request *fsync_recv = data; 829 __s32 datasync = le32_to_cpu(fsync_recv->datasync); 830 __s64 start = le64_to_cpu(fsync_recv->start); 831 __s64 end = le64_to_cpu(fsync_recv->end); 832 struct file *file = NULL; 833 __u32 file_id; 834 __u64 file_ver; 835 int ret = 0; 836 837 file_id = le32_to_cpu(fsync_recv->file_id); 838 file_ver = le64_to_cpu(fsync_recv->file_ver); 839 file = get_file_by_fid_and_ver(con, cmd, file_id, file_ver); 840 if (IS_ERR(file)) { 841 hmdfs_err("cannot find %u", file_id); 842 ret = PTR_ERR(file); 843 goto out; 844 } 845 846 ret = vfs_fsync_range(file, start, end, datasync); 847 if (ret) 848 hmdfs_err("fsync fail, ret %d", ret); 849 850 hmdfs_close_path(file); 851out: 852 hmdfs_send_err_response(con, cmd, ret); 853} 854 855void hmdfs_server_readpage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, 856 void *data) 857{ 858 struct readpage_request *readpage_recv = data; 859 __u64 file_ver; 860 __u32 file_id; 861 struct file *file = NULL; 862 loff_t pos; 863 struct readpage_response *readpage = NULL; 864 int ret = 0; 865 size_t read_len; 866 867 file_id = le32_to_cpu(readpage_recv->file_id); 868 file_ver = le64_to_cpu(readpage_recv->file_ver); 869 file = get_file_by_fid_and_ver(con, cmd, file_id, file_ver); 870 if (IS_ERR(file)) { 871 hmdfs_info( 872 "file with id %u does not exist, pgindex %llu, devid %llu", 873 file_id, le64_to_cpu(readpage_recv->index), 874 con->device_id); 875 ret = PTR_ERR(file); 876 goto fail; 877 } 878 879 read_len = (size_t)le32_to_cpu(readpage_recv->size); 880 if (read_len == 0) 881 goto fail_put_file; 882 883 readpage = kmalloc(read_len, GFP_KERNEL); 884 if (!readpage) { 885 ret = -ENOMEM; 886 goto fail_put_file; 887 } 888 889 pos = (loff_t)le64_to_cpu(readpage_recv->index) << HMDFS_PAGE_OFFSET; 890 ret = kernel_read(file, readpage->buf, read_len, &pos); 891 if (ret < 0) { 892 hmdfs_send_err_response(con, cmd, -EIO); 893 } else { 894 if (ret != read_len) 895 memset(readpage->buf + ret, 0, read_len - ret); 896 hmdfs_sendmessage_response(con, cmd, read_len, readpage, 0); 897 } 898 899 hmdfs_close_path(file); 900 kfree(readpage); 901 return; 902 903fail_put_file: 904 hmdfs_close_path(file); 905fail: 906 hmdfs_send_err_response(con, cmd, ret); 907} 908 909static bool need_rebuild_dcache(struct hmdfs_dcache_header *h, 910 struct hmdfs_time_t time, 911 unsigned int precision) 912{ 913 struct hmdfs_time_t crtime = { .tv_sec = le64_to_cpu(h->dcache_crtime), 914 .tv_nsec = le64_to_cpu( 915 h->dcache_crtime_nsec) }; 916 struct hmdfs_time_t ctime = { .tv_sec = le64_to_cpu(h->dentry_ctime), 917 .tv_nsec = le64_to_cpu( 918 h->dentry_ctime_nsec) }; 919 struct hmdfs_time_t pre_time = { .tv_sec = precision / MSEC_PER_SEC, 920 .tv_nsec = precision % MSEC_PER_SEC * 921 NSEC_PER_MSEC }; 922 923 if (hmdfs_time_compare(&time, &ctime) != 0) 924 return true; 925 926 pre_time = hmdfs_time_add(time, pre_time); 927 if (hmdfs_time_compare(&crtime, &pre_time) < 0) 928 return true; 929 930 return false; 931} 932 933static bool hmdfs_server_cache_validate(struct file *filp, struct inode *inode, 934 unsigned long precision) 935{ 936 struct hmdfs_dcache_header header; 937 int overallpage; 938 ssize_t bytes; 939 loff_t pos = 0; 940 941 overallpage = get_dentry_group_cnt(file_inode(filp)); 942 if (overallpage == 0) { 943 hmdfs_err("cache file size is 0"); 944 return false; 945 } 946 947 bytes = kernel_read(filp, &header, sizeof(header), &pos); 948 if (bytes != sizeof(header)) { 949 hmdfs_err("read file failed, err:%zd", bytes); 950 return false; 951 } 952 953 return !need_rebuild_dcache(&header, inode->i_ctime, precision); 954} 955 956struct file *hmdfs_server_cache_revalidate(struct hmdfs_sb_info *sbi, 957 const char *recvpath, 958 struct path *path) 959{ 960 struct cache_file_node *cfn = NULL; 961 struct file *file; 962 963 cfn = find_cfn(sbi, HMDFS_SERVER_CID, recvpath, true); 964 if (!cfn) 965 return NULL; 966 967 if (!hmdfs_server_cache_validate(cfn->filp, path->dentry->d_inode, 968 sbi->dcache_precision)) { 969 remove_cfn(cfn); 970 release_cfn(cfn); 971 return NULL; 972 } 973 file = cfn->filp; 974 get_file(cfn->filp); 975 release_cfn(cfn); 976 977 return file; 978} 979 980bool hmdfs_client_cache_validate(struct hmdfs_sb_info *sbi, 981 struct readdir_request *readdir_recv, 982 struct path *path) 983{ 984 struct inode *inode = path->dentry->d_inode; 985 struct hmdfs_dcache_header header; 986 987 /* always rebuild dentryfile for small dir */ 988 if (le64_to_cpu(readdir_recv->num) < sbi->dcache_threshold) 989 return false; 990 991 header.dcache_crtime = readdir_recv->dcache_crtime; 992 header.dcache_crtime_nsec = readdir_recv->dcache_crtime_nsec; 993 header.dentry_ctime = readdir_recv->dentry_ctime; 994 header.dentry_ctime_nsec = readdir_recv->dentry_ctime_nsec; 995 996 return !need_rebuild_dcache(&header, inode->i_ctime, 997 sbi->dcache_precision); 998} 999 1000static char *server_lower_dentry_path_raw(struct hmdfs_peer *peer, 1001 struct dentry *lo_d) 1002{ 1003 struct hmdfs_dentry_info *di = hmdfs_d(peer->sbi->sb->s_root); 1004 struct dentry *lo_d_root = di->lower_path.dentry; 1005 struct dentry *lo_d_tmp = NULL; 1006 char *lo_p_buf = NULL; 1007 char *buf_head = NULL; 1008 char *buf_tail = NULL; 1009 size_t path_len = 0; 1010 1011 lo_p_buf = kzalloc(PATH_MAX, GFP_KERNEL); 1012 if (unlikely(!lo_p_buf)) 1013 return ERR_PTR(-ENOMEM); 1014 1015 /* To generate a reversed path str */ 1016 for (lo_d_tmp = lo_d; lo_d_tmp != lo_d_root && !IS_ROOT(lo_d_tmp); 1017 lo_d_tmp = lo_d_tmp->d_parent) { 1018 u32 dlen = lo_d_tmp->d_name.len; 1019 int reverse_index = dlen - 1; 1020 1021 /* Considering the appended slash and '\0' */ 1022 if (unlikely(path_len + dlen + 1 > PATH_MAX - 1)) { 1023 kfree(lo_p_buf); 1024 return ERR_PTR(-ENAMETOOLONG); 1025 } 1026 for (; reverse_index >= 0; --reverse_index) 1027 lo_p_buf[path_len++] = 1028 lo_d_tmp->d_name.name[reverse_index]; 1029 lo_p_buf[path_len++] = '/'; 1030 } 1031 1032 /* Reverse the reversed path str to get the real path str */ 1033 for (buf_head = lo_p_buf, buf_tail = lo_p_buf + path_len - 1; 1034 buf_head < buf_tail; ++buf_head, --buf_tail) 1035 swap(*buf_head, *buf_tail); 1036 1037 if (path_len == 0) 1038 lo_p_buf[0] = '/'; 1039 return lo_p_buf; 1040} 1041 1042static int server_lookup(struct hmdfs_peer *peer, const char *req_path, 1043 struct path *path) 1044{ 1045 struct path root_path; 1046 int err = 0; 1047 1048 err = kern_path(peer->sbi->local_dst, 0, &root_path); 1049 if (err) 1050 goto out_noroot; 1051 1052 err = vfs_path_lookup(root_path.dentry, root_path.mnt, req_path, 1053 LOOKUP_DIRECTORY, path); 1054 path_put(&root_path); 1055out_noroot: 1056 return err; 1057} 1058 1059/** 1060 * server_lookup_lower - lookup lower file-system 1061 * @peer: target device node 1062 * @req_path: abs path (mount point as the root) from the request 1063 * @lo_o: the lower path to return 1064 * 1065 * return the lower path's name, with characters' cases matched 1066 */ 1067static char *server_lookup_lower(struct hmdfs_peer *peer, const char *req_path, 1068 struct path *lo_p) 1069{ 1070 char *lo_p_name = ERR_PTR(-ENOENT); 1071 struct path up_p; 1072 int err = 0; 1073 1074 err = server_lookup(peer, req_path, &up_p); 1075 if (err) 1076 goto out; 1077 1078 hmdfs_get_lower_path(up_p.dentry, lo_p); 1079 path_put(&up_p); 1080 1081 lo_p_name = server_lower_dentry_path_raw(peer, lo_p->dentry); 1082 if (IS_ERR(lo_p_name)) { 1083 err = PTR_ERR(lo_p_name); 1084 path_put(lo_p); 1085 } 1086out: 1087 return err ? ERR_PTR(err) : lo_p_name; 1088} 1089 1090void hmdfs_server_readdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, 1091 void *data) 1092{ 1093 struct readdir_request *readdir_recv = data; 1094 struct path lo_p; 1095 struct file *filp = NULL; 1096 int err = 0; 1097 unsigned long long num = 0; 1098 char *lo_p_name = NULL; 1099 1100 trace_hmdfs_server_readdir(readdir_recv); 1101 1102 if (path_contain_dotdot(readdir_recv->path, readdir_recv->path_len)) { 1103 err = -EINVAL; 1104 goto send_err; 1105 } 1106 1107 lo_p_name = server_lookup_lower(con, readdir_recv->path, &lo_p); 1108 if (IS_ERR(lo_p_name)) { 1109 err = PTR_ERR(lo_p_name); 1110 hmdfs_info("Failed to get lower path: %d", err); 1111 goto send_err; 1112 } 1113 1114 if (le32_to_cpu(readdir_recv->verify_cache)) { 1115 if (hmdfs_client_cache_validate(con->sbi, readdir_recv, &lo_p)) 1116 goto out_response; 1117 } 1118 1119 filp = hmdfs_server_cache_revalidate(con->sbi, lo_p_name, &lo_p); 1120 if (IS_ERR_OR_NULL(filp)) { 1121 filp = hmdfs_server_rebuild_dents(con->sbi, &lo_p, &num, 1122 lo_p_name); 1123 if (IS_ERR_OR_NULL(filp)) { 1124 err = PTR_ERR(filp); 1125 goto err_lookup_path; 1126 } 1127 } 1128 1129out_response: 1130 err = hmdfs_readfile_response(con, cmd, filp); 1131 if (!err) 1132 hmdfs_add_remote_cache_list(con, lo_p_name); 1133 if (num >= con->sbi->dcache_threshold) 1134 cache_file_persistent(con, filp, lo_p_name, true); 1135 if (filp) 1136 fput(filp); 1137err_lookup_path: 1138 path_put(&lo_p); 1139 kfree(lo_p_name); 1140send_err: 1141 if (err) 1142 hmdfs_send_err_response(con, cmd, err); 1143} 1144 1145void hmdfs_server_mkdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, 1146 void *data) 1147{ 1148 int err = 0; 1149 struct mkdir_request *mkdir_recv = data; 1150 struct inode *child_inode = NULL; 1151 struct dentry *dent = NULL; 1152 char *mkdir_dir = NULL; 1153 char *mkdir_name = NULL; 1154 struct hmdfs_inodeinfo_response *mkdir_resp = NULL; 1155 int respsize = sizeof(struct hmdfs_inodeinfo_response); 1156 int path_len = le32_to_cpu(mkdir_recv->path_len); 1157 1158 mkdir_resp = kzalloc(respsize, GFP_KERNEL); 1159 if (!mkdir_resp) { 1160 err = -ENOMEM; 1161 goto mkdir_out; 1162 } 1163 1164 mkdir_dir = mkdir_recv->path; 1165 mkdir_name = mkdir_recv->path + path_len + 1; 1166 if (path_contain_dotdot(mkdir_dir, mkdir_recv->path_len)) { 1167 err = -EINVAL; 1168 goto mkdir_out; 1169 } 1170 if (path_contain_dotdot(mkdir_name, mkdir_recv->name_len)) { 1171 err = -EINVAL; 1172 goto mkdir_out; 1173 } 1174 1175 dent = hmdfs_root_mkdir(con->device_id, con->sbi->local_dst, 1176 mkdir_dir, mkdir_name, 1177 le16_to_cpu(mkdir_recv->mode)); 1178 if (IS_ERR(dent)) { 1179 err = PTR_ERR(dent); 1180 hmdfs_err("hmdfs_root_mkdir failed err = %d", err); 1181 goto mkdir_out; 1182 } 1183 child_inode = d_inode(dent); 1184 mkdir_resp->i_mode = cpu_to_le16(child_inode->i_mode); 1185 mkdir_resp->i_size = cpu_to_le64(child_inode->i_size); 1186 mkdir_resp->i_mtime = cpu_to_le64(child_inode->i_mtime.tv_sec); 1187 mkdir_resp->i_mtime_nsec = cpu_to_le32(child_inode->i_mtime.tv_nsec); 1188 mkdir_resp->i_ino = cpu_to_le64(child_inode->i_ino); 1189 dput(dent); 1190mkdir_out: 1191 hmdfs_sendmessage_response(con, cmd, respsize, mkdir_resp, err); 1192 kfree(mkdir_resp); 1193} 1194 1195void hmdfs_server_create(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, 1196 void *data) 1197{ 1198 int err = 0; 1199 struct create_request *create_recv = data; 1200 struct inode *child_inode = NULL; 1201 struct dentry *dent = NULL; 1202 char *create_dir = NULL; 1203 char *create_name = NULL; 1204 struct hmdfs_inodeinfo_response *create_resp = NULL; 1205 int respsize = sizeof(struct hmdfs_inodeinfo_response); 1206 int path_len = le32_to_cpu(create_recv->path_len); 1207 1208 create_resp = kzalloc(respsize, GFP_KERNEL); 1209 if (!create_resp) { 1210 err = -ENOMEM; 1211 goto create_out; 1212 } 1213 1214 create_dir = create_recv->path; 1215 create_name = create_recv->path + path_len + 1; 1216 if (path_contain_dotdot(create_dir, create_recv->path_len)) { 1217 err = -EINVAL; 1218 goto create_out; 1219 } 1220 if (path_contain_dotdot(create_name, create_recv->name_len)) { 1221 err = -EINVAL; 1222 goto create_out; 1223 } 1224 1225 dent = hmdfs_root_create(con->device_id, con->sbi->local_dst, 1226 create_dir, create_name, 1227 le16_to_cpu(create_recv->mode), 1228 create_recv->want_excl); 1229 if (IS_ERR(dent)) { 1230 err = PTR_ERR(dent); 1231 hmdfs_err("hmdfs_root_create failed err = %d", err); 1232 goto create_out; 1233 } 1234 child_inode = d_inode(dent); 1235 create_resp->i_mode = cpu_to_le16(child_inode->i_mode); 1236 create_resp->i_size = cpu_to_le64(child_inode->i_size); 1237 create_resp->i_mtime = cpu_to_le64(child_inode->i_mtime.tv_sec); 1238 create_resp->i_mtime_nsec = cpu_to_le32(child_inode->i_mtime.tv_nsec); 1239 /* 1240 * keep same as hmdfs_server_open, 1241 * to prevent hmdfs_open_final_remote from judging ino errors. 1242 */ 1243 create_resp->i_ino = cpu_to_le64( 1244 generate_u64_ino(hmdfs_i(child_inode)->lower_inode->i_ino, 1245 child_inode->i_generation)); 1246 dput(dent); 1247create_out: 1248 hmdfs_sendmessage_response(con, cmd, respsize, create_resp, err); 1249 kfree(create_resp); 1250} 1251 1252void hmdfs_server_rmdir(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, 1253 void *data) 1254{ 1255 int err = 0; 1256 struct path root_path; 1257 char *path = NULL; 1258 char *name = NULL; 1259 struct rmdir_request *rmdir_recv = data; 1260 1261 path = rmdir_recv->path; 1262 name = rmdir_recv->path + le32_to_cpu(rmdir_recv->path_len) + 1; 1263 if (path_contain_dotdot(path, rmdir_recv->path_len)) { 1264 err = -EINVAL; 1265 goto rmdir_out; 1266 } 1267 if (path_contain_dotdot(name, rmdir_recv->name_len)) { 1268 err = -EINVAL; 1269 goto rmdir_out; 1270 } 1271 1272 err = kern_path(con->sbi->local_dst, 0, &root_path); 1273 if (!err) { 1274 err = hmdfs_root_rmdir(con->device_id, &root_path, path, name); 1275 path_put(&root_path); 1276 } 1277 1278rmdir_out: 1279 hmdfs_send_err_response(con, cmd, err); 1280} 1281 1282void hmdfs_server_unlink(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, 1283 void *data) 1284{ 1285 int err = 0; 1286 struct path root_path; 1287 char *path = NULL; 1288 char *name = NULL; 1289 struct unlink_request *unlink_recv = data; 1290 1291 path = unlink_recv->path; 1292 name = unlink_recv->path + le32_to_cpu(unlink_recv->path_len) + 1; 1293 if (path_contain_dotdot(path, unlink_recv->path_len)) { 1294 err = -EINVAL; 1295 goto unlink_out; 1296 } 1297 if (path_contain_dotdot(name, unlink_recv->name_len)) { 1298 err = -EINVAL; 1299 goto unlink_out; 1300 } 1301 1302 err = kern_path(con->sbi->local_dst, 0, &root_path); 1303 if (!err) { 1304 err = hmdfs_root_unlink(con->device_id, &root_path, path, name); 1305 path_put(&root_path); 1306 } 1307 1308unlink_out: 1309 hmdfs_send_err_response(con, cmd, err); 1310} 1311 1312void hmdfs_server_rename(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, 1313 void *data) 1314{ 1315 int err = 0; 1316 int old_path_len; 1317 int new_path_len; 1318 int old_name_len; 1319 int new_name_len; 1320 unsigned int flags; 1321 char *path_old = NULL; 1322 char *name_old = NULL; 1323 char *path_new = NULL; 1324 char *name_new = NULL; 1325 struct rename_request *recv = data; 1326 1327 old_path_len = le32_to_cpu(recv->old_path_len); 1328 new_path_len = le32_to_cpu(recv->new_path_len); 1329 old_name_len = le32_to_cpu(recv->old_name_len); 1330 new_name_len = le32_to_cpu(recv->new_name_len); 1331 flags = le32_to_cpu(recv->flags); 1332 1333 path_old = recv->path; 1334 path_new = recv->path + old_path_len + 1; 1335 name_old = recv->path + old_path_len + 1 + new_path_len + 1; 1336 name_new = recv->path + old_path_len + 1 + new_path_len + 1 + 1337 old_name_len + 1; 1338 if (path_contain_dotdot(path_old, old_path_len)) { 1339 err = -EINVAL; 1340 goto rename_out; 1341 } 1342 if (path_contain_dotdot(path_new, new_path_len)) { 1343 err = -EINVAL; 1344 goto rename_out; 1345 } 1346 if (path_contain_dotdot(name_old, old_name_len)) { 1347 err = -EINVAL; 1348 goto rename_out; 1349 } 1350 if (path_contain_dotdot(name_new, new_name_len)) { 1351 err = -EINVAL; 1352 goto rename_out; 1353 } 1354 1355 err = hmdfs_root_rename(con->sbi, con->device_id, path_old, name_old, 1356 path_new, name_new, flags); 1357 1358rename_out: 1359 hmdfs_send_err_response(con, cmd, err); 1360} 1361 1362static int hmdfs_lookup_symlink(struct path *link_path, const char *path_fmt, 1363 ... ) 1364{ 1365 int ret; 1366 va_list args; 1367 char *path = kmalloc(PATH_MAX, GFP_KERNEL); 1368 1369 if (!path) 1370 return -ENOMEM; 1371 1372 va_start(args, path_fmt); 1373 ret = vsnprintf(path, PATH_MAX, path_fmt, args); 1374 va_end(args); 1375 1376 if(ret >= PATH_MAX) { 1377 ret = -ENAMETOOLONG; 1378 goto out; 1379 } 1380 1381 ret = kern_path(path, LOOKUP_FOLLOW, link_path); 1382 if (ret) { 1383 hmdfs_err("kern_path failed err = %d", ret); 1384 goto out; 1385 } 1386 1387 if (!S_ISREG(d_inode(link_path->dentry)->i_mode)) { 1388 hmdfs_err("path is dir symlink"); 1389 path_put(link_path); 1390 ret = -EOPNOTSUPP; 1391 goto out; 1392 } 1393 1394out: 1395 kfree(path); 1396 return ret; 1397} 1398 1399struct dir_entry_info { 1400 struct list_head list; 1401 char *name; 1402 int name_len; 1403 unsigned int d_type; 1404}; 1405 1406static int hmdfs_filldir_real(struct dir_context *ctx, const char *name, 1407 int name_len, loff_t offset, u64 ino, 1408 unsigned int d_type) 1409{ 1410 int res = 0; 1411 char namestr[NAME_MAX + 1]; 1412 struct getdents_callback_real *gc = NULL; 1413 struct dentry *child = NULL; 1414 1415 if (name_len > NAME_MAX) { 1416 hmdfs_err("name_len:%d NAME_MAX:%u", name_len, NAME_MAX); 1417 goto out; 1418 } 1419 1420 gc = container_of(ctx, struct getdents_callback_real, ctx); 1421 1422 memcpy(namestr, name, name_len); 1423 namestr[name_len] = '\0'; 1424 1425 if (hmdfs_file_type(namestr) != HMDFS_TYPE_COMMON) 1426 goto out; 1427 1428 /* parent lock already hold by iterate_dir */ 1429 child = lookup_one_len(name, gc->parent_path->dentry, name_len); 1430 if (IS_ERR(child)) { 1431 res = PTR_ERR(child); 1432 hmdfs_err("lookup failed because %d", res); 1433 goto out; 1434 } 1435 1436 if (d_really_is_negative(child)) { 1437 dput(child); 1438 hmdfs_err("lookup failed because negative dentry"); 1439 /* just do not fill this entry and continue for next entry */ 1440 goto out; 1441 } 1442 1443 if (d_type == DT_REG || d_type == DT_DIR) { 1444 create_dentry(child, d_inode(child), gc->file, gc->sbi); 1445 gc->num++; 1446 } else if (d_type == DT_LNK) { 1447 struct path link_path; 1448 1449 res = hmdfs_lookup_symlink(&link_path, "%s/%s/%s", 1450 gc->sbi->local_src, gc->dir, 1451 name); 1452 if (!res) { 1453 create_dentry(child, d_inode(link_path.dentry), 1454 gc->file, gc->sbi); 1455 path_put(&link_path); 1456 gc->num++; 1457 } else if (res == -ENOENT) { 1458 create_dentry(child, d_inode(child), gc->file, gc->sbi); 1459 gc->num++; 1460 } 1461 } 1462 dput(child); 1463 1464out: 1465 /* 1466 * we always return 0 here, so that the caller can continue to next 1467 * dentry even if failed on this dentry somehow. 1468 */ 1469 return 0; 1470} 1471 1472static void hmdfs_server_set_header(struct hmdfs_dcache_header *header, 1473 struct file *file, struct file *dentry_file) 1474{ 1475 struct inode *inode = NULL; 1476 struct hmdfs_time_t cur_time; 1477 1478 inode = file_inode(file); 1479 cur_time = current_time(file_inode(dentry_file)); 1480 header->dcache_crtime = cpu_to_le64(cur_time.tv_sec); 1481 header->dcache_crtime_nsec = cpu_to_le64(cur_time.tv_nsec); 1482 header->dentry_ctime = cpu_to_le64(inode->i_ctime.tv_sec); 1483 header->dentry_ctime_nsec = cpu_to_le64(inode->i_ctime.tv_nsec); 1484} 1485 1486// Get the dentries of target directory 1487struct file *hmdfs_server_rebuild_dents(struct hmdfs_sb_info *sbi, 1488 struct path *path, loff_t *num, 1489 const char *dir) 1490{ 1491 int err = 0; 1492 struct getdents_callback_real gc = { 1493 .ctx.actor = hmdfs_filldir_real, 1494 .ctx.pos = 0, 1495 .num = 0, 1496 .sbi = sbi, 1497 .dir = dir, 1498 }; 1499 struct file *file = NULL; 1500 struct file *dentry_file = NULL; 1501 struct hmdfs_dcache_header header; 1502 1503 dentry_file = create_local_dentry_file_cache(sbi); 1504 if (IS_ERR(dentry_file)) { 1505 hmdfs_err("file create failed err=%ld", PTR_ERR(dentry_file)); 1506 return dentry_file; 1507 } 1508 1509 file = dentry_open(path, O_RDONLY | O_DIRECTORY, current_cred()); 1510 if (IS_ERR(file)) { 1511 err = PTR_ERR(file); 1512 hmdfs_err("dentry_open failed"); 1513 goto out; 1514 } 1515 1516 hmdfs_server_set_header(&header, file, dentry_file); 1517 1518 gc.parent_path = path; 1519 gc.file = dentry_file; 1520 1521 err = iterate_dir(file, &(gc.ctx)); 1522 if (err) { 1523 hmdfs_err("iterate_dir failed"); 1524 goto out; 1525 } 1526 1527 header.case_sensitive = sbi->s_case_sensitive; 1528 header.num = cpu_to_le64(gc.num); 1529 if (num) 1530 *num = gc.num; 1531 1532 err = write_header(dentry_file, &header); 1533out: 1534 if (!IS_ERR_OR_NULL(file)) 1535 fput(file); 1536 1537 if (err) { 1538 fput(dentry_file); 1539 dentry_file = ERR_PTR(err); 1540 } 1541 1542 trace_hmdfs_server_rebuild_dents(&header, err); 1543 return dentry_file; 1544} 1545 1546void hmdfs_server_writepage(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, 1547 void *data) 1548{ 1549 struct writepage_request *writepage_recv = data; 1550 struct hmdfs_server_writeback *hswb = NULL; 1551 __u64 file_ver; 1552 __u32 file_id; 1553 struct file *file = NULL; 1554 loff_t pos; 1555 __u32 count; 1556 ssize_t ret; 1557 int err = 0; 1558 1559 file_id = le32_to_cpu(writepage_recv->file_id); 1560 file_ver = le64_to_cpu(writepage_recv->file_ver); 1561 file = get_file_by_fid_and_ver(con, cmd, file_id, file_ver); 1562 if (IS_ERR(file)) { 1563 hmdfs_info( 1564 "file with id %u does not exist, pgindex %llu, devid %llu", 1565 file_id, le64_to_cpu(writepage_recv->index), 1566 con->device_id); 1567 err = PTR_ERR(file); 1568 goto out; 1569 } 1570 1571 pos = (loff_t)le64_to_cpu(writepage_recv->index) << HMDFS_PAGE_OFFSET; 1572 count = le32_to_cpu(writepage_recv->count); 1573 ret = kernel_write(file, writepage_recv->buf, count, &pos); 1574 if (ret != count) 1575 err = -EIO; 1576 1577 hmdfs_close_path(file); 1578out: 1579 hmdfs_send_err_response(con, cmd, err); 1580 1581 hswb = con->sbi->h_swb; 1582 if (!err && hswb->dirty_writeback_control) 1583 hmdfs_server_check_writeback(hswb); 1584} 1585 1586static int hmdfs_lookup_linkpath(struct hmdfs_sb_info *sbi, 1587 const char *path_name, struct path *dst_path) 1588{ 1589 struct path link_path; 1590 int err; 1591 1592 err = hmdfs_lookup_symlink(&link_path, "%s/%s", sbi->local_dst, 1593 path_name); 1594 if (err) 1595 return err; 1596 1597 if (d_inode(link_path.dentry)->i_sb != sbi->sb) { 1598 path_put(dst_path); 1599 *dst_path = link_path; 1600 } else { 1601 path_put(&link_path); 1602 } 1603 1604 return 0; 1605} 1606 1607static struct inode *hmdfs_verify_path(struct dentry *dentry, char *recv_buf, 1608 struct super_block *sb) 1609{ 1610 struct inode *inode = d_inode(dentry); 1611 struct hmdfs_inode_info *info = NULL; 1612 1613 /* if we found path from wrong fs */ 1614 if (inode->i_sb != sb) { 1615 hmdfs_err("super block do not match"); 1616 return NULL; 1617 } 1618 1619 info = hmdfs_i(inode); 1620 /* make sure lower inode is not NULL */ 1621 if (info->lower_inode) 1622 return info->lower_inode; 1623 1624 /* 1625 * we don't expect lower inode to be NULL in server. However, it's 1626 * possible because dentry cache can contain stale data. 1627 */ 1628 hmdfs_info("lower inode is NULL, is remote file: %d", 1629 info->conn != NULL); 1630 return NULL; 1631} 1632 1633static int hmdfs_notify_change(struct vfsmount *mnt, struct dentry *dentry, 1634 struct iattr *attr, 1635 struct inode **delegated_inode) 1636{ 1637#ifdef CONFIG_SDCARD_FS 1638 /* sdcard_fs need to call setattr2, notify_change will call setattr */ 1639 return notify_change2(mnt, dentry, attr, delegated_inode); 1640#else 1641 return notify_change(dentry, attr, delegated_inode); 1642#endif 1643} 1644 1645void hmdfs_server_setattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, 1646 void *data) 1647{ 1648 int err = 0; 1649 struct dentry *dentry = NULL; 1650 struct inode *inode = NULL; 1651 struct setattr_request *recv = data; 1652 struct path root_path, dst_path; 1653 struct iattr attr; 1654 __u32 valid = le32_to_cpu(recv->valid); 1655 1656 if (path_contain_dotdot(recv->buf, recv->path_len)) { 1657 err = -EINVAL; 1658 goto out; 1659 } 1660 1661 err = kern_path(con->sbi->local_dst, 0, &root_path); 1662 if (err) { 1663 hmdfs_err("kern_path failed err = %d", err); 1664 goto out; 1665 } 1666 1667 err = vfs_path_lookup(root_path.dentry, root_path.mnt, recv->buf, 0, 1668 &dst_path); 1669 if (err) 1670 goto out_put_root; 1671 1672 inode = hmdfs_verify_path(dst_path.dentry, recv->buf, con->sbi->sb); 1673 if (!inode) { 1674 err = -ENOENT; 1675 goto out_put_dst; 1676 } 1677 1678 if (S_ISLNK(inode->i_mode)) { 1679 err = hmdfs_lookup_linkpath(con->sbi, recv->buf, &dst_path); 1680 if(err == -ENOENT) 1681 err = 0; 1682 else if (err) 1683 goto out_put_dst; 1684 } 1685 1686 dentry = dst_path.dentry; 1687 memset(&attr, 0, sizeof(attr)); 1688 /* only support size and mtime */ 1689 if (valid & (ATTR_SIZE | ATTR_MTIME)) 1690 attr.ia_valid = 1691 (valid & (ATTR_MTIME | ATTR_MTIME_SET | ATTR_SIZE)); 1692 attr.ia_size = le64_to_cpu(recv->size); 1693 attr.ia_mtime.tv_sec = le64_to_cpu(recv->mtime); 1694 attr.ia_mtime.tv_nsec = le32_to_cpu(recv->mtime_nsec); 1695 1696 inode_lock(dentry->d_inode); 1697 err = hmdfs_notify_change(dst_path.mnt, dentry, &attr, NULL); 1698 inode_unlock(dentry->d_inode); 1699 1700out_put_dst: 1701 path_put(&dst_path); 1702out_put_root: 1703 path_put(&root_path); 1704out: 1705 hmdfs_send_err_response(con, cmd, err); 1706} 1707 1708static void update_getattr_response(struct hmdfs_peer *con, struct inode *inode, 1709 struct kstat *ks, 1710 struct getattr_response *resp) 1711{ 1712 /* if getattr for link, get ino and mode from actual lower inode */ 1713 resp->ino = cpu_to_le64( 1714 generate_u64_ino(inode->i_ino, inode->i_generation)); 1715 resp->mode = cpu_to_le16(inode->i_mode); 1716 1717 /* get other information from vfs_getattr() */ 1718 resp->result_mask = cpu_to_le32(STATX_BASIC_STATS | STATX_BTIME); 1719 resp->fsid = cpu_to_le64(ks->dev); 1720 resp->nlink = cpu_to_le32(ks->nlink); 1721 resp->uid = cpu_to_le32(ks->uid.val); 1722 resp->gid = cpu_to_le32(ks->gid.val); 1723 resp->size = cpu_to_le64(ks->size); 1724 resp->blocks = cpu_to_le64(ks->blocks); 1725 resp->blksize = cpu_to_le32(ks->blksize); 1726 resp->atime = cpu_to_le64(ks->atime.tv_sec); 1727 resp->atime_nsec = cpu_to_le32(ks->atime.tv_nsec); 1728 resp->mtime = cpu_to_le64(ks->mtime.tv_sec); 1729 resp->mtime_nsec = cpu_to_le32(ks->mtime.tv_nsec); 1730 resp->ctime = cpu_to_le64(ks->ctime.tv_sec); 1731 resp->ctime_nsec = cpu_to_le32(ks->ctime.tv_nsec); 1732 resp->crtime = cpu_to_le64(ks->btime.tv_sec); 1733 resp->crtime_nsec = cpu_to_le32(ks->btime.tv_nsec); 1734} 1735 1736void hmdfs_server_getattr(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, 1737 void *data) 1738{ 1739 int err = 0; 1740 struct getattr_request *recv = data; 1741 int size_read = sizeof(struct getattr_response); 1742 struct getattr_response *resp = NULL; 1743 struct kstat ks; 1744 struct path root_path, dst_path; 1745 struct inode *inode = NULL; 1746 unsigned int recv_flags = le32_to_cpu(recv->lookup_flags); 1747 unsigned int lookup_flags = 0; 1748 1749 if (path_contain_dotdot(recv->buf, recv->path_len)) { 1750 err = -EINVAL; 1751 goto err; 1752 } 1753 1754 err = hmdfs_convert_lookup_flags(recv_flags, &lookup_flags); 1755 if (err) 1756 goto err; 1757 1758 resp = kzalloc(size_read, GFP_KERNEL); 1759 if (!resp) { 1760 err = -ENOMEM; 1761 goto err; 1762 } 1763 err = kern_path(con->sbi->local_dst, 0, &root_path); 1764 if (err) { 1765 hmdfs_err("kern_path failed err = %d", err); 1766 goto err_free_resp; 1767 } 1768 1769 err = vfs_path_lookup(root_path.dentry, root_path.mnt, recv->buf, 1770 lookup_flags, &dst_path); 1771 if (err) 1772 goto out_put_root; 1773 1774 inode = hmdfs_verify_path(dst_path.dentry, recv->buf, con->sbi->sb); 1775 if (!inode) { 1776 err = -ENOENT; 1777 goto out_put_dst; 1778 } 1779 1780 if (S_ISLNK(inode->i_mode)) { 1781 err = hmdfs_lookup_linkpath(con->sbi, recv->buf, &dst_path); 1782 if(err && err != -ENOENT) 1783 goto out_put_dst; 1784 } 1785 1786 err = vfs_getattr(&dst_path, &ks, STATX_BASIC_STATS | STATX_BTIME, 0); 1787 if (err) 1788 goto err_put_dst; 1789 update_getattr_response(con, inode, &ks, resp); 1790 1791out_put_dst: 1792 path_put(&dst_path); 1793out_put_root: 1794 /* 1795 * if path lookup failed, we return with result_mask setting to 1796 * zero. So we can be aware of such situation in caller. 1797 */ 1798 if (err) 1799 resp->result_mask = cpu_to_le32(0); 1800 path_put(&root_path); 1801 hmdfs_sendmessage_response(con, cmd, size_read, resp, err); 1802 kfree(resp); 1803 return; 1804 1805err_put_dst: 1806 path_put(&dst_path); 1807 path_put(&root_path); 1808err_free_resp: 1809 kfree(resp); 1810err: 1811 hmdfs_send_err_response(con, cmd, err); 1812} 1813 1814static void init_statfs_response(struct statfs_response *resp, 1815 struct kstatfs *st) 1816{ 1817 resp->f_type = cpu_to_le64(HMDFS_SUPER_MAGIC); 1818 resp->f_bsize = cpu_to_le64(st->f_bsize); 1819 resp->f_blocks = cpu_to_le64(st->f_blocks); 1820 resp->f_bfree = cpu_to_le64(st->f_bfree); 1821 resp->f_bavail = cpu_to_le64(st->f_bavail); 1822 resp->f_files = cpu_to_le64(st->f_files); 1823 resp->f_ffree = cpu_to_le64(st->f_ffree); 1824 resp->f_fsid_0 = cpu_to_le32(st->f_fsid.val[0]); 1825 resp->f_fsid_1 = cpu_to_le32(st->f_fsid.val[1]); 1826 resp->f_namelen = cpu_to_le64(st->f_namelen); 1827 resp->f_frsize = cpu_to_le64(st->f_frsize); 1828 resp->f_flags = cpu_to_le64(st->f_flags); 1829 /* f_spare is not used in f2fs or ext4 */ 1830 resp->f_spare_0 = cpu_to_le64(st->f_spare[0]); 1831 resp->f_spare_1 = cpu_to_le64(st->f_spare[1]); 1832 resp->f_spare_2 = cpu_to_le64(st->f_spare[2]); 1833 resp->f_spare_3 = cpu_to_le64(st->f_spare[3]); 1834} 1835 1836void hmdfs_server_statfs(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, 1837 void *data) 1838{ 1839 struct statfs_request *recv = data; 1840 struct statfs_response *resp = NULL; 1841 struct path root_path, path; 1842 struct kstatfs *st = NULL; 1843 int err = 0; 1844 1845 if (path_contain_dotdot(recv->path, recv->path_len)) { 1846 err = -EINVAL; 1847 goto out; 1848 } 1849 1850 st = kzalloc(sizeof(*st), GFP_KERNEL); 1851 if (!st) { 1852 err = -ENOMEM; 1853 goto out; 1854 } 1855 1856 resp = kmalloc(sizeof(*resp), GFP_KERNEL); 1857 if (!resp) { 1858 err = -ENOMEM; 1859 goto free_st; 1860 } 1861 1862 err = kern_path(con->sbi->local_src, 0, &root_path); 1863 if (err) { 1864 hmdfs_info("kern_path failed err = %d", err); 1865 goto free_st; 1866 } 1867 1868 err = vfs_path_lookup(root_path.dentry, root_path.mnt, recv->path, 0, 1869 &path); 1870 if (err) { 1871 hmdfs_info("recv->path found failed err = %d", err); 1872 goto put_root; 1873 } 1874 1875 err = vfs_statfs(&path, st); 1876 if (err) 1877 hmdfs_info("statfs local dentry failed, err = %d", err); 1878 init_statfs_response(resp, st); 1879 path_put(&path); 1880 1881put_root: 1882 path_put(&root_path); 1883free_st: 1884 kfree(st); 1885out: 1886 if (err) 1887 hmdfs_send_err_response(con, cmd, err); 1888 else 1889 hmdfs_sendmessage_response(con, cmd, sizeof(*resp), resp, 0); 1890 1891 kfree(resp); 1892} 1893 1894void hmdfs_server_syncfs(struct hmdfs_peer *con, struct hmdfs_head_cmd *cmd, 1895 void *data) 1896{ 1897 /* 1898 * Reserved interface. There is a difference compared with traditional 1899 * syncfs process. Remote syncfs process in client: 1900 * 1. Remote writepages by async call 1901 * 2. Remote syncfs calling 1902 * 3. Wait all remote async calls(writepages) return in step 1 1903 */ 1904 int ret = 0; 1905 1906 hmdfs_send_err_response(con, cmd, ret); 1907} 1908 1909void hmdfs_server_getxattr(struct hmdfs_peer *con, 1910 struct hmdfs_head_cmd *cmd, void *data) 1911{ 1912 struct getxattr_request *recv = data; 1913 size_t size = le32_to_cpu(recv->size); 1914 size_t size_read = sizeof(struct getxattr_response) + size; 1915 struct getxattr_response *resp = NULL; 1916 struct path root_path; 1917 struct path path; 1918 char *file_path = recv->buf; 1919 char *name = recv->buf + recv->path_len + 1; 1920 int err = -ENOMEM; 1921 1922 if (path_contain_dotdot(file_path, recv->path_len)) { 1923 err = -EINVAL; 1924 goto err; 1925 } 1926 if (path_contain_dotdot(name, recv->name_len)) { 1927 err = -EINVAL; 1928 goto err; 1929 } 1930 1931 resp = kzalloc(size_read, GFP_KERNEL); 1932 if (!resp) { 1933 err = -ENOMEM; 1934 goto err; 1935 } 1936 1937 err = kern_path(con->sbi->local_dst, LOOKUP_DIRECTORY, &root_path); 1938 if (err) { 1939 hmdfs_info("kern_path failed err = %d", err); 1940 goto err_free_resp; 1941 } 1942 1943 err = vfs_path_lookup(root_path.dentry, root_path.mnt, 1944 file_path, 0, &path); 1945 if (err) { 1946 hmdfs_info("path found failed err = %d", err); 1947 goto err_put_root; 1948 } 1949 1950 if (!size) 1951 err = vfs_getxattr(path.dentry, name, NULL, size); 1952 else 1953 err = vfs_getxattr(path.dentry, name, resp->value, size); 1954 if (err < 0) { 1955 hmdfs_info("getxattr failed err %d", err); 1956 goto err_put_path; 1957 } 1958 1959 resp->size = cpu_to_le32(err); 1960 hmdfs_sendmessage_response(con, cmd, size_read, resp, 0); 1961 path_put(&path); 1962 path_put(&root_path); 1963 kfree(resp); 1964 return; 1965 1966err_put_path: 1967 path_put(&path); 1968err_put_root: 1969 path_put(&root_path); 1970err_free_resp: 1971 kfree(resp); 1972err: 1973 hmdfs_send_err_response(con, cmd, err); 1974} 1975 1976void hmdfs_server_setxattr(struct hmdfs_peer *con, 1977 struct hmdfs_head_cmd *cmd, void *data) 1978{ 1979 struct setxattr_request *recv = data; 1980 size_t size = le32_to_cpu(recv->size); 1981 int flags = le32_to_cpu(recv->flags); 1982 bool del = recv->del; 1983 struct path root_path; 1984 struct path path; 1985 const char *file_path = recv->buf; 1986 const char *name = recv->buf + recv->path_len + 1; 1987 const void *value = name + recv->name_len + 1; 1988 int err; 1989 1990 if (path_contain_dotdot(file_path, recv->path_len)) { 1991 err = -EINVAL; 1992 goto err; 1993 } 1994 if (path_contain_dotdot(name, recv->name_len)) { 1995 err = -EINVAL; 1996 goto err; 1997 } 1998 1999 err = kern_path(con->sbi->local_dst, LOOKUP_DIRECTORY, &root_path); 2000 if (err) { 2001 hmdfs_info("kern_path failed err = %d", err); 2002 goto err; 2003 } 2004 err = vfs_path_lookup(root_path.dentry, root_path.mnt, 2005 file_path, 0, &path); 2006 if (err) { 2007 hmdfs_info("path found failed err = %d", err); 2008 goto err_put_root; 2009 } 2010 2011 if (del) { 2012 WARN_ON(flags != XATTR_REPLACE); 2013 err = vfs_removexattr(path.dentry, name); 2014 } else { 2015 err = vfs_setxattr(path.dentry, name, value, size, flags); 2016 } 2017 2018 path_put(&path); 2019err_put_root: 2020 path_put(&root_path); 2021err: 2022 hmdfs_send_err_response(con, cmd, err); 2023} 2024 2025void hmdfs_server_listxattr(struct hmdfs_peer *con, 2026 struct hmdfs_head_cmd *cmd, void *data) 2027{ 2028 struct listxattr_request *recv = data; 2029 size_t size = le32_to_cpu(recv->size); 2030 int size_read = sizeof(struct listxattr_response) + size; 2031 struct listxattr_response *resp = NULL; 2032 const char *file_path = recv->buf; 2033 struct path root_path; 2034 struct path path; 2035 int err = 0; 2036 2037 if (path_contain_dotdot(file_path, recv->path_len)) { 2038 err = -EINVAL; 2039 goto err; 2040 } 2041 2042 resp = kzalloc(size_read, GFP_KERNEL); 2043 if (!resp) { 2044 err = -ENOMEM; 2045 goto err; 2046 } 2047 2048 err = kern_path(con->sbi->local_dst, LOOKUP_DIRECTORY, &root_path); 2049 if (err) { 2050 hmdfs_info("kern_path failed err = %d", err); 2051 goto err_free_resp; 2052 } 2053 err = vfs_path_lookup(root_path.dentry, root_path.mnt, 2054 file_path, 0, &path); 2055 if (err) { 2056 hmdfs_info("path found failed err = %d", err); 2057 goto err_put_root; 2058 } 2059 2060 if (!size) 2061 err = vfs_listxattr(path.dentry, NULL, size); 2062 else 2063 err = vfs_listxattr(path.dentry, resp->list, size); 2064 if (err < 0) { 2065 hmdfs_info("listxattr failed err = %d", err); 2066 goto err_put_path; 2067 } 2068 2069 resp->size = cpu_to_le32(err); 2070 hmdfs_sendmessage_response(con, cmd, size_read, resp, 0); 2071 path_put(&root_path); 2072 path_put(&path); 2073 kfree(resp); 2074 return; 2075 2076err_put_path: 2077 path_put(&path); 2078err_put_root: 2079 path_put(&root_path); 2080err_free_resp: 2081 kfree(resp); 2082err: 2083 hmdfs_send_err_response(con, cmd, err); 2084} 2085 2086void hmdfs_server_get_drop_push(struct hmdfs_peer *con, 2087 struct hmdfs_head_cmd *cmd, void *data) 2088{ 2089 struct drop_push_request *dp_recv = data; 2090 struct path root_path, path; 2091 int err; 2092 char *tmp_path = NULL; 2093 2094 if (path_contain_dotdot(dp_recv->path, dp_recv->path_len)) { 2095 err = -EINVAL; 2096 goto quickack; 2097 } 2098 2099 err = kern_path(con->sbi->real_dst, 0, &root_path); 2100 if (err) { 2101 hmdfs_err("kern_path failed err = %d", err); 2102 goto quickack; 2103 } 2104 tmp_path = kzalloc(PATH_MAX, GFP_KERNEL); 2105 if (!tmp_path) 2106 goto out; 2107 snprintf(tmp_path, PATH_MAX, "/" DEVICE_VIEW_ROOT "/%s%s", 2108 con->cid, dp_recv->path); 2109 2110 err = vfs_path_lookup(root_path.dentry, root_path.mnt, tmp_path, 0, 2111 &path); 2112 if (err) { 2113 hmdfs_info("path found failed err = %d", err); 2114 goto free; 2115 } 2116 hmdfs_remove_cache_filp(con, path.dentry); 2117 2118 path_put(&path); 2119free: 2120 kfree(tmp_path); 2121out: 2122 path_put(&root_path); 2123quickack: 2124 set_conn_sock_quickack(con); 2125} 2126