1// SPDX-License-Identifier: GPL-2.0 2/* 3 * fs/hmdfs/inode_local.c 4 * 5 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 6 */ 7 8#include <linux/file.h> 9#include <linux/fs_stack.h> 10#include <linux/kernel.h> 11#include <linux/mount.h> 12#include <linux/namei.h> 13#include <linux/string.h> 14 15#include "authority/authentication.h" 16#include "comm/socket_adapter.h" 17#include "comm/transport.h" 18#include "hmdfs_client.h" 19#include "hmdfs_dentryfile.h" 20#include "hmdfs_device_view.h" 21#include "hmdfs_share.h" 22#include "hmdfs_trace.h" 23 24extern struct kmem_cache *hmdfs_dentry_cachep; 25 26struct hmdfs_name_data { 27 struct dir_context ctx; 28 const struct qstr *to_find; 29 char *name; 30 bool found; 31}; 32 33int init_hmdfs_dentry_info(struct hmdfs_sb_info *sbi, struct dentry *dentry, 34 int dentry_type) 35{ 36 struct hmdfs_dentry_info *info = 37 kmem_cache_zalloc(hmdfs_dentry_cachep, GFP_ATOMIC); 38 39 if (!info) 40 return -ENOMEM; 41 INIT_LIST_HEAD(&info->cache_list_head); 42 INIT_LIST_HEAD(&info->remote_cache_list_head); 43 spin_lock_init(&info->cache_list_lock); 44 mutex_init(&info->remote_cache_list_lock); 45 mutex_init(&info->cache_pull_lock); 46 spin_lock_init(&info->lock); 47 info->dentry_type = dentry_type; 48 info->device_id = 0; 49 dentry->d_fsdata = info; 50 if (dentry_type == HMDFS_LAYER_ZERO || 51 dentry_type == HMDFS_LAYER_FIRST_DEVICE || 52 dentry_type == HMDFS_LAYER_SECOND_LOCAL || 53 dentry_type == HMDFS_LAYER_SECOND_CLOUD || 54 dentry_type == HMDFS_LAYER_SECOND_REMOTE) 55 d_set_d_op(dentry, &hmdfs_dev_dops); 56 else 57 d_set_d_op(dentry, &hmdfs_dops); 58 return 0; 59} 60 61static inline void set_sharefile_flag(struct hmdfs_dentry_info *gdi) 62{ 63 gdi->file_type = HM_SHARE; 64} 65 66static void check_and_fixup_share_ops(struct inode *inode, 67 const char *name) 68{ 69 if (is_share_dir(inode, name)) { 70 inode->i_op = &hmdfs_dir_inode_ops_share; 71 inode->i_fop = &hmdfs_dir_ops_share; 72 } 73} 74 75struct inode *fill_inode_local(struct super_block *sb, 76 struct inode *lower_inode, const char *name) 77{ 78 int ret = 0; 79 struct inode *inode; 80 struct hmdfs_sb_info *sbi = hmdfs_sb(sb); 81 struct hmdfs_inode_info *info; 82 83 if (!igrab(lower_inode)) 84 return ERR_PTR(-ESTALE); 85 86 inode = hmdfs_iget5_locked_local(sb, lower_inode); 87 if (!inode) { 88 hmdfs_err("iget5_locked get inode NULL"); 89 iput(lower_inode); 90 return ERR_PTR(-ENOMEM); 91 } 92 if (!(inode->i_state & I_NEW)) { 93 iput(lower_inode); 94 return inode; 95 } 96 97 info = hmdfs_i(inode); 98#ifdef CONFIG_HMDFS_FS_PERMISSION 99 info->perm = hmdfs_read_perm(lower_inode); 100#endif 101 if (S_ISDIR(lower_inode->i_mode)) 102 inode->i_mode = (lower_inode->i_mode & S_IFMT) | S_IRWXU | 103 S_IRWXG | S_IXOTH; 104 else if (S_ISREG(lower_inode->i_mode)) 105 inode->i_mode = (lower_inode->i_mode & S_IFMT) | S_IRUSR | 106 S_IWUSR | S_IRGRP | S_IWGRP; 107 else if (S_ISLNK(lower_inode->i_mode)) 108 inode->i_mode = 109 S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; 110 111#ifdef CONFIG_HMDFS_FS_PERMISSION 112 inode->i_uid = lower_inode->i_uid; 113 inode->i_gid = lower_inode->i_gid; 114#else 115 inode->i_uid = KUIDT_INIT((uid_t)1000); 116 inode->i_gid = KGIDT_INIT((gid_t)1000); 117#endif 118 inode->i_atime = lower_inode->i_atime; 119 inode->i_ctime = lower_inode->i_ctime; 120 inode->i_mtime = lower_inode->i_mtime; 121 inode->i_generation = lower_inode->i_generation; 122 123 info->inode_type = HMDFS_LAYER_OTHER_LOCAL; 124 if (S_ISDIR(lower_inode->i_mode)) { 125 inode->i_op = &hmdfs_dir_inode_ops_local; 126 inode->i_fop = &hmdfs_dir_ops_local; 127 inode->i_mode |= S_IXUGO; 128 } else if (S_ISREG(lower_inode->i_mode)) { 129 inode->i_op = &hmdfs_file_iops_local; 130 inode->i_fop = &hmdfs_file_fops_local; 131 } else if (S_ISLNK(lower_inode->i_mode)) { 132 inode->i_op = &hmdfs_symlink_iops_local; 133 inode->i_fop = &hmdfs_file_fops_local; 134 inode->i_size = i_size_read(lower_inode); 135 } else { 136 ret = -EIO; 137 goto bad_inode; 138 } 139 140 if (sbi->s_cloud_disk_switch) 141 inode->i_mapping->a_ops = &hmdfs_aops_cloud; 142 143 fsstack_copy_inode_size(inode, lower_inode); 144 check_and_fixup_share_ops(inode, name); 145 unlock_new_inode(inode); 146 return inode; 147bad_inode: 148 iget_failed(inode); 149 return ERR_PTR(ret); 150} 151 152/* hmdfs_convert_lookup_flags - covert hmdfs lookup flags to vfs lookup flags 153 * 154 * @hmdfs_flags: hmdfs lookup flags 155 * @vfs_flags: pointer to converted flags 156 * 157 * return 0 on success, or err code on failure. 158 */ 159int hmdfs_convert_lookup_flags(unsigned int hmdfs_flags, 160 unsigned int *vfs_flags) 161{ 162 *vfs_flags = 0; 163 164 /* currently only support HMDFS_LOOKUP_REVAL */ 165 if (hmdfs_flags & ~HMDFS_LOOKUP_REVAL) 166 return -EINVAL; 167 168 if (hmdfs_flags & HMDFS_LOOKUP_REVAL) 169 *vfs_flags |= LOOKUP_REVAL; 170 171 return 0; 172} 173 174static int hmdfs_name_match(struct dir_context *ctx, const char *name, 175 int namelen, loff_t offset, u64 ino, 176 unsigned int d_type) 177{ 178 struct hmdfs_name_data *buf = 179 container_of(ctx, struct hmdfs_name_data, ctx); 180 struct qstr candidate = QSTR_INIT(name, namelen); 181 182 if (qstr_case_eq(buf->to_find, &candidate)) { 183 memcpy(buf->name, name, namelen); 184 buf->name[namelen] = 0; 185 buf->found = true; 186 return 1; 187 } 188 return 0; 189} 190 191static int __lookup_nosensitive(struct path *lower_parent_path, 192 struct dentry *child_dentry, unsigned int flags, 193 struct path *lower_path) 194{ 195 struct file *file; 196 const struct cred *cred = current_cred(); 197 const struct qstr *name = &child_dentry->d_name; 198 int err; 199 struct hmdfs_name_data buffer = { 200 .ctx.actor = hmdfs_name_match, 201 .to_find = name, 202 .name = __getname(), 203 .found = false, 204 }; 205 206 if (!buffer.name) { 207 err = -ENOMEM; 208 goto out; 209 } 210 file = dentry_open(lower_parent_path, O_RDONLY, cred); 211 if (IS_ERR(file)) { 212 err = PTR_ERR(file); 213 goto put_name; 214 } 215 err = iterate_dir(file, &buffer.ctx); 216 fput(file); 217 if (err) 218 goto put_name; 219 if (buffer.found) 220 err = vfs_path_lookup(lower_parent_path->dentry, 221 lower_parent_path->mnt, buffer.name, 222 flags, lower_path); 223 else 224 err = -ENOENT; 225put_name: 226 __putname(buffer.name); 227out: 228 return err; 229} 230 231static inline void set_symlink_flag(struct hmdfs_dentry_info *gdi) 232{ 233 gdi->file_type = HM_SYMLINK; 234} 235 236struct dentry *hmdfs_lookup_local(struct inode *parent_inode, 237 struct dentry *child_dentry, 238 unsigned int flags) 239{ 240 const char *d_name = child_dentry->d_name.name; 241 int err = 0; 242 struct path lower_path, lower_parent_path; 243 struct dentry *lower_dentry = NULL, *parent_dentry = NULL, *ret = NULL; 244 struct hmdfs_dentry_info *gdi = NULL; 245 struct inode *child_inode = NULL; 246 struct hmdfs_sb_info *sbi = hmdfs_sb(child_dentry->d_sb); 247 248 trace_hmdfs_lookup_local(parent_inode, child_dentry, flags); 249 if (child_dentry->d_name.len > NAME_MAX) { 250 ret = ERR_PTR(-ENAMETOOLONG); 251 goto out; 252 } 253 254 /* local device */ 255 parent_dentry = dget_parent(child_dentry); 256 hmdfs_get_lower_path(parent_dentry, &lower_parent_path); 257 err = init_hmdfs_dentry_info(sbi, child_dentry, 258 HMDFS_LAYER_OTHER_LOCAL); 259 if (err) { 260 ret = ERR_PTR(err); 261 goto out_err; 262 } 263 264 gdi = hmdfs_d(child_dentry); 265 266 flags &= ~LOOKUP_FOLLOW; 267 err = vfs_path_lookup(lower_parent_path.dentry, lower_parent_path.mnt, 268 (child_dentry->d_name.name), 0, &lower_path); 269 if (err && err != -ENOENT) { 270 ret = ERR_PTR(err); 271 goto out_err; 272 } else if (!err) { 273 hmdfs_set_lower_path(child_dentry, &lower_path); 274 child_inode = fill_inode_local(parent_inode->i_sb, 275 d_inode(lower_path.dentry), 276 child_dentry->d_name.name); 277 278 if (S_ISLNK(d_inode(lower_path.dentry)->i_mode)) 279 set_symlink_flag(gdi); 280 if (IS_ERR(child_inode)) { 281 err = PTR_ERR(child_inode); 282 ret = ERR_PTR(err); 283 hmdfs_put_reset_lower_path(child_dentry); 284 goto out_err; 285 } 286 ret = d_splice_alias(child_inode, child_dentry); 287 if (IS_ERR(ret)) { 288 err = PTR_ERR(ret); 289 hmdfs_put_reset_lower_path(child_dentry); 290 goto out_err; 291 } 292 293 check_and_fixup_ownership(parent_inode, child_inode); 294 goto out_err; 295 } 296 /* 297 * return 0 here, so that vfs can continue the process of making this 298 * negative dentry to a positive one while creating a new file. 299 */ 300 err = 0; 301 ret = 0; 302 303 lower_dentry = lookup_one_len_unlocked(d_name, lower_parent_path.dentry, 304 child_dentry->d_name.len); 305 if (IS_ERR(lower_dentry)) { 306 err = PTR_ERR(lower_dentry); 307 ret = lower_dentry; 308 goto out_err; 309 } 310 lower_path.dentry = lower_dentry; 311 lower_path.mnt = mntget(lower_parent_path.mnt); 312 hmdfs_set_lower_path(child_dentry, &lower_path); 313 314out_err: 315 if (!err) 316 hmdfs_set_time(child_dentry, jiffies); 317 hmdfs_put_lower_path(&lower_parent_path); 318 dput(parent_dentry); 319out: 320 trace_hmdfs_lookup_local_end(parent_inode, child_dentry, err); 321 return ret; 322} 323 324int hmdfs_mkdir_local_dentry(struct inode *dir, struct dentry *dentry, 325 umode_t mode) 326{ 327 struct inode *lower_dir = hmdfs_i(dir)->lower_inode; 328 struct dentry *lower_dir_dentry = NULL; 329 struct super_block *sb = dir->i_sb; 330 struct path lower_path; 331 struct dentry *lower_dentry = NULL; 332 int error = 0; 333 struct inode *lower_inode = NULL; 334 struct inode *child_inode = NULL; 335 bool local_res = false; 336 struct cache_fs_override or; 337 __u16 child_perm; 338 kuid_t tmp_uid; 339 340 error = hmdfs_override_dir_id_fs(&or, dir, dentry, &child_perm); 341 if (error) 342 goto cleanup; 343 344 hmdfs_get_lower_path(dentry, &lower_path); 345 lower_dentry = lower_path.dentry; 346 lower_dir_dentry = lock_parent(lower_dentry); 347 348 tmp_uid = hmdfs_override_inode_uid(lower_dir); 349 mode = (mode & S_IFMT) | 00771; 350 351 error = vfs_mkdir(lower_dir, lower_dentry, mode); 352 hmdfs_revert_inode_uid(lower_dir, tmp_uid); 353 if (error) { 354 hmdfs_err("vfs_mkdir() error:%d", error); 355 goto out; 356 } 357 local_res = true; 358 lower_inode = d_inode(lower_dentry); 359#ifdef CONFIG_HMDFS_FS_PERMISSION 360 error = hmdfs_persist_perm(lower_dentry, &child_perm); 361#endif 362 child_inode = fill_inode_local(sb, lower_inode, dentry->d_name.name); 363 if (IS_ERR(child_inode)) { 364 error = PTR_ERR(child_inode); 365 goto out; 366 } 367 d_add(dentry, child_inode); 368 set_nlink(dir, hmdfs_i(dir)->lower_inode->i_nlink); 369out: 370 unlock_dir(lower_dir_dentry); 371 if (local_res) 372 hmdfs_drop_remote_cache_dents(dentry->d_parent); 373 374 if (error) { 375 hmdfs_clear_drop_flag(dentry->d_parent); 376 d_drop(dentry); 377 } 378 hmdfs_put_lower_path(&lower_path); 379 hmdfs_revert_dir_id_fs(&or); 380cleanup: 381 return error; 382} 383 384int hmdfs_mkdir_local(struct inode *dir, struct dentry *dentry, umode_t mode) 385{ 386 int err = 0; 387 388 if (check_filename(dentry->d_name.name, dentry->d_name.len)) { 389 err = -EINVAL; 390 return err; 391 } 392 393 if (hmdfs_file_type(dentry->d_name.name) != HMDFS_TYPE_COMMON) { 394 err = -EACCES; 395 return err; 396 } 397 err = hmdfs_mkdir_local_dentry(dir, dentry, mode); 398 trace_hmdfs_mkdir_local(dir, dentry, err); 399 return err; 400} 401 402int hmdfs_create_local_dentry(struct inode *dir, struct dentry *dentry, 403 umode_t mode, bool want_excl) 404{ 405 struct inode *lower_dir = NULL; 406 struct dentry *lower_dir_dentry = NULL; 407 struct super_block *sb = dir->i_sb; 408 struct path lower_path; 409 struct dentry *lower_dentry = NULL; 410 int error = 0; 411 struct inode *lower_inode = NULL; 412 struct inode *child_inode = NULL; 413 kuid_t tmp_uid; 414#ifdef CONFIG_HMDFS_FS_PERMISSION 415 const struct cred *saved_cred = NULL; 416 struct fs_struct *saved_fs = NULL, *copied_fs = NULL; 417 __u16 child_perm; 418#endif 419 420#ifdef CONFIG_HMDFS_FS_PERMISSION 421 saved_cred = hmdfs_override_file_fsids(dir, &child_perm); 422 if (!saved_cred) { 423 error = -ENOMEM; 424 goto path_err; 425 } 426 427 saved_fs = current->fs; 428 copied_fs = hmdfs_override_fsstruct(saved_fs); 429 if (!copied_fs) { 430 error = -ENOMEM; 431 goto revert_fsids; 432 } 433#endif 434 hmdfs_get_lower_path(dentry, &lower_path); 435 lower_dentry = lower_path.dentry; 436 mode = (mode & S_IFMT) | 00660; 437 lower_dir_dentry = lock_parent(lower_dentry); 438 lower_dir = d_inode(lower_dir_dentry); 439 tmp_uid = hmdfs_override_inode_uid(lower_dir); 440 error = vfs_create(lower_dir, lower_dentry, mode, want_excl); 441 hmdfs_revert_inode_uid(lower_dir, tmp_uid); 442 unlock_dir(lower_dir_dentry); 443 if (error) 444 goto out; 445 446 lower_inode = d_inode(lower_dentry); 447#ifdef CONFIG_HMDFS_FS_PERMISSION 448 error = hmdfs_persist_perm(lower_dentry, &child_perm); 449#endif 450 child_inode = fill_inode_local(sb, lower_inode, dentry->d_name.name); 451 if (IS_ERR(child_inode)) { 452 error = PTR_ERR(child_inode); 453 goto out_created; 454 } 455 d_add(dentry, child_inode); 456 457out_created: 458 hmdfs_drop_remote_cache_dents(dentry->d_parent); 459out: 460 if (error) { 461 hmdfs_clear_drop_flag(dentry->d_parent); 462 d_drop(dentry); 463 } 464 hmdfs_put_lower_path(&lower_path); 465 466#ifdef CONFIG_HMDFS_FS_PERMISSION 467 hmdfs_revert_fsstruct(saved_fs, copied_fs); 468revert_fsids: 469 hmdfs_revert_fsids(saved_cred); 470#endif 471#ifdef CONFIG_HMDFS_FS_PERMISSION 472path_err: 473#endif 474 return error; 475} 476 477int hmdfs_create_local(struct inode *dir, struct dentry *child_dentry, 478 umode_t mode, bool want_excl) 479{ 480 int err = 0; 481 482 if (check_filename(child_dentry->d_name.name, 483 child_dentry->d_name.len)) { 484 err = -EINVAL; 485 return err; 486 } 487 488 if (hmdfs_file_type(child_dentry->d_name.name) != HMDFS_TYPE_COMMON) { 489 err = -EACCES; 490 return err; 491 } 492 493 err = hmdfs_create_local_dentry(dir, child_dentry, mode, want_excl); 494 trace_hmdfs_create_local(dir, child_dentry, err); 495 return err; 496} 497 498int hmdfs_rmdir_local_dentry(struct inode *dir, struct dentry *dentry) 499{ 500 struct inode *lower_dir = NULL; 501 struct dentry *lower_dir_dentry = NULL; 502 kuid_t tmp_uid; 503 struct path lower_path; 504 struct dentry *lower_dentry = NULL; 505 struct dentry *lookup_dentry = NULL; 506 int error = 0; 507 508 hmdfs_clear_cache_dents(dentry, true); 509 hmdfs_get_lower_path(dentry, &lower_path); 510 lower_dentry = lower_path.dentry; 511 lower_dir_dentry = lock_parent(lower_dentry); 512 lower_dir = d_inode(lower_dir_dentry); 513 514 lookup_dentry = lookup_one_len(lower_dentry->d_name.name, lower_dir_dentry, 515 lower_dentry->d_name.len); 516 if (IS_ERR(lookup_dentry)) { 517 error = PTR_ERR(lookup_dentry); 518 hmdfs_err("lookup_one_len failed, err = %d", error); 519 goto lookup_err; 520 } 521 tmp_uid = hmdfs_override_inode_uid(lower_dir); 522 523 error = vfs_rmdir(lower_dir, lookup_dentry); 524 hmdfs_revert_inode_uid(lower_dir, tmp_uid); 525 dput(lookup_dentry); 526lookup_err: 527 unlock_dir(lower_dir_dentry); 528 hmdfs_put_lower_path(&lower_path); 529 if (error) 530 goto path_err; 531 hmdfs_drop_remote_cache_dents(dentry->d_parent); 532path_err: 533 if (error) 534 hmdfs_clear_drop_flag(dentry->d_parent); 535 return error; 536} 537 538int hmdfs_rmdir_local(struct inode *dir, struct dentry *dentry) 539{ 540 int err = 0; 541 542 if (hmdfs_file_type(dentry->d_name.name) != HMDFS_TYPE_COMMON) { 543 err = -EACCES; 544 goto out; 545 } 546 547 err = hmdfs_rmdir_local_dentry(dir, dentry); 548 if (err != 0) { 549 hmdfs_err("rm dir failed:%d", err); 550 goto out; 551 } 552 553 /* drop dentry even remote failed 554 * it maybe cause that one remote devices disconnect 555 * when doing remote rmdir 556 */ 557 d_drop(dentry); 558out: 559 /* return connect device's errcode */ 560 trace_hmdfs_rmdir_local(dir, dentry, err); 561 return err; 562} 563 564int hmdfs_unlink_local_dentry(struct inode *dir, struct dentry *dentry) 565{ 566 struct dentry *lower_dir_dentry = NULL; 567 struct path lower_path; 568 struct inode *lower_dir = NULL; 569 struct dentry *lower_dentry = NULL; 570 struct dentry *lookup_dentry = NULL; 571 int error; 572 kuid_t tmp_uid; 573 574 hmdfs_get_lower_path(dentry, &lower_path); 575 lower_dentry = lower_path.dentry; 576 dget(lower_dentry); 577 lower_dir_dentry = lock_parent(lower_dentry); 578 lower_dir = d_inode(lower_dir_dentry); 579 lookup_dentry = lookup_one_len(lower_dentry->d_name.name, lower_dir_dentry, 580 lower_dentry->d_name.len); 581 if (IS_ERR(lookup_dentry)) { 582 error = PTR_ERR(lookup_dentry); 583 hmdfs_err("lookup_one_len failed, err = %d", error); 584 goto lookup_err; 585 } 586 587 tmp_uid = hmdfs_override_inode_uid(lower_dir); 588 error = vfs_unlink(lower_dir, lookup_dentry, NULL); 589 hmdfs_revert_inode_uid(lower_dir, tmp_uid); 590 set_nlink(d_inode(dentry), 591 hmdfs_i(d_inode(dentry))->lower_inode->i_nlink); 592 dput(lookup_dentry); 593lookup_err: 594 unlock_dir(lower_dir_dentry); 595 dput(lower_dentry); 596 if (error) 597 goto path_err; 598 599 hmdfs_drop_remote_cache_dents(dentry->d_parent); 600 d_drop(dentry); 601 602path_err: 603 hmdfs_put_lower_path(&lower_path); 604 if (error) 605 hmdfs_clear_drop_flag(dentry->d_parent); 606 return error; 607} 608 609int hmdfs_unlink_local(struct inode *dir, struct dentry *dentry) 610{ 611 if (hmdfs_file_type(dentry->d_name.name) != HMDFS_TYPE_COMMON) 612 return -EACCES; 613 614 return hmdfs_unlink_local_dentry(dir, dentry); 615} 616 617int hmdfs_rename_local_dentry(struct inode *old_dir, struct dentry *old_dentry, 618 struct inode *new_dir, struct dentry *new_dentry, 619 unsigned int flags) 620{ 621 struct path lower_old_path; 622 struct path lower_new_path; 623 struct dentry *lower_old_dentry = NULL; 624 struct dentry *lower_new_dentry = NULL; 625 struct dentry *lower_old_dir_dentry = NULL; 626 struct dentry *lower_new_dir_dentry = NULL; 627 struct dentry *trap = NULL; 628 int rc = 0; 629 kuid_t old_dir_uid, new_dir_uid; 630 631 if (flags) 632 return -EINVAL; 633 634 hmdfs_get_lower_path(old_dentry, &lower_old_path); 635 lower_old_dentry = lower_old_path.dentry; 636 if (!lower_old_dentry) { 637 hmdfs_err("lower_old_dentry as NULL"); 638 rc = -EACCES; 639 goto out_put_old_path; 640 } 641 642 hmdfs_get_lower_path(new_dentry, &lower_new_path); 643 lower_new_dentry = lower_new_path.dentry; 644 if (!lower_new_dentry) { 645 hmdfs_err("lower_new_dentry as NULL"); 646 rc = -EACCES; 647 goto out_put_new_path; 648 } 649 650 lower_old_dir_dentry = dget_parent(lower_old_dentry); 651 lower_new_dir_dentry = dget_parent(lower_new_dentry); 652 trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); 653 new_dir_uid = hmdfs_override_inode_uid(d_inode(lower_new_dir_dentry)); 654 old_dir_uid = hmdfs_override_inode_uid(d_inode(lower_old_dir_dentry)); 655 656 /* source should not be ancestor of target */ 657 if (trap == lower_old_dentry) { 658 rc = -EINVAL; 659 goto out_lock; 660 } 661 /* target should not be ancestor of source */ 662 if (trap == lower_new_dentry) { 663 rc = -ENOTEMPTY; 664 goto out_lock; 665 } 666 667 rc = vfs_rename(d_inode(lower_old_dir_dentry), lower_old_dentry, 668 d_inode(lower_new_dir_dentry), lower_new_dentry, NULL, 669 flags); 670out_lock: 671 dget(old_dentry); 672 673 hmdfs_revert_inode_uid(d_inode(lower_old_dir_dentry), old_dir_uid); 674 hmdfs_revert_inode_uid(d_inode(lower_new_dir_dentry), new_dir_uid); 675 676 unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); 677 if (rc == 0) { 678 hmdfs_drop_remote_cache_dents(old_dentry->d_parent); 679 if (old_dentry->d_parent != new_dentry->d_parent) 680 hmdfs_drop_remote_cache_dents(new_dentry->d_parent); 681 } else { 682 hmdfs_clear_drop_flag(old_dentry->d_parent); 683 if (old_dentry->d_parent != new_dentry->d_parent) 684 hmdfs_clear_drop_flag(old_dentry->d_parent); 685 d_drop(new_dentry); 686 } 687 688 dput(old_dentry); 689 dput(lower_old_dir_dentry); 690 dput(lower_new_dir_dentry); 691 692out_put_new_path: 693 hmdfs_put_lower_path(&lower_new_path); 694out_put_old_path: 695 hmdfs_put_lower_path(&lower_old_path); 696 return rc; 697} 698 699int hmdfs_rename_local(struct inode *old_dir, struct dentry *old_dentry, 700 struct inode *new_dir, struct dentry *new_dentry, 701 unsigned int flags) 702{ 703 int err = 0; 704 int ret = 0; 705 706 trace_hmdfs_rename_local(old_dir, old_dentry, new_dir, new_dentry, 707 flags); 708 if (hmdfs_file_type(old_dentry->d_name.name) != HMDFS_TYPE_COMMON || 709 hmdfs_file_type(new_dentry->d_name.name) != HMDFS_TYPE_COMMON) { 710 err = -EACCES; 711 goto rename_out; 712 } 713 714 if (hmdfs_i(old_dir)->inode_type != hmdfs_i(new_dir)->inode_type) { 715 hmdfs_err("in different view"); 716 err = -EPERM; 717 goto rename_out; 718 } 719 720 if (hmdfs_d(old_dentry)->device_id != hmdfs_d(new_dentry)->device_id) { 721 err = -EXDEV; 722 goto rename_out; 723 } 724 725 if (S_ISREG(old_dentry->d_inode->i_mode)) { 726 err = hmdfs_rename_local_dentry(old_dir, old_dentry, new_dir, 727 new_dentry, flags); 728 } else if (S_ISDIR(old_dentry->d_inode->i_mode)) { 729 ret = hmdfs_rename_local_dentry(old_dir, old_dentry, new_dir, 730 new_dentry, flags); 731 if (ret != 0) { 732 err = ret; 733 goto rename_out; 734 } 735 } 736 737 if (!err) 738 d_invalidate(old_dentry); 739 740rename_out: 741 return err; 742} 743 744static bool symname_is_allowed(const char *symname) 745{ 746 char *p = NULL; 747 size_t len; 748 749 len = strnlen(symname, PATH_MAX); 750 if (len >= PATH_MAX) 751 return false; 752 753 p = strstr(symname, "/../"); 754 if (p) 755 return false; 756 757 if (len == 2u && strncmp(symname, "..", 2u) == 0) 758 return false; 759 if (len >= 3u && strncmp(symname, "../", 3u) == 0) 760 return false; 761 if (len >= 3u && strncmp(symname + len - 3u, "/..", 3u) == 0) 762 return false; 763 return true; 764} 765 766int hmdfs_symlink_local(struct inode *dir, struct dentry *dentry, 767 const char *symname) 768{ 769 int err; 770 struct dentry *lower_dentry = NULL; 771 struct dentry *lower_parent_dentry = NULL; 772 struct path lower_path; 773 struct inode *child_inode = NULL; 774 struct inode *lower_dir_inode = hmdfs_i(dir)->lower_inode; 775 struct hmdfs_dentry_info *gdi = hmdfs_d(dentry); 776 kuid_t tmp_uid; 777#ifdef CONFIG_HMDFS_FS_PERMISSION 778 const struct cred *saved_cred = NULL; 779 struct fs_struct *saved_fs = NULL, *copied_fs = NULL; 780 __u16 child_perm; 781#endif 782 783 if (unlikely(!symname_is_allowed(symname))) { 784 err = -EPERM; 785 goto path_err; 786 } 787 788#ifdef CONFIG_HMDFS_FS_PERMISSION 789 saved_cred = hmdfs_override_file_fsids(dir, &child_perm); 790 if (!saved_cred) { 791 err = -ENOMEM; 792 goto path_err; 793 } 794 795 saved_fs = current->fs; 796 copied_fs = hmdfs_override_fsstruct(saved_fs); 797 if (!copied_fs) { 798 err = -ENOMEM; 799 goto revert_fsids; 800 } 801#endif 802 hmdfs_get_lower_path(dentry, &lower_path); 803 lower_dentry = lower_path.dentry; 804 lower_parent_dentry = lock_parent(lower_dentry); 805 tmp_uid = hmdfs_override_inode_uid(lower_dir_inode); 806 err = vfs_symlink(lower_dir_inode, lower_dentry, symname); 807 hmdfs_revert_inode_uid(lower_dir_inode, tmp_uid); 808 unlock_dir(lower_parent_dentry); 809 if (err) 810 goto out_err; 811 set_symlink_flag(gdi); 812#ifdef CONFIG_HMDFS_FS_PERMISSION 813 err = hmdfs_persist_perm(lower_dentry, &child_perm); 814#endif 815 child_inode = fill_inode_local(dir->i_sb, d_inode(lower_dentry), 816 dentry->d_name.name); 817 if (IS_ERR(child_inode)) { 818 err = PTR_ERR(child_inode); 819 goto out_err; 820 } 821 d_add(dentry, child_inode); 822 fsstack_copy_attr_times(dir, lower_dir_inode); 823 fsstack_copy_inode_size(dir, lower_dir_inode); 824 825out_err: 826 hmdfs_put_lower_path(&lower_path); 827#ifdef CONFIG_HMDFS_FS_PERMISSION 828 hmdfs_revert_fsstruct(saved_fs, copied_fs); 829revert_fsids: 830 hmdfs_revert_fsids(saved_cred); 831#endif 832path_err: 833 return err; 834} 835 836static const char *hmdfs_get_link_local(struct dentry *dentry, 837 struct inode *inode, 838 struct delayed_call *done) 839{ 840 const char *link = NULL; 841 struct dentry *lower_dentry = NULL; 842 struct inode *lower_inode = NULL; 843 struct path lower_path; 844 845 if(!dentry) { 846 hmdfs_err("dentry MULL"); 847 link = ERR_PTR(-ECHILD); 848 goto link_out; 849 } 850 851 hmdfs_get_lower_path(dentry, &lower_path); 852 lower_dentry = lower_path.dentry; 853 lower_inode = d_inode(lower_dentry); 854 if(!lower_inode->i_op || !lower_inode->i_op->get_link) { 855 hmdfs_err("The lower inode doesn't support get_link i_op"); 856 link = ERR_PTR(-EINVAL); 857 goto out; 858 } 859 860 link = lower_inode->i_op->get_link(lower_dentry, lower_inode, done); 861 if(IS_ERR_OR_NULL(link)) 862 goto out; 863 fsstack_copy_attr_atime(inode, lower_inode); 864out: 865 hmdfs_put_lower_path(&lower_path); 866link_out: 867 return link; 868} 869 870static int hmdfs_setattr_local(struct dentry *dentry, struct iattr *ia) 871{ 872 struct inode *inode = d_inode(dentry); 873 struct inode *lower_inode = hmdfs_i(inode)->lower_inode; 874 struct path lower_path; 875 struct dentry *lower_dentry = NULL; 876 struct iattr lower_ia; 877 unsigned int ia_valid = ia->ia_valid; 878 int err = 0; 879 kuid_t tmp_uid; 880 881 hmdfs_get_lower_path(dentry, &lower_path); 882 lower_dentry = lower_path.dentry; 883 memcpy(&lower_ia, ia, sizeof(lower_ia)); 884 if (ia_valid & ATTR_FILE) 885 lower_ia.ia_file = hmdfs_f(ia->ia_file)->lower_file; 886 lower_ia.ia_valid &= ~(ATTR_UID | ATTR_GID | ATTR_MODE); 887 if (ia_valid & ATTR_SIZE) { 888 err = inode_newsize_ok(inode, ia->ia_size); 889 if (err) 890 goto out; 891 truncate_setsize(inode, ia->ia_size); 892 } 893 inode_lock(lower_inode); 894 tmp_uid = hmdfs_override_inode_uid(lower_inode); 895 896 err = notify_change(lower_dentry, &lower_ia, NULL); 897 i_size_write(inode, i_size_read(lower_inode)); 898 inode->i_atime = lower_inode->i_atime; 899 inode->i_mtime = lower_inode->i_mtime; 900 inode->i_ctime = lower_inode->i_ctime; 901 err = update_inode_to_dentry(dentry, inode); 902 hmdfs_revert_inode_uid(lower_inode, tmp_uid); 903 904 inode_unlock(lower_inode); 905out: 906 hmdfs_put_lower_path(&lower_path); 907 return err; 908} 909 910static int hmdfs_getattr_local(const struct path *path, struct kstat *stat, 911 u32 request_mask, unsigned int flags) 912{ 913 struct path lower_path; 914 int ret; 915 916 if (path->dentry == NULL || hmdfs_d(path->dentry) == NULL) { 917 hmdfs_err("dentry is NULL"); 918 return -ENOENT; 919 } 920 hmdfs_get_lower_path(path->dentry, &lower_path); 921 ret = vfs_getattr(&lower_path, stat, request_mask, flags); 922 stat->ino = d_inode(path->dentry)->i_ino; 923 stat->uid = d_inode(path->dentry)->i_uid; 924 stat->gid = d_inode(path->dentry)->i_gid; 925 stat->dev = 0; 926 stat->rdev = 0; 927 hmdfs_put_lower_path(&lower_path); 928 929 return ret; 930} 931 932int hmdfs_permission(struct inode *inode, int mask) 933{ 934#ifdef CONFIG_HMDFS_FS_PERMISSION 935 unsigned int mode = inode->i_mode; 936 kuid_t cur_uid = current_fsuid(); 937 938 if (uid_eq(cur_uid, ROOT_UID) || uid_eq(cur_uid, SYSTEM_UID)) 939 return 0; 940 941 if (uid_eq(cur_uid, inode->i_uid)) { 942 mode >>= 6; 943 } else if (in_group_p(inode->i_gid)) { 944 mode >>= 3; 945 } 946 947 if ((mask & ~mode & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) 948 return 0; 949 950 trace_hmdfs_permission(inode->i_ino); 951 return -EACCES; 952#else 953 954 return 0; 955#endif 956} 957 958static ssize_t hmdfs_local_listxattr(struct dentry *dentry, char *list, 959 size_t size) 960{ 961 struct path lower_path; 962 ssize_t res = 0; 963 size_t r_size = size; 964 965 if (!hmdfs_support_xattr(dentry)) 966 return -EOPNOTSUPP; 967 968 if (size > HMDFS_LISTXATTR_SIZE_MAX) 969 r_size = HMDFS_LISTXATTR_SIZE_MAX; 970 971 hmdfs_get_lower_path(dentry, &lower_path); 972 res = vfs_listxattr(lower_path.dentry, list, r_size); 973 hmdfs_put_lower_path(&lower_path); 974 975 if (res == -ERANGE && r_size != size) { 976 hmdfs_info("no support listxattr size over than %d", 977 HMDFS_LISTXATTR_SIZE_MAX); 978 res = -E2BIG; 979 } 980 981 return res; 982} 983struct dentry *hmdfs_lookup_share(struct inode *parent_inode, 984 struct dentry *child_dentry, unsigned int flags) 985{ 986 const struct qstr *d_name = &child_dentry->d_name; 987 int err = 0; 988 struct dentry *ret = NULL; 989 struct hmdfs_sb_info *sbi = hmdfs_sb(child_dentry->d_sb); 990 struct path src_path; 991 struct inode *child_inode = NULL; 992 993 trace_hmdfs_lookup_share(parent_inode, child_dentry, flags); 994 if (d_name->len > NAME_MAX) { 995 ret = ERR_PTR(-ENAMETOOLONG); 996 goto err_out; 997 } 998 999 err = init_hmdfs_dentry_info(sbi, child_dentry, HMDFS_LAYER_OTHER_LOCAL); 1000 if (err) { 1001 ret = ERR_PTR(err); 1002 goto err_out; 1003 } 1004 1005 err = get_path_from_share_table(sbi, child_dentry, &src_path); 1006 if (err) { 1007 ret = ERR_PTR(err); 1008 goto err_out; 1009 } 1010 1011 hmdfs_set_lower_path(child_dentry, &src_path); 1012 child_inode = fill_inode_local(parent_inode->i_sb, 1013 d_inode(src_path.dentry), d_name->name); 1014 1015 set_sharefile_flag(hmdfs_d(child_dentry)); 1016 1017 if (IS_ERR(child_inode)) { 1018 err = PTR_ERR(child_inode); 1019 ret = ERR_PTR(err); 1020 hmdfs_put_reset_lower_path(child_dentry); 1021 goto err_out; 1022 } 1023 ret = d_splice_alias(child_inode, child_dentry); 1024 if (IS_ERR(ret)) { 1025 err = PTR_ERR(ret); 1026 hmdfs_put_reset_lower_path(child_dentry); 1027 goto err_out; 1028 } 1029 1030 check_and_fixup_ownership(parent_inode, child_inode); 1031 1032err_out: 1033 trace_hmdfs_lookup_share_end(parent_inode, child_dentry, err); 1034 return ret; 1035} 1036 1037const struct inode_operations hmdfs_dir_inode_ops_local = { 1038 .lookup = hmdfs_lookup_local, 1039 .mkdir = hmdfs_mkdir_local, 1040 .create = hmdfs_create_local, 1041 .rmdir = hmdfs_rmdir_local, 1042 .unlink = hmdfs_unlink_local, 1043 .symlink = hmdfs_symlink_local, 1044 .rename = hmdfs_rename_local, 1045 .permission = hmdfs_permission, 1046 .setattr = hmdfs_setattr_local, 1047 .getattr = hmdfs_getattr_local, 1048}; 1049 1050const struct inode_operations hmdfs_symlink_iops_local = { 1051 .get_link = hmdfs_get_link_local, 1052 .permission = hmdfs_permission, 1053 .setattr = hmdfs_setattr_local, 1054}; 1055 1056const struct inode_operations hmdfs_dir_inode_ops_share = { 1057 .lookup = hmdfs_lookup_share, 1058 .permission = hmdfs_permission, 1059}; 1060 1061const struct inode_operations hmdfs_file_iops_local = { 1062 .setattr = hmdfs_setattr_local, 1063 .getattr = hmdfs_getattr_local, 1064 .permission = hmdfs_permission, 1065 .listxattr = hmdfs_local_listxattr, 1066}; 1067