MCPcopy Create free account
hub / github.com/ceph/ceph / _link

Method _link

src/client/Client.cc:16664–16721  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

16662}
16663
16664int Client::_link(Inode *diri_from, const char* path_from, Inode* diri_to, const char* path_to, const UserPerm& perm, std::string alternate_name)
16665{
16666 ldout(cct, 8) << "_link(" << diri_from->ino << " to " << diri_to->ino << " " << path_to << " " << perm << dendl;
16667
16668 walk_dentry_result wdr_from;
16669 if (int rc = path_walk(diri_from, filepath(path_from), &wdr_from, perm, {}); rc < 0) {
16670 return rc;
16671 }
16672
16673 walk_dentry_result wdr_to;
16674 if (int rc = path_walk(diri_to, filepath(path_to), &wdr_to, perm, {}); rc == 0) {
16675 return -EEXIST;
16676 } else if (rc != -ENOENT) {
16677 return rc;
16678 }
16679
16680 if (should_check_perms()) {
16681 if (S_ISDIR(wdr_from.target->mode)) {
16682 return -EPERM;
16683 }
16684 if (int rc = may_hardlink(wdr_from.target.get(), perm); rc < 0) {
16685 return rc;
16686 }
16687 if (int rc = may_create(wdr_to.diri.get(), perm); rc < 0) {
16688 return rc;
16689 }
16690 }
16691
16692 auto* in = wdr_from.target.get();
16693 if (in->snapid != CEPH_NOSNAP || wdr_to.diri->snapid != CEPH_NOSNAP) {
16694 return -EROFS;
16695 }
16696 if (is_quota_files_exceeded(wdr_to.diri.get(), perm)) {
16697 return -EDQUOT;
16698 }
16699
16700 in->break_all_delegs();
16701 MetaRequest *req = new MetaRequest(CEPH_MDS_OP_LINK);
16702
16703 req->set_filepath(wdr_to.getpath());
16704 req->set_alternate_name(alternate_name.empty() ? wdr_to.alternate_name : alternate_name);
16705#if defined(__linux__)
16706 wdr_to.diri->gen_inherited_fscrypt_auth(&req->fscrypt_auth);
16707#endif
16708 req->set_filepath2(wdr_from.getpath());
16709 req->set_inode(wdr_to.diri);
16710 req->inode_drop = CEPH_CAP_FILE_SHARED;
16711 req->inode_unless = CEPH_CAP_FILE_EXCL;
16712 req->set_dentry(wdr_to.dn);
16713
16714 int res = make_request(req, perm);
16715
16716 ldout(cct, 10) << "link result is " << res << dendl;
16717
16718 trim_cache();
16719 ldout(cct, 8) << "link(" << wdr_from.getpath() << ", " << wdr_to.getpath() << ") = " << res << dendl;
16720 return res;
16721}

Callers

nothing calls this directly

Calls 12

break_all_delegsMethod · 0.80
getpathMethod · 0.80
set_inodeMethod · 0.80
set_dentryMethod · 0.80
filepathClass · 0.70
make_requestFunction · 0.50
getMethod · 0.45
set_filepathMethod · 0.45
set_alternate_nameMethod · 0.45
emptyMethod · 0.45
set_filepath2Method · 0.45

Tested by

no test coverage detected