| 19081 | // --- subvolume metrics tracking --- // |
| 19082 | |
| 19083 | int Client::fcopyfile(const char *spath, const char *dpath, UserPerm& perms, mode_t mode) { |
| 19084 | ldout(cct, 10) << "fcopyfile spath=" << spath << " dpath=" << dpath << " mode=" << mode << dendl; |
| 19085 | |
| 19086 | walk_dentry_result wdrsrc; |
| 19087 | { |
| 19088 | std::scoped_lock lock(client_lock); |
| 19089 | if (int rc = path_walk(cwd, spath, &wdrsrc, perms, {.followsym = false}); rc < 0) { |
| 19090 | return rc; |
| 19091 | } |
| 19092 | } |
| 19093 | |
| 19094 | auto& srcin = wdrsrc.target; |
| 19095 | std::string alt_name = wdrsrc.alternate_name; |
| 19096 | |
| 19097 | FSCrypt_Options foptions; |
| 19098 | foptions.fscrypt_auth = srcin->fscrypt_auth; |
| 19099 | foptions.fscrypt_file = srcin->fscrypt_file; |
| 19100 | |
| 19101 | if (srcin->is_symlink()){ |
| 19102 | char linkpath[4096]; |
| 19103 | |
| 19104 | int link_size = readlink(spath, linkpath, 4096, perms); |
| 19105 | linkpath[link_size] = '\0'; |
| 19106 | |
| 19107 | int r = do_symlinkat(linkpath, CEPHFS_AT_FDCWD, dpath, perms, alt_name, foptions); |
| 19108 | if (r < 0) { |
| 19109 | ldout(cct, 10) << "fcopyfile could not create symlink=" << dpath << " r=" << r << dendl; |
| 19110 | return r; |
| 19111 | } |
| 19112 | } else if(srcin->is_dir()) { |
| 19113 | int r = do_mkdirat(CEPHFS_AT_FDCWD, dpath, mode, perms, alt_name, foptions); |
| 19114 | if (r < 0) { |
| 19115 | ldout(cct, 10) << "fcopyfile could not create dest dir=" << dpath << " r=" << r << dendl; |
| 19116 | return r; |
| 19117 | } |
| 19118 | } else if(srcin->is_file()) { |
| 19119 | int r = 0; |
| 19120 | size_t size = srcin->size; |
| 19121 | |
| 19122 | int dest = do_openat(CEPHFS_AT_FDCWD, dpath, O_CREAT | O_TRUNC | O_WRONLY, perms, mode, 0,0,0, NULL, alt_name, foptions); |
| 19123 | if (dest < 0) { |
| 19124 | ldout(cct, 10) << "fcopyfile could not open dest file=" << dpath << " ret=" << dest << dendl; |
| 19125 | return dest; |
| 19126 | } |
| 19127 | |
| 19128 | bool need_read = true; |
| 19129 | if (size == 0) |
| 19130 | need_read = false; |
| 19131 | |
| 19132 | int src; |
| 19133 | if (need_read) { |
| 19134 | src = open(spath, O_RDONLY, perms, mode); |
| 19135 | if (src < 0) { |
| 19136 | ldout(cct, 10) << "fcopyfile could not open source file=" << spath << " ret=" << src << dendl; |
| 19137 | close(dest); |
| 19138 | return src; |
| 19139 | } |
| 19140 | |