1// SPDX-License-Identifier: GPL-2.0 2/* 3 * fs/hmdfs/inode_remote.c 4 * 5 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 6 */ 7 8#include <linux/fs_stack.h> 9#include <linux/namei.h> 10#include <linux/xattr.h> 11#include <linux/string.h> 12 13#include "comm/socket_adapter.h" 14#include "hmdfs.h" 15#include "hmdfs_client.h" 16#include "hmdfs_dentryfile.h" 17#include "hmdfs_share.h" 18#include "hmdfs_trace.h" 19#include "authority/authentication.h" 20#include "stash.h" 21 22struct hmdfs_lookup_ret *lookup_remote_dentry(struct dentry *child_dentry, 23 const struct qstr *qstr, 24 uint64_t dev_id) 25{ 26 struct hmdfs_lookup_ret *lookup_ret; 27 struct hmdfs_dentry *dentry = NULL; 28 struct clearcache_item *cache_item = NULL; 29 struct hmdfs_dcache_lookup_ctx ctx; 30 struct hmdfs_sb_info *sbi = hmdfs_sb(child_dentry->d_sb); 31 32 cache_item = hmdfs_find_cache_item(dev_id, child_dentry->d_parent); 33 if (!cache_item) 34 return NULL; 35 36 lookup_ret = kmalloc(sizeof(*lookup_ret), GFP_KERNEL); 37 if (!lookup_ret) 38 goto out; 39 40 hmdfs_init_dcache_lookup_ctx(&ctx, sbi, qstr, cache_item->filp); 41 dentry = hmdfs_find_dentry(child_dentry, &ctx); 42 if (!dentry) { 43 kfree(lookup_ret); 44 lookup_ret = NULL; 45 goto out; 46 } 47 48 lookup_ret->i_mode = le16_to_cpu(dentry->i_mode); 49 lookup_ret->i_size = le64_to_cpu(dentry->i_size); 50 lookup_ret->i_mtime = le64_to_cpu(dentry->i_mtime); 51 lookup_ret->i_mtime_nsec = le32_to_cpu(dentry->i_mtime_nsec); 52 lookup_ret->i_ino = le64_to_cpu(dentry->i_ino); 53 54 hmdfs_unlock_file(ctx.filp, get_dentry_group_pos(ctx.bidx), 55 DENTRYGROUP_SIZE); 56 kfree(ctx.page); 57out: 58 kref_put(&cache_item->ref, release_cache_item); 59 return lookup_ret; 60} 61 62/* get_remote_inode_info - fill hmdfs_lookup_ret by info from remote getattr 63 * 64 * @dentry: local dentry 65 * @hmdfs_peer: which remote devcie 66 * @flags: lookup flags 67 * 68 * return allocaed and initialized hmdfs_lookup_ret on success, and NULL on 69 * failure. 70 */ 71struct hmdfs_lookup_ret *get_remote_inode_info(struct hmdfs_peer *con, 72 struct dentry *dentry, 73 unsigned int flags) 74{ 75 int err = 0; 76 struct hmdfs_lookup_ret *lookup_ret = NULL; 77 struct hmdfs_getattr_ret *getattr_ret = NULL; 78 unsigned int expected_flags = 0; 79 80 lookup_ret = kmalloc(sizeof(*lookup_ret), GFP_KERNEL); 81 if (!lookup_ret) 82 return NULL; 83 84 err = hmdfs_remote_getattr(con, dentry, flags, &getattr_ret); 85 if (err) { 86 hmdfs_debug("inode info get failed with err %d", err); 87 kfree(lookup_ret); 88 return NULL; 89 } 90 /* make sure we got everything we need */ 91 expected_flags = STATX_INO | STATX_SIZE | STATX_MODE | STATX_MTIME; 92 if ((getattr_ret->stat.result_mask & expected_flags) != 93 expected_flags) { 94 hmdfs_debug("remote getattr failed with flag %x", 95 getattr_ret->stat.result_mask); 96 kfree(lookup_ret); 97 kfree(getattr_ret); 98 return NULL; 99 } 100 101 lookup_ret->i_mode = getattr_ret->stat.mode; 102 lookup_ret->i_size = getattr_ret->stat.size; 103 lookup_ret->i_mtime = getattr_ret->stat.mtime.tv_sec; 104 lookup_ret->i_mtime_nsec = getattr_ret->stat.mtime.tv_nsec; 105 lookup_ret->i_ino = getattr_ret->stat.ino; 106 kfree(getattr_ret); 107 return lookup_ret; 108} 109 110static void hmdfs_remote_readdir_work(struct work_struct *work) 111{ 112 struct hmdfs_readdir_work *rw = 113 container_of(to_delayed_work(work), struct hmdfs_readdir_work, 114 dwork); 115 struct dentry *dentry = rw->dentry; 116 struct hmdfs_peer *con = rw->con; 117 const struct cred *old_cred = hmdfs_override_creds(con->sbi->cred); 118 bool empty = false; 119 120 get_remote_dentry_file(dentry, con); 121 hmdfs_d(dentry)->async_readdir_in_progress = 0; 122 hmdfs_revert_creds(old_cred); 123 124 spin_lock(&con->sbi->async_readdir_work_lock); 125 list_del(&rw->head); 126 empty = list_empty(&con->sbi->async_readdir_work_list); 127 spin_unlock(&con->sbi->async_readdir_work_lock); 128 129 dput(dentry); 130 peer_put(con); 131 kfree(rw); 132 133 if (empty) 134 wake_up_interruptible(&con->sbi->async_readdir_wq); 135} 136 137static void get_remote_dentry_file_in_wq(struct dentry *dentry, 138 struct hmdfs_peer *con) 139{ 140 struct hmdfs_readdir_work *rw = NULL; 141 142 /* do nothing if async readdir is already in progress */ 143 if (cmpxchg_relaxed(&hmdfs_d(dentry)->async_readdir_in_progress, 0, 144 1)) 145 return; 146 147 rw = kmalloc(sizeof(*rw), GFP_KERNEL); 148 if (!rw) { 149 hmdfs_d(dentry)->async_readdir_in_progress = 0; 150 return; 151 } 152 153 dget(dentry); 154 peer_get(con); 155 rw->dentry = dentry; 156 rw->con = con; 157 spin_lock(&con->sbi->async_readdir_work_lock); 158 INIT_DELAYED_WORK(&rw->dwork, hmdfs_remote_readdir_work); 159 list_add(&rw->head, &con->sbi->async_readdir_work_list); 160 spin_unlock(&con->sbi->async_readdir_work_lock); 161 queue_delayed_work(con->dentry_wq, &rw->dwork, 0); 162} 163 164void get_remote_dentry_file_sync(struct dentry *dentry, struct hmdfs_peer *con) 165{ 166 get_remote_dentry_file_in_wq(dentry, con); 167 flush_workqueue(con->dentry_wq); 168} 169 170struct hmdfs_lookup_ret *hmdfs_lookup_by_con(struct hmdfs_peer *con, 171 struct dentry *dentry, 172 struct qstr *qstr, 173 unsigned int flags, 174 const char *relative_path) 175{ 176 struct hmdfs_lookup_ret *result = NULL; 177 178 /* 179 * LOOKUP_REVAL means we found stale info from dentry file, thus 180 * we need to use remote getattr. 181 */ 182 if (flags & LOOKUP_REVAL) { 183 /* 184 * HMDFS_LOOKUP_REVAL means we need to skip dentry cache 185 * in lookup, because dentry cache in server might have 186 * stale data. 187 */ 188 result = get_remote_inode_info(con, dentry, 189 HMDFS_LOOKUP_REVAL); 190 get_remote_dentry_file_in_wq(dentry->d_parent, con); 191 return result; 192 } 193 194 /* If cache file is still valid */ 195 if (hmdfs_cache_revalidate(READ_ONCE(con->conn_time), 196 con->device_id, dentry->d_parent)) { 197 result = lookup_remote_dentry(dentry, qstr, 198 con->device_id); 199 /* 200 * If lookup from cache file failed, use getattr to see 201 * if remote have created the file. 202 */ 203 if (!(flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) && 204 !result) 205 result = get_remote_inode_info(con, dentry, 0); 206 /* If cache file expired, use getattr directly 207 * except create and rename opt 208 */ 209 } else { 210 result = get_remote_inode_info(con, dentry, 0); 211 get_remote_dentry_file_in_wq(dentry->d_parent, con); 212 } 213 214 return result; 215} 216 217/* 218 * hmdfs_update_inode_size - update inode size when finding aready existed 219 * inode. 220 * 221 * First of all, if the file is opened for writing, we don't update inode size 222 * here, because inode size is about to be changed after writing. 223 * 224 * If the file is not opened, simply update getattr_isize(not actual inode size, 225 * just a value showed to user). This is safe because inode size will be 226 * up-to-date after open. 227 * 228 * If the file is opened for read: 229 * a. getattr_isize == HMDFS_STALE_REMOTE_ISIZE 230 * 1) i_size == new_size, nothing need to be done. 231 * 2) i_size > new_size, we keep the i_size and set getattr_isize to new_size, 232 * stale data might be readed in this case, which is fine because file is 233 * opened before remote truncate the file. 234 * 3) i_size < new_size, we drop the last page of the file if i_size is not 235 * aligned to PAGE_SIZE, clear getattr_isize, and update i_size to 236 * new_size. 237 * b. getattr_isize != HMDFS_STALE_REMOTE_ISIZE, getattr_isize will only be set 238 * after 2). 239 * 4) getattr_isize > i_size, this situation is impossible. 240 * 5) i_size >= new_size, this case is the same as 2). 241 * 6) i_size < new_size, this case is the same as 3). 242 */ 243static void hmdfs_update_inode_size(struct inode *inode, uint64_t new_size) 244{ 245 struct hmdfs_inode_info *info = hmdfs_i(inode); 246 int writecount; 247 uint64_t size; 248 249 inode_lock(inode); 250 size = info->getattr_isize; 251 if (size == HMDFS_STALE_REMOTE_ISIZE) 252 size = i_size_read(inode); 253 if (size == new_size) { 254 inode_unlock(inode); 255 return; 256 } 257 258 writecount = atomic_read(&inode->i_writecount); 259 /* check if writing is in progress */ 260 if (writecount > 0) { 261 info->getattr_isize = HMDFS_STALE_REMOTE_ISIZE; 262 inode_unlock(inode); 263 return; 264 } 265 266 /* check if there is no one who opens the file */ 267 if (kref_read(&info->ref) == 0) 268 goto update_info; 269 270 /* check if there is someone who opens the file for read */ 271 if (writecount == 0) { 272 uint64_t aligned_size; 273 274 /* use inode size here instead of getattr_isize */ 275 size = i_size_read(inode); 276 if (new_size <= size) 277 goto update_info; 278 /* 279 * if the old inode size is not aligned to HMDFS_PAGE_SIZE, we 280 * need to drop the last page of the inode, otherwise zero will 281 * be returned while reading the new range in the page after 282 * chaning inode size. 283 */ 284 aligned_size = round_down(size, HMDFS_PAGE_SIZE); 285 if (aligned_size != size) 286 truncate_inode_pages(inode->i_mapping, aligned_size); 287 i_size_write(inode, new_size); 288 info->getattr_isize = HMDFS_STALE_REMOTE_ISIZE; 289 inode_unlock(inode); 290 return; 291 } 292 293update_info: 294 info->getattr_isize = new_size; 295 inode_unlock(inode); 296} 297 298static void hmdfs_update_inode(struct inode *inode, 299 struct hmdfs_lookup_ret *lookup_result) 300{ 301 struct hmdfs_time_t remote_mtime = { 302 .tv_sec = lookup_result->i_mtime, 303 .tv_nsec = lookup_result->i_mtime_nsec, 304 }; 305 306 /* 307 * We only update mtime if the file is not opened for writing. If we do 308 * update it before writing is about to start, user might see the mtime 309 * up-and-down if system time in server and client do not match. However 310 * mtime in client will eventually match server after timeout without 311 * writing. 312 */ 313 if (!inode_is_open_for_write(inode)) 314 inode->i_mtime = remote_mtime; 315 316 /* 317 * We don't care i_size of dir, and lock inode for dir 318 * might cause deadlock. 319 */ 320 if (S_ISREG(inode->i_mode)) 321 hmdfs_update_inode_size(inode, lookup_result->i_size); 322} 323 324static void hmdfs_fill_inode_remote(struct inode *inode, struct inode *dir, 325 umode_t mode) 326{ 327#ifdef CONFIG_HMDFS_FS_PERMISSION 328 inode->i_uid = dir->i_uid; 329 inode->i_gid = dir->i_gid; 330#endif 331} 332 333struct inode *fill_inode_remote(struct super_block *sb, struct hmdfs_peer *con, 334 struct hmdfs_lookup_ret *res, struct inode *dir) 335{ 336 int ret = 0; 337 struct inode *inode = NULL; 338 struct hmdfs_inode_info *info; 339 umode_t mode = res->i_mode; 340 341 inode = hmdfs_iget5_locked_remote(sb, con, res->i_ino); 342 if (!inode) 343 return ERR_PTR(-ENOMEM); 344 345 info = hmdfs_i(inode); 346 info->inode_type = HMDFS_LAYER_OTHER_REMOTE; 347 348 /* the inode was found in cache */ 349 if (!(inode->i_state & I_NEW)) { 350 hmdfs_fill_inode_remote(inode, dir, mode); 351 hmdfs_update_inode(inode, res); 352 return inode; 353 } 354 355 hmdfs_remote_init_stash_status(con, inode, mode); 356 357 inode->__i_ctime.tv_sec = 0; 358 inode->__i_ctime.tv_nsec = 0; 359 inode->i_mtime.tv_sec = res->i_mtime; 360 inode->i_mtime.tv_nsec = res->i_mtime_nsec; 361 362 inode->i_uid = KUIDT_INIT((uid_t)1000); 363 inode->i_gid = KGIDT_INIT((gid_t)1000); 364 365 if (S_ISDIR(mode)) 366 inode->i_mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IXOTH; 367 else if (S_ISREG(mode)) 368 inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; 369 else if (S_ISLNK(mode)) 370 inode->i_mode = S_IFREG | S_IRWXU | S_IRWXG; 371 else { 372 ret = -EIO; 373 goto bad_inode; 374 } 375 376 if (S_ISREG(mode) || S_ISLNK(mode)) { 377 inode->i_op = &hmdfs_dev_file_iops_remote; 378 inode->i_fop = &hmdfs_dev_file_fops_remote; 379 inode->i_size = res->i_size; 380 set_nlink(inode, 1); 381 } else if (S_ISDIR(mode)) { 382 inode->i_op = &hmdfs_dev_dir_inode_ops_remote; 383 inode->i_fop = &hmdfs_dev_dir_ops_remote; 384 set_nlink(inode, 2); 385 } else { 386 ret = -EIO; 387 goto bad_inode; 388 } 389 390 inode->i_mapping->a_ops = &hmdfs_dev_file_aops_remote; 391 392 hmdfs_fill_inode_remote(inode, dir, mode); 393 unlock_new_inode(inode); 394 return inode; 395bad_inode: 396 iget_failed(inode); 397 return ERR_PTR(ret); 398} 399 400static struct dentry *hmdfs_lookup_remote_dentry(struct inode *parent_inode, 401 struct dentry *child_dentry, 402 int flags) 403{ 404 struct dentry *ret = NULL; 405 struct inode *inode = NULL; 406 struct super_block *sb = parent_inode->i_sb; 407 struct hmdfs_sb_info *sbi = sb->s_fs_info; 408 struct hmdfs_lookup_ret *lookup_result = NULL; 409 struct hmdfs_peer *con = NULL; 410 char *file_name = NULL; 411 int file_name_len = child_dentry->d_name.len; 412 struct qstr qstr; 413 struct hmdfs_dentry_info *gdi = hmdfs_d(child_dentry); 414 uint64_t device_id = 0; 415 char *relative_path = NULL; 416 417 file_name = kzalloc(NAME_MAX + 1, GFP_KERNEL); 418 if (!file_name) 419 return ERR_PTR(-ENOMEM); 420 strncpy(file_name, child_dentry->d_name.name, file_name_len); 421 422 qstr.name = file_name; 423 qstr.len = strlen(file_name); 424 425 device_id = gdi->device_id; 426 con = hmdfs_lookup_from_devid(sbi, device_id); 427 if (!con) { 428 ret = ERR_PTR(-ESHUTDOWN); 429 goto done; 430 } 431 432 relative_path = hmdfs_get_dentry_relative_path(child_dentry->d_parent); 433 if (unlikely(!relative_path)) { 434 ret = ERR_PTR(-ENOMEM); 435 hmdfs_err("get relative path failed %d", -ENOMEM); 436 goto done; 437 } 438 439 lookup_result = hmdfs_lookup_by_con(con, child_dentry, &qstr, flags, 440 relative_path); 441 if (lookup_result != NULL) { 442 if (S_ISLNK(lookup_result->i_mode)) 443 gdi->file_type = HM_SYMLINK; 444 else if (in_share_dir(child_dentry)) 445 gdi->file_type = HM_SHARE; 446 inode = fill_inode_remote(sb, con, lookup_result, parent_inode); 447 check_and_fixup_ownership_remote(parent_inode, 448 inode, 449 child_dentry); 450 ret = d_splice_alias(inode, child_dentry); 451 if (!IS_ERR_OR_NULL(ret)) 452 child_dentry = ret; 453 } else { 454 ret = ERR_PTR(-ENOENT); 455 } 456 457done: 458 if (con) 459 peer_put(con); 460 kfree(relative_path); 461 kfree(lookup_result); 462 kfree(file_name); 463 return ret; 464} 465 466struct dentry *hmdfs_lookup_remote(struct inode *parent_inode, 467 struct dentry *child_dentry, 468 unsigned int flags) 469{ 470 int err = 0; 471 struct dentry *ret = NULL; 472 struct hmdfs_dentry_info *gdi = NULL; 473 struct hmdfs_sb_info *sbi = hmdfs_sb(child_dentry->d_sb); 474 475 trace_hmdfs_lookup_remote(parent_inode, child_dentry, flags); 476 if (child_dentry->d_name.len > NAME_MAX) { 477 err = -ENAMETOOLONG; 478 ret = ERR_PTR(-ENAMETOOLONG); 479 goto out; 480 } 481 482 err = init_hmdfs_dentry_info(sbi, child_dentry, 483 HMDFS_LAYER_OTHER_REMOTE); 484 if (err) { 485 ret = ERR_PTR(err); 486 goto out; 487 } 488 gdi = hmdfs_d(child_dentry); 489 gdi->device_id = hmdfs_d(child_dentry->d_parent)->device_id; 490 491 if (is_current_hmdfs_server_ctx()) 492 goto out; 493 494 ret = hmdfs_lookup_remote_dentry(parent_inode, child_dentry, flags); 495 /* 496 * don't return error if inode do not exist, so that vfs can continue 497 * to create it. 498 */ 499 if (IS_ERR_OR_NULL(ret)) { 500 err = PTR_ERR(ret); 501 if (err == -ENOENT) 502 ret = NULL; 503 } else { 504 child_dentry = ret; 505 } 506 507out: 508 if (!err) 509 hmdfs_set_time(child_dentry, jiffies); 510 trace_hmdfs_lookup_remote_end(parent_inode, child_dentry, err); 511 return ret; 512} 513 514/* delete dentry in cache file */ 515void delete_in_cache_file(uint64_t dev_id, struct dentry *dentry) 516{ 517 struct clearcache_item *item = NULL; 518 519 item = hmdfs_find_cache_item(dev_id, dentry->d_parent); 520 if (item) { 521 hmdfs_delete_dentry(dentry, item->filp); 522 kref_put(&item->ref, release_cache_item); 523 } else { 524 hmdfs_info("find cache item failed, con:%llu", dev_id); 525 } 526} 527 528int hmdfs_mkdir_remote_dentry(struct hmdfs_peer *conn, struct dentry *dentry, 529 umode_t mode) 530{ 531 int err = 0; 532 char *dir_path = NULL; 533 struct dentry *parent_dentry = dentry->d_parent; 534 struct inode *parent_inode = d_inode(parent_dentry); 535 struct super_block *sb = parent_inode->i_sb; 536 const unsigned char *d_name = dentry->d_name.name; 537 struct hmdfs_lookup_ret *mkdir_ret = NULL; 538 struct inode *inode = NULL; 539 540 mkdir_ret = kmalloc(sizeof(*mkdir_ret), GFP_KERNEL); 541 if (!mkdir_ret) { 542 err = -ENOMEM; 543 return err; 544 } 545 dir_path = hmdfs_get_dentry_relative_path(parent_dentry); 546 if (!dir_path) { 547 err = -EACCES; 548 goto mkdir_out; 549 } 550 err = hmdfs_client_start_mkdir(conn, dir_path, d_name, mode, mkdir_ret); 551 if (err) { 552 hmdfs_err("hmdfs_client_start_mkdir failed err = %d", err); 553 goto mkdir_out; 554 } 555 if (mkdir_ret) { 556 inode = fill_inode_remote(sb, conn, mkdir_ret, parent_inode); 557 check_and_fixup_ownership_remote(parent_inode, 558 inode, 559 dentry); 560 if (!IS_ERR(inode)) 561 d_add(dentry, inode); 562 else 563 err = PTR_ERR(inode); 564 } else { 565 err = -ENOENT; 566 } 567 568mkdir_out: 569 kfree(dir_path); 570 kfree(mkdir_ret); 571 return err; 572} 573 574int hmdfs_mkdir_remote(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode) 575{ 576 int err = 0; 577 struct hmdfs_inode_info *info = hmdfs_i(dir); 578 struct hmdfs_peer *con = info->conn; 579 580 if (!con) { 581 hmdfs_warning("qpb_debug: con is null!"); 582 goto out; 583 } 584 585 err = hmdfs_mkdir_remote_dentry(con, dentry, mode); 586 if (!err) 587 create_in_cache_file(con->device_id, dentry); 588 else 589 hmdfs_err("remote mkdir failed err = %d", err); 590 591out: 592 trace_hmdfs_mkdir_remote(dir, dentry, err); 593 return err; 594} 595 596int hmdfs_create_remote_dentry(struct hmdfs_peer *conn, struct dentry *dentry, 597 umode_t mode, bool want_excl) 598{ 599 int err = 0; 600 char *dir_path = NULL; 601 struct dentry *parent_dentry = dentry->d_parent; 602 struct inode *parent_inode = d_inode(parent_dentry); 603 struct super_block *sb = parent_inode->i_sb; 604 const unsigned char *d_name = dentry->d_name.name; 605 struct hmdfs_lookup_ret *create_ret = NULL; 606 struct inode *inode = NULL; 607 608 create_ret = kmalloc(sizeof(*create_ret), GFP_KERNEL); 609 if (!create_ret) { 610 err = -ENOMEM; 611 return err; 612 } 613 dir_path = hmdfs_get_dentry_relative_path(parent_dentry); 614 if (!dir_path) { 615 err = -EACCES; 616 goto create_out; 617 } 618 err = hmdfs_client_start_create(conn, dir_path, d_name, mode, 619 want_excl, create_ret); 620 if (err) { 621 hmdfs_err("hmdfs_client_start_create failed err = %d", err); 622 goto create_out; 623 } 624 if (create_ret) { 625 inode = fill_inode_remote(sb, conn, create_ret, parent_inode); 626 check_and_fixup_ownership_remote(parent_inode, 627 inode, 628 dentry); 629 if (!IS_ERR(inode)) 630 d_add(dentry, inode); 631 else 632 err = PTR_ERR(inode); 633 } else { 634 err = -ENOENT; 635 hmdfs_err("get remote inode info failed err = %d", err); 636 } 637 638create_out: 639 kfree(dir_path); 640 kfree(create_ret); 641 return err; 642} 643 644int hmdfs_create_remote(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode, 645 bool want_excl) 646{ 647 int err = 0; 648 struct hmdfs_inode_info *info = hmdfs_i(dir); 649 struct hmdfs_peer *con = info->conn; 650 651 if (!con) { 652 hmdfs_warning("qpb_debug: con is null!"); 653 goto out; 654 } 655 656 err = hmdfs_create_remote_dentry(con, dentry, mode, want_excl); 657 if (!err) 658 create_in_cache_file(con->device_id, dentry); 659 else 660 hmdfs_err("remote create failed err = %d", err); 661 662out: 663 trace_hmdfs_create_remote(dir, dentry, err); 664 return err; 665} 666 667int hmdfs_rmdir_remote_dentry(struct hmdfs_peer *conn, struct dentry *dentry) 668{ 669 int error = 0; 670 char *dir_path = NULL; 671 const char *dentry_name = dentry->d_name.name; 672 673 dir_path = hmdfs_get_dentry_relative_path(dentry->d_parent); 674 if (!dir_path) { 675 error = -EACCES; 676 goto rmdir_out; 677 } 678 679 error = hmdfs_client_start_rmdir(conn, dir_path, dentry_name); 680 if (!error) 681 delete_in_cache_file(conn->device_id, dentry); 682 683rmdir_out: 684 kfree(dir_path); 685 return error; 686} 687 688int hmdfs_rmdir_remote(struct inode *dir, struct dentry *dentry) 689{ 690 int err = 0; 691 struct hmdfs_inode_info *info = hmdfs_i(dentry->d_inode); 692 struct hmdfs_peer *con = info->conn; 693 694 if (!con) 695 goto out; 696 697 if (hmdfs_file_type(dentry->d_name.name) != HMDFS_TYPE_COMMON) { 698 err = -EACCES; 699 goto out; 700 } 701 702 err = hmdfs_rmdir_remote_dentry(con, dentry); 703 /* drop dentry even remote failed 704 * it maybe cause that one remote devices disconnect 705 * when doing remote rmdir 706 */ 707 d_drop(dentry); 708out: 709 /* return connect device's errcode */ 710 trace_hmdfs_rmdir_remote(dir, dentry, err); 711 return err; 712} 713 714int hmdfs_dev_unlink_from_con(struct hmdfs_peer *conn, struct dentry *dentry) 715{ 716 int error = 0; 717 char *dir_path = NULL; 718 const char *dentry_name = dentry->d_name.name; 719 720 dir_path = hmdfs_get_dentry_relative_path(dentry->d_parent); 721 if (!dir_path) { 722 error = -EACCES; 723 goto unlink_out; 724 } 725 error = hmdfs_client_start_unlink(conn, dir_path, dentry_name); 726 if (!error) { 727 delete_in_cache_file(conn->device_id, dentry); 728 drop_nlink(d_inode(dentry)); 729 d_drop(dentry); 730 } 731unlink_out: 732 kfree(dir_path); 733 return error; 734} 735 736int hmdfs_unlink_remote(struct inode *dir, struct dentry *dentry) 737{ 738 struct hmdfs_inode_info *info = hmdfs_i(dentry->d_inode); 739 struct hmdfs_peer *conn = info->conn; 740 741 if (hmdfs_file_type(dentry->d_name.name) != HMDFS_TYPE_COMMON) 742 return -EACCES; 743 744 if (!conn) 745 return 0; 746 747 if (conn->status != NODE_STAT_ONLINE) 748 return 0; 749 750 return hmdfs_dev_unlink_from_con(conn, dentry); 751} 752 753/* rename dentry in cache file */ 754static void rename_in_cache_file(uint64_t dev_id, struct dentry *old_dentry, 755 struct dentry *new_dentry) 756{ 757 struct clearcache_item *old_item = NULL; 758 struct clearcache_item *new_item = NULL; 759 760 old_item = hmdfs_find_cache_item(dev_id, old_dentry->d_parent); 761 new_item = hmdfs_find_cache_item(dev_id, new_dentry->d_parent); 762 if (old_item != NULL && new_item != NULL) { 763 hmdfs_rename_dentry(old_dentry, new_dentry, old_item->filp, 764 new_item->filp); 765 } else if (old_item != NULL) { 766 hmdfs_err("new cache item find failed!"); 767 } else if (new_item != NULL) { 768 hmdfs_err("old cache item find failed!"); 769 } else { 770 hmdfs_err("both cache item find failed!"); 771 } 772 773 if (old_item) 774 kref_put(&old_item->ref, release_cache_item); 775 if (new_item) 776 kref_put(&new_item->ref, release_cache_item); 777} 778 779int hmdfs_rename_remote(struct mnt_idmap *idmap, struct inode *old_dir, struct dentry *old_dentry, 780 struct inode *new_dir, struct dentry *new_dentry, 781 unsigned int flags) 782{ 783 int err = 0; 784 int ret = 0; 785 const char *old_dentry_d_name = old_dentry->d_name.name; 786 char *relative_old_dir_path = 0; 787 const char *new_dentry_d_name = new_dentry->d_name.name; 788 char *relative_new_dir_path = 0; 789 struct hmdfs_inode_info *info = hmdfs_i(old_dentry->d_inode); 790 struct hmdfs_peer *con = info->conn; 791 792 trace_hmdfs_rename_remote(old_dir, old_dentry, new_dir, new_dentry, 793 flags); 794 795 if (flags & ~RENAME_NOREPLACE) 796 return -EINVAL; 797 798 if (hmdfs_file_type(old_dentry->d_name.name) != HMDFS_TYPE_COMMON || 799 hmdfs_file_type(new_dentry->d_name.name) != HMDFS_TYPE_COMMON) { 800 return -EACCES; 801 } 802 803 if (hmdfs_i(old_dir)->inode_type != hmdfs_i(new_dir)->inode_type) { 804 hmdfs_err("in different view"); 805 return -EPERM; 806 } 807 808 if (hmdfs_d(old_dentry)->device_id != hmdfs_d(new_dentry)->device_id) 809 return -EXDEV; 810 811 relative_old_dir_path = 812 hmdfs_get_dentry_relative_path(old_dentry->d_parent); 813 relative_new_dir_path = 814 hmdfs_get_dentry_relative_path(new_dentry->d_parent); 815 if (!relative_old_dir_path || !relative_new_dir_path) { 816 err = -EACCES; 817 goto rename_out; 818 } 819 if (S_ISREG(old_dentry->d_inode->i_mode)) { 820 hmdfs_debug("send MSG to remote devID %llu", 821 con->device_id); 822 err = hmdfs_client_start_rename( 823 con, relative_old_dir_path, old_dentry_d_name, 824 relative_new_dir_path, new_dentry_d_name, 825 flags); 826 if (!err) 827 rename_in_cache_file(con->device_id, old_dentry, 828 new_dentry); 829 } else if (S_ISDIR(old_dentry->d_inode->i_mode)) { 830 if (con->status == NODE_STAT_ONLINE) { 831 ret = hmdfs_client_start_rename( 832 con, relative_old_dir_path, old_dentry_d_name, 833 relative_new_dir_path, new_dentry_d_name, 834 flags); 835 if (!ret) 836 rename_in_cache_file(con->device_id, old_dentry, 837 new_dentry); 838 else 839 err = ret; 840 } 841 } 842 if (!err) 843 d_invalidate(old_dentry); 844rename_out: 845 kfree(relative_old_dir_path); 846 kfree(relative_new_dir_path); 847 return err; 848} 849 850static int hmdfs_dir_setattr_remote(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *ia) 851{ 852 // Do not support dir setattr 853 return 0; 854} 855 856const struct inode_operations hmdfs_dev_dir_inode_ops_remote = { 857 .lookup = hmdfs_lookup_remote, 858 .mkdir = hmdfs_mkdir_remote, 859 .create = hmdfs_create_remote, 860 .rmdir = hmdfs_rmdir_remote, 861 .unlink = hmdfs_unlink_remote, 862 .rename = hmdfs_rename_remote, 863 .setattr = hmdfs_dir_setattr_remote, 864 .permission = hmdfs_permission, 865}; 866 867static int hmdfs_setattr_remote(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *ia) 868{ 869 struct hmdfs_inode_info *info = hmdfs_i(d_inode(dentry)); 870 struct hmdfs_peer *conn = info->conn; 871 struct inode *inode = d_inode(dentry); 872 char *send_buf = NULL; 873 int err = 0; 874 875 if (hmdfs_inode_is_stashing(info)) 876 return -EAGAIN; 877 878 send_buf = hmdfs_get_dentry_relative_path(dentry); 879 if (!send_buf) { 880 err = -ENOMEM; 881 goto out_free; 882 } 883 if (ia->ia_valid & ATTR_SIZE) { 884 err = inode_newsize_ok(inode, ia->ia_size); 885 if (err) 886 goto out_free; 887 truncate_setsize(inode, ia->ia_size); 888 info->getattr_isize = HMDFS_STALE_REMOTE_ISIZE; 889 } 890 if (ia->ia_valid & ATTR_MTIME) 891 inode->i_mtime = ia->ia_mtime; 892 893 if ((ia->ia_valid & ATTR_SIZE) || (ia->ia_valid & ATTR_MTIME)) { 894 struct setattr_info send_setattr_info = { 895 .size = cpu_to_le64(ia->ia_size), 896 .valid = cpu_to_le32(ia->ia_valid), 897 .mtime = cpu_to_le64(ia->ia_mtime.tv_sec), 898 .mtime_nsec = cpu_to_le32(ia->ia_mtime.tv_nsec), 899 }; 900 err = hmdfs_send_setattr(conn, send_buf, &send_setattr_info); 901 } 902out_free: 903 kfree(send_buf); 904 return err; 905} 906 907int hmdfs_remote_getattr(struct hmdfs_peer *conn, struct dentry *dentry, 908 unsigned int lookup_flags, 909 struct hmdfs_getattr_ret **result) 910{ 911 char *send_buf = NULL; 912 struct hmdfs_getattr_ret *attr = NULL; 913 int err = 0; 914 915 if (dentry->d_sb != conn->sbi->sb || !result) 916 return -EINVAL; 917 918 attr = kzalloc(sizeof(*attr), GFP_KERNEL); 919 if (!attr) 920 return -ENOMEM; 921 922 send_buf = hmdfs_get_dentry_relative_path(dentry); 923 if (!send_buf) { 924 kfree(attr); 925 return -ENOMEM; 926 } 927 928 err = hmdfs_send_getattr(conn, send_buf, lookup_flags, attr); 929 kfree(send_buf); 930 931 if (err) { 932 kfree(attr); 933 return err; 934 } 935 936 *result = attr; 937 return 0; 938} 939 940static int hmdfs_get_cached_attr_remote(struct mnt_idmap *idmap, const struct path *path, 941 struct kstat *stat, u32 request_mask, 942 unsigned int flags) 943{ 944 struct inode *inode = d_inode(path->dentry); 945 struct hmdfs_inode_info *info = hmdfs_i(inode); 946 uint64_t size = info->getattr_isize; 947 948 stat->ino = inode->i_ino; 949 stat->mtime = inode->i_mtime; 950 stat->mode = inode->i_mode; 951 stat->uid.val = inode->i_uid.val; 952 stat->gid.val = inode->i_gid.val; 953 if (size == HMDFS_STALE_REMOTE_ISIZE) 954 size = i_size_read(inode); 955 956 stat->size = size; 957 return 0; 958} 959 960ssize_t hmdfs_remote_listxattr(struct dentry *dentry, char *list, size_t size) 961{ 962 struct inode *inode = d_inode(dentry); 963 struct hmdfs_inode_info *info = hmdfs_i(inode); 964 struct hmdfs_peer *conn = info->conn; 965 char *send_buf = NULL; 966 ssize_t res = 0; 967 size_t r_size = size; 968 969 if (!hmdfs_support_xattr(dentry)) 970 return -EOPNOTSUPP; 971 972 if (size > HMDFS_LISTXATTR_SIZE_MAX) 973 r_size = HMDFS_LISTXATTR_SIZE_MAX; 974 975 send_buf = hmdfs_get_dentry_relative_path(dentry); 976 if (!send_buf) 977 return -ENOMEM; 978 979 res = hmdfs_send_listxattr(conn, send_buf, list, r_size); 980 kfree(send_buf); 981 982 if (res == -ERANGE && r_size != size) { 983 hmdfs_info("no support listxattr size over than %d", 984 HMDFS_LISTXATTR_SIZE_MAX); 985 res = -E2BIG; 986 } 987 988 return res; 989} 990 991const struct inode_operations hmdfs_dev_file_iops_remote = { 992 .setattr = hmdfs_setattr_remote, 993 .permission = hmdfs_permission, 994 .getattr = hmdfs_get_cached_attr_remote, 995 .listxattr = hmdfs_remote_listxattr, 996}; 997