| 16073 | } |
| 16074 | |
| 16075 | int Client::_mkdir(const walk_dentry_result& wdr, mode_t mode, const UserPerm& perm, |
| 16076 | InodeRef *inp, const std::map<std::string, std::string> &metadata, |
| 16077 | std::string alternate_name, FSCrypt_Options fscrypt_options) |
| 16078 | { |
| 16079 | ldout(cct, 8) << "_mkdir(" << wdr << ", 0o" << std::oct << mode << std::dec |
| 16080 | << ", uid " << perm.uid() |
| 16081 | << ", gid " << perm.gid() << ")" << dendl; |
| 16082 | |
| 16083 | if (wdr.target) { |
| 16084 | return -EEXIST; |
| 16085 | } |
| 16086 | |
| 16087 | if (should_check_perms()) { |
| 16088 | if (int rc = may_create(wdr.diri, perm); rc < 0) { |
| 16089 | return rc; |
| 16090 | } |
| 16091 | } |
| 16092 | if (wdr.diri->snapid != CEPH_NOSNAP && wdr.diri->snapid != CEPH_SNAPDIR) { |
| 16093 | return -EROFS; |
| 16094 | } |
| 16095 | if (is_quota_files_exceeded(wdr.diri.get(), perm)) { |
| 16096 | return -EDQUOT; |
| 16097 | } |
| 16098 | |
| 16099 | bool is_snap_op = wdr.diri->snapid == CEPH_SNAPDIR; |
| 16100 | MetaRequest *req = new MetaRequest(is_snap_op ? |
| 16101 | CEPH_MDS_OP_MKSNAP : CEPH_MDS_OP_MKDIR); |
| 16102 | |
| 16103 | if (!is_snap_op) |
| 16104 | req->set_inode_owner_uid_gid(perm.uid(), perm.gid()); |
| 16105 | |
| 16106 | req->set_filepath(wdr.getpath()); |
| 16107 | req->set_inode(wdr.diri); |
| 16108 | req->dentry_drop = CEPH_CAP_FILE_SHARED; |
| 16109 | req->dentry_unless = CEPH_CAP_FILE_EXCL; |
| 16110 | req->set_alternate_name(alternate_name.empty() ? wdr.alternate_name : alternate_name); |
| 16111 | if (fscrypt_options.fscrypt_auth.size()) |
| 16112 | req->fscrypt_auth = fscrypt_options.fscrypt_auth; |
| 16113 | #if defined(__linux__) |
| 16114 | else |
| 16115 | wdr.diri->gen_inherited_fscrypt_auth(&req->fscrypt_auth); |
| 16116 | #endif |
| 16117 | if (fscrypt_options.fscrypt_file.size()) |
| 16118 | req->fscrypt_file = fscrypt_options.fscrypt_file; |
| 16119 | |
| 16120 | mode |= S_IFDIR; |
| 16121 | bufferlist bl; |
| 16122 | int res = _posix_acl_create(wdr.diri, &mode, bl, perm); |
| 16123 | if (res < 0) { |
| 16124 | put_request(req); |
| 16125 | return res; |
| 16126 | } |
| 16127 | req->head.args.mkdir.mode = mode; |
| 16128 | if (is_snap_op) { |
| 16129 | SnapPayload payload; |
| 16130 | // clear the bufferlist that may have been populated by the call |
| 16131 | // to _posix_acl_create(). MDS mksnap does not make use of it. |
| 16132 | // So, reuse it to pass metadata payload. |
nothing calls this directly
no test coverage detected